본문 바로가기

Games/CTF

Codegate 2014 4stone writeup

We have given a local linux environment and a setuid binary. The binary does not have NX.



The program implements simple 4stone game. but if we win the computer within 1 second, the program overwrites arbitrary memory location with arbitrary 4byte value right before calling _exit(). However, the arbitrary memory location of the address cannot have 0xB... or 0x08... prefix. This makes impossible to overwrite any of writable memory segment. However using that we have local privilege, there was a trick making the base address of libraries to other location (ulimit -s unlimited). Enabling this configuration, we could move the library base addresses into 0x40... prefix.



root@ubuntu:/var/www/ctf# cat /proc/20213/maps

08048000-0804a000 r-xp 00000000 08:01 294838     /var/www/ctf/4stone

0804a000-0804b000 r-xp 00001000 08:01 294838     /var/www/ctf/4stone

0804b000-0804c000 rwxp 00002000 08:01 294838     /var/www/ctf/4stone

0804c000-0806d000 rwxp 00000000 00:00 0          [heap]

40000000-40020000 r-xp 00000000 08:01 1049390    /lib/i386-linux-gnu/ld-2.17.so

40020000-40021000 r-xp 0001f000 08:01 1049390    /lib/i386-linux-gnu/ld-2.17.so

40021000-40022000 rwxp 00020000 08:01 1049390    /lib/i386-linux-gnu/ld-2.17.so

40022000-40023000 r-xp 00000000 00:00 0          [vdso]

40023000-40025000 rwxp 00000000 00:00 0 

40038000-40058000 r-xp 00000000 08:01 1049468    /lib/i386-linux-gnu/libncurses.so.5.9

40058000-40059000 r-xp 0001f000 08:01 1049468    /lib/i386-linux-gnu/libncurses.so.5.9

40059000-4005a000 rwxp 00020000 08:01 1049468    /lib/i386-linux-gnu/libncurses.so.5.9

4005a000-40076000 r-xp 00000000 08:01 1049550    /lib/i386-linux-gnu/libtinfo.so.5.9

40076000-40078000 r-xp 0001b000 08:01 1049550    /lib/i386-linux-gnu/libtinfo.so.5.9

40078000-40079000 rwxp 0001d000 08:01 1049550    /lib/i386-linux-gnu/libtinfo.so.5.9

40079000-4007a000 rwxp 00000000 00:00 0 

4007a000-40227000 r-xp 00000000 08:01 1049414    /lib/i386-linux-gnu/libc-2.17.so

40227000-40229000 r-xp 001ad000 08:01 1049414    /lib/i386-linux-gnu/libc-2.17.so

40229000-4022a000 rwxp 001af000 08:01 1049414    /lib/i386-linux-gnu/libc-2.17.so

4022a000-4022d000 rwxp 00000000 00:00 0 

4022d000-40230000 r-xp 00000000 08:01 1049429    /lib/i386-linux-gnu/libdl-2.17.so

40230000-40231000 r-xp 00002000 08:01 1049429    /lib/i386-linux-gnu/libdl-2.17.so

40231000-40232000 rwxp 00003000 08:01 1049429    /lib/i386-linux-gnu/libdl-2.17.so

40232000-40233000 rwxp 00000000 00:00 0 

bffdf000-c0000000 rwxp 00000000 00:00 0          [stack]


Now, we can overwrite some of the data segments of library function. However we were stuck for a while to find some exploitable memory address. After thoroughly analyzing the procedure for resolving the _exit of GOT with IDA instruction tracing, we found out that the dynamic linker references some table which contains the base addresses of libraries, and calculates the _exit() location by adding the offset with libc base address.



Breakpoint 2, 0x4000e5df in _dl_fixup (l=0x40021938, reloc_arg=<optimized out>) at dl-runtime.c:113

113 dl-runtime.c: No such file or directory.

(gdb) i r

eax            0x4007f000 1074262016

ecx            0xbfc07154 -1077907116

edx            0x0 0

ebx            0x40021000 1073876992

esp            0xbfc07118 0xbfc07118

ebp            0x804b014 0x804b014 <_exit@got.plt>

esi            0x40021938 1073879352

edi            0x1 1

eip            0x4000e5df 0x4000e5df <_dl_fixup+207>

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/10x 0x4007f000

0x4007f000: 0x40080000 0x40024dc8 0x4022fdbc 0x4007f2b8

0x4007f010: 0x40024b28 0x4007f000 0x00000000 0x4007f25c

0x4007f020: 0x00000000 0x4022fdbc

(gdb) x/10x 0x4007f000



(gdb) i r $eax

eax            0x40080000 1074266112

(gdb) x/10i $eip

=> 0x4000e5fd <_dl_fixup+237>: add    0x4(%ecx),%eax

   0x4000e600 <_dl_fixup+240>: movzbl 0xc(%ecx),%ecx

   0x4000e604 <_dl_fixup+244>: and    $0xf,%ecx

   0x4000e607 <_dl_fixup+247>: cmp    $0xa,%cl

   0x4000e60a <_dl_fixup+250>: je     0x4000e6b2 <_dl_fixup+418>

   0x4000e610 <_dl_fixup+256>: mov    -0x310(%ebx),%edx

   0x4000e616 <_dl_fixup+262>: test   %edx,%edx

   0x4000e618 <_dl_fixup+264>: jne    0x4000e61d <_dl_fixup+269>

   0x4000e61a <_dl_fixup+266>: mov    %eax,0x0(%ebp)

   0x4000e61d <_dl_fixup+269>: add    $0x4c,%esp

(gdb) si

143 in dl-runtime.c

(gdb) i r $eax

eax            0x4013ab04 1075030788

(gdb) 


ld-2.17.so references...

library base address table : 0x4007f000

offset between libc and _exit : BAB04


so, If we overwrite the libc base address from table at 0x4007f000, we can make the dynamic linker to calculate the GOT entry of _exit as we want. So we launched eggshell in the stack and calculated malicious libc base address for calling our shell code instead of the _exit().  However due to the ASLR, we had to bruteforce the stack address. After doing some brute forcing against stack address... we got shell.




'Games > CTF' 카테고리의 다른 글

PlaidCTF 2014 tenement  (0) 2014.04.15
PlaidCTF 2014 hudak  (0) 2014.04.14
Codegate 2014 Angry Doraemon Writeup  (0) 2014.03.03
Olympic CTF 2014 Echof writeup  (1) 2014.02.10
PHDays 2014 miXer  (0) 2014.01.27