dimanche 28 janvier 2018

Solving a CTF chall the [crazy|OMG] way (FIC2018)

This is the third blogpost about the same crackme, you can read the first two ones here:
This time, an extremely simple solution. You thought that pin was almost cheating? Get prepared to see worse.

1/ Basic recon

mitsurugi@dojo:~/chall/FIC2018/v24$ ls -l a.out 
-rwxr-xr-x 1 mitsurugi mitsurugi 15568 janv. 24 14:30 a.out
mitsurugi@dojo:~/chall/FIC2018/v24$ strings a.out 
/lib64/ld-linux-x86-64.so.2
libc.so.6
exit
read
malloc
__libc_start_main
write
free
__gmon_start__
GLIBC_2.2.5
tPHc
fffff.
[]A\A]A^A_
;*3$"
FAILEDnWINnENTER PASS :              //look this line
 (... snip snip snip ...)
mitsurugi@dojo:~/chall/FIC2018/v24$

So, we imagine that FAILED means fail and WIN is the winning message, right?

That's all we need to know! 
Yes. gdb? nope. asm? nope. reversing capabilities? nope. Lazinest? A lot.

2/ Hey, you like surprises and python?

you know angr, right? If not, check this awesome program. It can explore binaries, instrument them, modify them on the fly, explore all paths, and all by itself!

It blews my minds me on this:

#! /usr/bin/env python
# You are not judged because you fall. 
# You are judged by the way you get up after a fall.
#                          0xMitsurugi

import angr, datetime

print "Starting"
start = datetime.datetime.now()
#Loading the binary
proj = angr.Project('./a.out')
#Create a simulation manager
simgr = proj.factory.simgr()
#We search the word WIN somewhere in the file descriptor 1 (standard output)
simgr.explore(find=lambda s: "WIN" in s.posix.dumps(1))

#angr works hard here ...

#Let's see which input produce a 'WIN' in output
s = simgr.found[0]
# file descriptor 0 is standard input
flag = s.posix.dumps(0)

print "The flag is: %s " % flag
#At least we know this challenge is buggy..
print "\nWe know this challenge is bugged :("
print "Flag in hex is: %s" % (flag.encode('hex'))
end = datetime.datetime.now()
print "Time used: %s" % (end - start)

Basically we tell angr to open the binary, and explore it (like fuzzing, but better :) ) until it found the word "WIN" in the standard output. And then, we print the standard input which generates this output. Sounds crazy?

And, as you guess, in only 7 minutes, without any prior knowledge:

mitsurugi@dojo:~/chall/FIC2018/v24$ ./solver.py 
Starting
The flag is: iWaseMyTime 

We know this challenge is bugged :(
Flag in hex is: 6957617300654d7954696d65
Time used: 0:07:22.198219
mitsurugi@dojo:~/chall/FIC2018/v24$

Without the bug, angr would have found the good flag, but it remains impressive: the angr solution works. The only thing to know is that the binary prints WIN for victory, which could be found with a strings command..

Ready? Prepare yourself!
0xMitsurugi

Aucun commentaire:

Publier un commentaire