CodeGateCTF - Angrybird
Angrybird was the first challenge that I solved on the 2017 CodeGate2017 CTF
. There was no description for the challenge just a binary.
When we opened the binary with IDA
, we can see the graph overview of the main function:
if we have a closer look at the call graph, every basic block is composed of a small check. if that check holds, then the flow of execution continues to the next block. Otherwise, the flow of execution terminates with a call to exit.
Everyone of those checks validate a partcular byte of a variable. That variable is input at the beguinning of main, and suppose to be the flag for this challenge itself.
We can see that at the end of the if else chain, the input string is printed.
When I attempted to execute the file, I found out that it wil not execute. The reason for this is because the functions at the beginning of main
are in charge to avoid execution of the program. One can see things like:
mov eax, 0
test eax, eax
jz _exit
symbolic execution magic
.
The framework that I used was angr. The name of the challenege also suggest using it I then realised.
In order to write a sucessfull angr
script. As many symbolic execution frameworks, they work very similar as path searching algorithms.
First we have to identify the initial
state where we want to begin our search. The address I choose for this was 0x004007c2
which s the address of the main function after the no execute shenanigans.
Once we have identified the initial_state
. then we have to identify the desired final_state
. this would be 0x0404fbc
which is the address of the call to puts at the end of main.
Okey, we know where to start and where to go. However it would be nice to feed the symbolic engine a series of states to avoid in order to process the search faster.
The approach I followed to choose these states was to find the xrefs of the _exit
function. This is because this function is always called if any of the checks fail.
This being said and with a bit of vim magic I came up with the following python script:
import sys
import angr
import simuvex
import claripy
p = angr.Project('angrybird')
e = p.factory.blank_state(addr=0x004007c2)
frame_addr = e.regs.rbp
frame_val = e.se.BVS('flag', 100*8)
e.memory.store(frame_addr, frame_val)
pg = p.factory.path_group(e)
to_avoid = [
0x4007fe,
0x400827,
0x400847,
0x400870,
0x40089f,
0x4008c8,
0x4008f1,
0x40091a,
0x400943,
0x400986,
0x4009af,
0x4009d8,
0x400a01,
0x400a2a,
0x400a56,
0x400a7b,
0x400aa4,
0x400aca,
0x400aef,
0x400b18,
0x400b4e,
0x400b77,
0x400bb3,
0x400be5,
0x400c0e,
0x400c40,
0x400c6c,
0x400c91,
0x400cba,
0x400cdf,
0x400d04,
0x400d2a,
0x400d4f,
0x400d78,
0x400da1,
0x400dc1,
0x400de6,
0x400e0f,
0x400e35,
0x400e61,
0x400e8a,
0x400ec7,
0x400eec,
0x400f15,
0x400f3e,
0x400f67,
0x400f87,
0x400fb0,
0x400fdf,
0x401004,
0x40102a,
0x40105a,
0x40107f,
0x4010a8,
0x4010d1,
0x4010f1,
0x40111a,
0x401143,
0x40116c,
0x401195,
0x4011d1,
0x4011fa,
0x40122a,
0x401253,
0x40127c,
0x4012a5,
0x4012ce,
0x4012f7,
0x40132d,
0x401356,
0x401382,
0x4013ab,
0x4013d4,
0x4013f4,
0x40141d,
0x401446,
0x40146f,
0x401498,
0x4014c1,
0x4014ea,
0x401513,
0x40153c,
0x401565,
0x40158e,
0x4015b7,
0x4015e0,
0x40160f,
0x401638,
0x401661,
0x40168a,
0x4016b3,
0x4016e2,
0x40170b,
0x401734,
0x40178a,
0x4017b3,
0x4017db,
0x401804,
0x40182d,
0x401863,
0x40188c,
0x4018c2,
0x4018eb,
0x401914,
0x40193d,
0x401966,
0x40198f,
0x4019b8,
0x4019e1,
0x401a0a,
0x401a33,
0x401a62,
0x401a8b,
0x401abb,
0x401ae4,
0x401b0d,
0x401b3c,
0x401b65,
0x401b8e,
0x401bb3,
0x401bdc,
0x401c04,
0x401c3a,
0x401c69,
0x401c92,
0x401cbb,
0x401ce4,
0x401d0d,
0x401d32,
0x401d58,
0x401d7d,
0x401da6,
0x401de2,
0x401e0b,
0x401e34,
0x401e59,
0x401e7f,
0x401ea4,
0x401ec9,
0x401ef2,
0x401f21,
0x401f4a,
0x401f73,
0x401f9c,
0x401fc5,
0x401fee,
0x402017,
0x402040,
0x402069,
0x402092,
0x4020b7,
0x4020dc,
0x402102,
0x402127,
0x402150,
0x402179,
0x4021af,
0x4021d8,
0x40220e,
0x402233,
0x40226c,
0x402292,
0x4022b7,
0x4022e0,
0x402309,
0x402332,
0x40235b,
0x402384,
0x4023ad,
0x4023d2,
0x4023f7,
0x40241c,
0x402442,
0x402467,
0x40249d,
0x4024cf,
0x40250b,
0x402534,
0x402559,
0x40257e,
0x4025a4,
0x4025c9,
0x4025f2,
0x40264f,
0x402681,
0x4026a6,
0x4026d5,
0x4026fe,
0x40272e,
0x402757,
0x40278d,
0x4027b6,
0x4027dc,
0x402801,
0x40282a,
0x402853,
0x40287c,
0x4028a5,
0x4028ce,
0x402900,
0x402929,
0x402952,
0x402977,
0x40299c,
0x4029c5,
0x4029ea,
0x402a24,
0x402a49,
0x402a78,
0x402aa1,
0x402aca,
0x402b00,
0x402b29,
0x402b52,
0x402b88,
0x402bad,
0x402bd6,
0x402bff,
0x402c24,
0x402c49,
0x402c78,
0x402ca1,
0x402cc6,
0x402cec,
0x402d11,
0x402d3a,
0x402d70,
0x402d99,
0x402dc2,
0x402de7,
0x402e10,
0x402e3e,
0x402e67,
0x402e99,
0x402ebe,
0x402eed,
0x402f12,
0x402f3b,
0x402f64,
0x402f9f,
0x402fc5,
0x402ff7,
0x403020,
0x403049,
0x403069,
0x403092,
0x4030bb,
0x4030e4,
0x40310d,
0x40312d,
0x403163,
0x40318c,
0x4031ac,
0x4031d5,
0x4031fe,
0x403227,
0x403250,
0x403279,
0x4032a2,
0x4032e9,
0x403316,
0x40333f,
0x403368,
0x4033a4,
0x4033da,
0x4033fa,
0x403423,
0x40344c,
0x403475,
0x40349e,
0x4034c7,
0x4034f0,
0x403510,
0x403539,
0x403568,
0x403591,
0x4035ba,
0x4035e3,
0x403619,
0x403639,
0x40366f,
0x403698,
0x4036c1,
0x403711,
0x40373a,
0x403763,
0x403799,
0x4037cf,
0x4037f8,
0x403821,
0x40384a,
0x403873,
0x40389c,
0x4038d2,
0x403908,
0x40393e,
0x403967,
0x40398c,
0x4039b2,
0x4039d7,
0x403a00,
0x403a29,
0x403a52,
0x403a7b,
0x403aa0,
0x403acf,
0x403af4,
0x403b23,
0x403b4c,
0x403b75,
0x403b9e,
0x403bc7,
0x403bf0,
0x403c15,
0x403c3a,
0x403c69,
0x403c92,
0x403cbb,
0x403cf1,
0x403d1a,
0x403d43,
0x403d6c,
0x403d91,
0x403db6,
0x403de5,
0x403e0e,
0x403e37,
0x403e60,
0x403e9f,
0x403ee0,
0x403f16,
0x403f3f,
0x403f75,
0x403f9a,
0x403fbf,
0x403fe5,
0x40400a,
0x404033,
0x404069,
0x404092,
0x4040bb,
0x4040e0,
0x404105,
0x40412b,
0x404150,
0x404179,
0x4041a2,
0x4041d8,
0x404201,
0x404227,
0x40424c,
0x404275,
0x40429e,
0x4042c7,
0x4042f0,
0x404319,
0x40433e,
0x404367,
0x40438c,
0x4043b1,
0x4043e3,
0x404409,
0x40442e,
0x404457,
0x404480,
0x4044a9,
0x4044d2,
0x4044fb,
0x404520,
0x404549,
0x40456e,
0x404593,
0x4045bc,
0x4045e1,
0x404607,
0x40462c,
0x404655,
0x40467e,
0x4046a7,
0x4046d0,
0x4046f9,
0x40471e,
0x404747,
0x40476c,
0x404791,
0x4047ba,
0x4047df,
0x404804,
0x404829,
0x40484f,
0x404874,
0x40489d,
0x4048c6,
0x4048eb,
0x404910,
0x40493f,
0x404968,
0x404991,
0x4049ba,
0x4049e3,
0x404a0c,
0x404a2c,
0x404a55,
0x404a7e,
0x404aa7,
0x404ad0,
0x404af9,
0x404b19,
0x404b42,
0x404b6b,
0x404b94,
0x404bbd,
0x404be6,
0x404c0f,
0x404c38,
0x404c7b,
0x404ca4,
0x404ccd,
0x404cf6,
0x404d1f,
0x404d48,
0x404d7e,
0x404da7,
0x404dd0,
0x404df9,
0x404e22,
0x404e4b,
0x404e70,
0x404e9f,
0x404ec8,
0x404ef1,
0x404f1a,
0x404f3f,
0x404f77,
0x404fa6]
pg.explore(find=0x0404FBC, avoid=to_avoid)
if len(pg.found) == 0:
print "not found anything"
sys.exit()
s = pg.found[0].state
print "flag", s.se.any_str(s.memory.load(frame_addr-0x50, 20))
Im_so_cute&pretty_:)