Monday, September 3, 2012

nebula level13

Level details:
There is a security check that prevents the program from continuing execution if the user invoking it does not match a specific user id.
This one is quite nice. Source code:

This program requires us to run it with a UID of 1000 in order to print the token. But let's think where that token actually comes from. The fact that not all of the source code is shown indicates that the token may be somehow generated (or even hardcoded) and then printed to us. The flag13 binary being SUID serves no purpose. We can easily reverse engineer how the token is generated. You could go for a static analysis approach and use a disassembler (I prefer IDA). This is however one of the cases where a dynamic approach is ideal. Since we don't need the elevated UID from the setuid bit, we can simply make getuid return 1000 ourselves. This could be done using LD_PRELOAD and writing our own getuid function in a library, but there's an even easier way. Simply use a debugger and modify the return value:
level13@nebula:~$ gdb -q ~flag13/flag13
Reading symbols from /home/flag13/flag13...(no debugging symbols found)...done.
(gdb) disas main
Dump of assembler code for function main:
   0x080484c4 <+0>:     push   %ebp
   0x080484c5 <+1>:     mov    %esp,%ebp
   0x080484c7 <+3>:     push   %edi
   0x080484c8 <+4>:     push   %ebx
   0x080484c9 <+5>:     and    $0xfffffff0,%esp
   0x080484cc <+8>:     sub    $0x130,%esp
   0x080484d2 <+14>:    mov    0xc(%ebp),%eax
   0x080484d5 <+17>:    mov    %eax,0x1c(%esp)
   0x080484d9 <+21>:    mov    0x10(%ebp),%eax
   0x080484dc <+24>:    mov    %eax,0x18(%esp)
   0x080484e0 <+28>:    mov    %gs:0x14,%eax
   0x080484e6 <+34>:    mov    %eax,0x12c(%esp)
   0x080484ed <+41>:    xor    %eax,%eax
   0x080484ef <+43>:    call   0x80483c0 
   0x080484f4 <+48>:    cmp    $0x3e8,%eax
   0x080484f9 <+53>:    je     0x8048531 
0x080484fb <+55>: call 0x80483c0 0x08048500 <+60>: mov $0x80486d0,%edx 0x08048505 <+65>: movl $0x3e8,0x8(%esp) 0x0804850d <+73>: mov %eax,0x4(%esp) 0x08048511 <+77>: mov %edx,(%esp) 0x08048514 <+80>: call 0x80483a0 ---Type to continue, or q to quit---q Quit (gdb) break *main+48 Breakpoint 1 at 0x80484f4 (gdb) commands 1 Type commands for breakpoint(s) 1, one per line. End with a line saying just "end". >set $eax = 1000 >c >end (gdb) r Starting program: /home/flag13/flag13 Breakpoint 1, 0x080484f4 in main () your token is b705702b-76a8-42b0-8844-3adabbe5ac58 [Inferior 1 (process 1330) exited with code 063] (gdb)
And there's our token :)
Keep in mind that when debugging a SUID binary, it actually runs as a normal binary, effectively dismissing the setuid bit. And LD_PRELOAD wouldn't work with a SUID binary.

Now go ahead and get the flag:
level13@nebula:~$ su flag13 -c getflag
You have successfully executed getflag on a target account

~ Dmitry

No comments:

Post a Comment