Rating: 5.0

This challenge consists of 999 binaries, each of with accepts a single character and prints either "Success" or "Nope" if the character was right or wrong, respectively.

As someone who likes angr, I decided this would be a quick way to solve. I wrote a very simple angr script that symbolically executes each binary and looks for the word "Success" in the output, then prints the input:


import angr
import sys
import logging

logging.getLogger('angr').setLevel(logging.CRITICAL)

result = ""

def should_abort(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return "Nope" in stdout_output

def is_successful(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return "OK" in stdout_output

for i in range(999): # ifor each binary
idx = i + 1 # lazy :)
progname=str(idx).zfill(3) + ".c.out"
project = angr.Project(progname)
state = project.factory.entry_state()
simgr = project.factory.simgr(state)
simgr.explore(find=is_successful, avoid=should_abort)
if simgr.found:
solution_state=simgr.found[0]
result += str(solution_state.posix.dumps(sys.stdin.fileno()))
print(result)
else:
raise Exception("no solution found for {}".format(progname))


We get way more output than is wanted, but just output to a file and grep for RITSEC and you'll get the flag!

Original writeup (https://github.com/b01lers/b01lers-library/tree/master/2019ritsec/pwn/168-999-bottles).