Rating:
# Asby
`100pts` `331 solves` `Binary`
-----
* *@author*: derbenoo
* *@note*: The original write-up is located [here](https://derbenoo.github.io/ctf/2017/08/11/sha2017_ctf_asby/)
-----
## Challenge Description
Eindbazen team member asby has by far been putting the most energy and time in creating the SHA2017 CTF. To honor his dedication and all his effort we created this challenge as an ode to him.
You can choose to reverse engineer this challenge or you can "asby" it. Good luck with the option you choose.
`asby.tgz 7422948a4034252d45cee02753b3d13b`
## Overview
We download and extract the provided archive file. Looks like we are dealing with a Windows executable:
```
$ file asby.exe
asby.exe: PE32 executable (console) Intel 80386, for MS Windows
```
We start our Win7 VM and execute the program:
```
$ ./asby.exe
What is the flag? test
Checking char 1:WRONG!
What is the flag? flag{123
Checking char 1:CORRECT!
Checking char 2:CORRECT!
Checking char 3:CORRECT!
Checking char 4:CORRECT!
Checking char 5:CORRECT!
Checking char 6:WRONG!
What is the flag?
```
Interesting, apparently we have some kind of oracle that we can query to check whether our flag is correct or not. It even tells us up to which character our flag is correct so it should be trivial to brute-force the flag out of the program.
## Extracting the flag via brute-forcing
We run Python 2.7 using the `cygwin` utility under Windows 7 to automate the flag extraction. The asby executable does not terminate after a wrong flag was entered, instead the user is prompted again to input a flag. We therefore execute the program and set the `stdout` pipe to non-blocking. Now we are able to input a flag, read the response and input another flag. We also know that a wrong character will cause the program to output `WRONG!`, which we can use to check whether or not we guessed the character correctly. We know that the flags are md5 digests and can therefore set our alphabet to `0123456789abcdef`. Lastly, we can already skip the first 5 characters as they are always `flag{`.
``` Python
#!/usr/bin/python2
import os, sys, fcntl, time, subprocess
from subprocess import Popen, PIPE, STDOUT
def setNonBlocking(fd):
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
flags = flags | os.O_NONBLOCK
fcntl.fcntl(fd, fcntl.F_SETFL, flags)
def read(p):
while True:
try:
out1 = p.stdout.read()
except IOError:
continue
else:
break
return out1
p = Popen("./asby.exe", stdin = PIPE, stdout = PIPE, stderr = PIPE, bufsize = 1)
setNonBlocking(p.stdout)
setNonBlocking(p.stderr)
flag= "flag{"
alphabet= "0123456789abcdef"
try:
while 1:
for ch in alphabet:
found= False
newFlag= flag+ch+"\n"
sys.stdout.write("\r"+newFlag[:-1])
p.stdin.write(newFlag)
out1= read(p)
time.sleep(0.05)
if not "WRONG!" in out1:
flag+= ch
found= True
break
if not found:
break
flag+= "}"
print "\nExtracted flag: "+flag
p.stdin.write(flag+"\n")
print read(p)
print "\nFinished."
p.kill()
except KeyboardInterrupt:
print "\nKilling asby.exe"
p.kill()
sys.exit()
```
The flag is: `flag{024baa8ac03ef22fdde61c0f11069f2f}`