import angr
import claripy
import os
import requests
import shutil

base_url = "http://outsourz3d.ecsm2018.hack.cert.pl"

s = requests.session()

def download_binary():
	response = s.get(base_url+"/binary", stream=True)
	with open('binary', 'wb') as out_file:
		shutil.copyfileobj(response.raw, out_file)

def submit_passw0rd(param):
	return s.post(base_url+"/validate", data={'answer': param})


def solve_binary():
	#puts_addr = os.popen("objdump -d binary | grep 'puts@plt>' | grep -v 'plt>:' | awk '{ print $8 }'").read()
	puts_addr = os.popen("objdump -d binary | grep 'puts@plt>' | grep -v '@plt>:' | sed -n 2p | awk '{print $1}'").read()
	
	puts_addr = int(puts_addr[:-2].split('\n')[0], 16)
	puts_addr += 0x400000
	print(hex(puts_addr))

	#exit_func_addr = os.popen("objdump -d binary | grep '<exit@plt+' | grep 'callq' | awk '{print $8}' | sort | uniq -c | sort -n -r | awk '{print $2}'").read()
	exit_func_addr = os.popen("objdump -d binary | grep exit | sed -n 2p | awk '{print $8}'").read()


	exit_func_addr = 0x400000 + int(exit_func_addr.split('\n')[0], 16)
	print(hex(exit_func_addr))

	p = angr.Project("binary")
	arg1 = claripy.BVS('arg1', 32*8)
	simgr = p.factory.simulation_manager(p.factory.full_init_state(args=[p.filename, arg1]))
	simgr.explore(find=puts_addr, avoid=exit_func_addr)

	return simgr.found[0].solver.eval(arg1, cast_to=bytes).decode("utf-8")

if __name__ == '__main__':
	for i in range(0, 20):
		print("******************  "+str(i)+"/20  *******************")
		download_binary()
		res = solve_binary()
		print(submit_passw0rd(res).text)
		print("Found key>  " + res)
		print("./binary " + res + " >>> " + os.popen("./binary " + res).read())

	#	os.system("rm binary")
	

	#res = solve_binary()
	#print(res)
	#print(os.popen("./binary " + res).read())
