├── .gitignore ├── README.md ├── problems ├── 00_angr_find ├── 01_angr_avoid ├── 02_angr_find_condition ├── 03_angr_symbolic_registers ├── 04_angr_symbolic_stack ├── 05_angr_symbolic_memory ├── 06_angr_symbolic_dynamic_memory ├── 07_angr_symbolic_file ├── 08_angr_constraints ├── 09_angr_hooks ├── 10_angr_simprocedures ├── 11_angr_sim_scanf ├── 12_angr_veritesting ├── 13_angr_static_binary ├── 14_angr_shared_library ├── 15_angr_arbitrary_read ├── 16_angr_arbitrary_write ├── 17_angr_arbitrary_jump └── lib14_angr_shared_library.so └── solutions ├── 00_angr_find.py ├── 01_angr_avoid.py ├── 02_angr_condition.py ├── 03_angr_symbolic_register.py ├── 04_angr_stack.py ├── 05_angr_symbolic_memory.py ├── 06_angr_heap.py ├── 07_angr_symbolic_file.py ├── 08_angr_constraints.py ├── 08_angr_constraints_hook.py ├── 08_angr_constraints_veritesting.py ├── 09_angr_hook.py ├── 10_angr_simprocedures.py ├── 11_angr_simscanf.py ├── 12_angr_veritesting.py ├── 13_static_binary.py ├── 14_angr_just_loadso.py ├── 14_angr_load_so.py └── 15_angr_arbitary_read.py /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angr_Tutorial_For_CTF 2 | angr is a very useful binary analysis framework. Many ctfers like using angr to save their time in CTF. 3 | However angr is a little bit difficult for beginners as its update from version 7 to version 8. And many great tutorials for angr in CTF can't work well. I use this git repo to record my learning experience for angr based on this fantasic tutorial [angr_ctf](https://github.com/jakespringer/angr_ctf), [angr Documentation](https://docs.angr.io/) and [angr API documentation](http://angr.io/api-doc/index.html). Many thanks to them. And I hope that I can keep going for some time and being familiar with angr in the future. 4 | 5 | # Installation 6 | I use pypy for running angr in a faster way. Here are my installation instructions. 7 | ```bash 8 | conda create -n angr # a clean environment 9 | conda activate angr 10 | conda install -c conda-forge pypy3.6 11 | wget https://bootstrap.pypa.io/get-pip.py 12 | pypy3 get-pip.py 13 | pypy3 -m pip install angr # then wait and have a rest 14 | ``` 15 | 16 | # How to use this repo 17 | I just use the schedule made by angr_ctf and update the codes support by the newest angr. So if you want to learn angr with me, you can clone this repo and follow the levels. 18 | - every problem has solution scripts, and you can read the solutions to learn how to use angr. But you need to analysis the binary by yourself.(It's a common problem in CTF in Re or Pwn) 19 | - some codes don't have comment as to the code is clear enough or the same code have been commented in before levels 20 | 21 | I think codes' comments are enough, however, if you have questions you can open an issue and we can disscuss. I hope this repo can be helpful. 22 | -------------------------------------------------------------------------------- /problems/00_angr_find: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/00_angr_find -------------------------------------------------------------------------------- /problems/01_angr_avoid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/01_angr_avoid -------------------------------------------------------------------------------- /problems/02_angr_find_condition: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/02_angr_find_condition -------------------------------------------------------------------------------- /problems/03_angr_symbolic_registers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/03_angr_symbolic_registers -------------------------------------------------------------------------------- /problems/04_angr_symbolic_stack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/04_angr_symbolic_stack -------------------------------------------------------------------------------- /problems/05_angr_symbolic_memory: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/05_angr_symbolic_memory -------------------------------------------------------------------------------- /problems/06_angr_symbolic_dynamic_memory: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/06_angr_symbolic_dynamic_memory -------------------------------------------------------------------------------- /problems/07_angr_symbolic_file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/07_angr_symbolic_file -------------------------------------------------------------------------------- /problems/08_angr_constraints: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/08_angr_constraints -------------------------------------------------------------------------------- /problems/09_angr_hooks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/09_angr_hooks -------------------------------------------------------------------------------- /problems/10_angr_simprocedures: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/10_angr_simprocedures -------------------------------------------------------------------------------- /problems/11_angr_sim_scanf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/11_angr_sim_scanf -------------------------------------------------------------------------------- /problems/12_angr_veritesting: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/12_angr_veritesting -------------------------------------------------------------------------------- /problems/13_angr_static_binary: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/13_angr_static_binary -------------------------------------------------------------------------------- /problems/14_angr_shared_library: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/14_angr_shared_library -------------------------------------------------------------------------------- /problems/15_angr_arbitrary_read: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/15_angr_arbitrary_read -------------------------------------------------------------------------------- /problems/16_angr_arbitrary_write: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/16_angr_arbitrary_write -------------------------------------------------------------------------------- /problems/17_angr_arbitrary_jump: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/17_angr_arbitrary_jump -------------------------------------------------------------------------------- /problems/lib14_angr_shared_library.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hustcw/Angr_Tutorial_For_CTF/b6a84231a28fe27aef18290953bfe34d25e55719/problems/lib14_angr_shared_library.so -------------------------------------------------------------------------------- /solutions/00_angr_find.py: -------------------------------------------------------------------------------- 1 | import angr 2 | 3 | def main(): 4 | # create project 5 | proj = angr.Project('../problems/00_angr_find') 6 | # entry point 7 | init_state = proj.factory.entry_state() 8 | # create simulation 9 | simulation = proj.factory.simgr(init_state) 10 | # expected address 11 | print_good = 0x804867d 12 | # start explore 13 | simulation.explore(find=print_good) 14 | 15 | if simulation.found: 16 | solution = simulation.found[0] 17 | print('flag: ', solution.posix.dumps(0)) 18 | else: 19 | print('no solution') 20 | 21 | if __name__ == '__main__': 22 | main() 23 | 24 | 25 | -------------------------------------------------------------------------------- /solutions/01_angr_avoid.py: -------------------------------------------------------------------------------- 1 | import angr 2 | 3 | # create project 4 | proj = angr.Project('../problems/01_angr_avoid') 5 | # initial_state at the entry point of the binary 6 | init_state = proj.factory.entry_state() 7 | # create simulation 8 | simulation = proj.factory.simgr(init_state) 9 | 10 | print_good = 0x080485e5 11 | avoid_addr = 0x080485A8 12 | 13 | simulation.explore(find=print_good, avoid=avoid_addr) 14 | 15 | if simulation.found: 16 | # if found stash is not empty, get the first state as the solution 17 | solution = simulation.found[0] 18 | print(solution.posix.dumps(0)) 19 | 20 | -------------------------------------------------------------------------------- /solutions/02_angr_condition.py: -------------------------------------------------------------------------------- 1 | import angr,sys 2 | 3 | def main(): 4 | proj = angr.Project('../problems/02_angr_find_condition') 5 | init_state = proj.factory.entry_state() 6 | simulation = proj.factory.simgr(init_state) 7 | 8 | simulation.explore(find=is_successful, avoid=should_abort) 9 | 10 | if simulation.found: 11 | solution = simulation.found[0] 12 | print('flag: ', solution.posix.dumps(sys.stdin.fileno())) 13 | else: 14 | print('no flag') 15 | 16 | # set expected function 17 | # note: sys.stdout.fileno() is the stdout file discription number. you can replace it by 1 18 | # note: state.posix is the api for posix, and dumps(file discription number) will get the 19 | # bytes for the pointed file. 20 | def is_successful(state): 21 | return b"Good Job" in state.posix.dumps(sys.stdout.fileno()) 22 | 23 | # set disexpected function 24 | def should_abort(state): 25 | return b"Try again" in state.posix.dumps(sys.stdout.fileno()) 26 | 27 | if __name__ == '__main__': 28 | main() 29 | -------------------------------------------------------------------------------- /solutions/03_angr_symbolic_register.py: -------------------------------------------------------------------------------- 1 | import angr 2 | import claripy 3 | import sys 4 | 5 | def main(): 6 | project = angr.Project('../problems/03_angr_symbolic_registers') 7 | 8 | # start address 9 | start_address = 0x08048980 10 | 11 | # use blank state for create a clean state and 12 | # we need assign some regs or mems next 13 | init_state = project.factory.blank_state(addr=start_address) 14 | 15 | # TODO: create some Bitvector Symbols 16 | password0 = claripy.BVS('p0', 32) 17 | password1 = claripy.BVS('p1', 32) 18 | password2 = claripy.BVS('p2', 32) 19 | 20 | # TODO: assign some regs 21 | init_state.regs.eax = password0 22 | init_state.regs.ebx = password1 23 | init_state.regs.edx = password2 24 | 25 | simulation = project.factory.simgr(init_state) 26 | simulation.explore(find=is_successful, avoid=should_abort) 27 | 28 | if simulation.found: 29 | solution_state = simulation.found[0] 30 | # TODO: get the value of Bitvector symbols of the solution_state 31 | solution0 = solution_state.solver.eval(password0) 32 | solution1 = solution_state.solver.eval(password1) 33 | solution2 = solution_state.solver.eval(password2) 34 | print('flag: ', hex(solution0), hex(solution1), hex(solution2)) 35 | 36 | else: 37 | print('no flag') 38 | 39 | def is_successful(state): 40 | return b"Good Job." in state.posix.dumps(sys.stdout.fileno()) 41 | 42 | def should_abort(state): 43 | return b"Try again." in state.posix.dumps(sys.stdout.fileno()) 44 | 45 | 46 | if __name__ == '__main__': 47 | main() -------------------------------------------------------------------------------- /solutions/04_angr_stack.py: -------------------------------------------------------------------------------- 1 | import angr 2 | import claripy 3 | import sys 4 | 5 | def is_successful(state): 6 | return b'Good Job.' in state.posix.dumps(sys.stdout.fileno()) 7 | 8 | def should_abort(state): 9 | return b'Try again.' in state.posix.dumps(sys.stdout.fileno()) 10 | 11 | def main(): 12 | proj = angr.Project('../problems/04_angr_symbolic_stack') 13 | 14 | # this start address can be calculate according to 0x18+0x4-0x10+0x4 == 0x8+0x4+0x4 (esp - 8 - 4 - 4) 15 | start_addr = 0x08048697 16 | init_state = proj.factory.blank_state(addr=start_addr) 17 | 18 | init_state.regs.ebp = init_state.regs.esp 19 | password1 = init_state.solver.BVS('password1', 32) 20 | password2 = init_state.solver.BVS('password2', 32) 21 | 22 | # simulate the stack 23 | padding_len = 0x8 24 | init_state.regs.esp -= padding_len 25 | # because the password2 locate at ebp-0x8 (ebp -> esp : high -> low), ebp-0x9, ebp-0xa, ebp-0xb 26 | # the same to password1 27 | 28 | init_state.stack_push(password1) 29 | init_state.stack_push(password2) 30 | 31 | simulation = proj.factory.simgr(init_state) 32 | simulation.explore(find=is_successful, avoid=should_abort) 33 | 34 | if simulation.found: 35 | solution = simulation.found[0] 36 | # TODO: get the value of Bitvector symbols 37 | solution_password1 = solution.solver.eval(password1) 38 | solution_password2 = solution.solver.eval(password2) 39 | print('flag: ', solution_password1, solution_password2) 40 | 41 | else: 42 | print('no flag') 43 | 44 | 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /solutions/05_angr_symbolic_memory.py: -------------------------------------------------------------------------------- 1 | import angr 2 | import sys 3 | 4 | def success(state): 5 | return b'Good Job.' in state.posix.dumps(sys.stdout.fileno()) 6 | 7 | def fail(state): 8 | return b'Try again.' in state.posix.dumps(sys.stdout.fileno()) 9 | 10 | def main(): 11 | proj = angr.Project('../problems/05_angr_symbolic_memory') 12 | 13 | # define start addr 14 | start_addr = 0x080485FE 15 | init_state = proj.factory.blank_state(addr=start_addr) 16 | 17 | # add memory symbol 18 | user_input = init_state.solver.BVS('user_input', 8*8) 19 | password1 = init_state.solver.BVS('password1', 8*8) 20 | password2 = init_state.solver.BVS('password2', 8*8) 21 | password3 = init_state.solver.BVS('password3', 8*8) 22 | 23 | # store in memory 24 | init_state.memory.store(0x0A1BA1C0, user_input) 25 | init_state.memory.store(0x0A1BA1C8, password1) 26 | init_state.memory.store(0x0A1BA1D0, password2) 27 | init_state.memory.store(0x0A1BA1D8, password3) 28 | 29 | # prepare simulation 30 | simulation = proj.factory.simgr(init_state) 31 | 32 | simulation.explore(find=success, avoid=fail) 33 | 34 | if simulation.found: 35 | solution_state = simulation.found[0] 36 | input1 = solution_state.solver.eval(user_input, cast_to=bytes) 37 | input2 = solution_state.solver.eval(password1, cast_to=bytes) 38 | input3 = solution_state.solver.eval(password2, cast_to=bytes) 39 | input4 = solution_state.solver.eval(password3, cast_to=bytes) 40 | print('flag: ', input1, input2, input3, input4) 41 | else: 42 | raise Exception('Counld not find flag') 43 | 44 | if __name__ == '__main__': 45 | main() 46 | -------------------------------------------------------------------------------- /solutions/06_angr_heap.py: -------------------------------------------------------------------------------- 1 | import angr 2 | import sys 3 | 4 | def main(): 5 | proj = angr.Project('../problems/06_angr_symbolic_dynamic_memory') 6 | init_state = proj.factory.blank_state(addr=0x08048696) 7 | 8 | fake_heap_addr = 0x602000 9 | buffer0 = 0x0ABCC8A4 10 | buffer1 = 0x0ABCC8AC 11 | password1 = init_state.solver.BVS('password1',8*8) 12 | password2 = init_state.solver.BVS('password2',8*8) 13 | 14 | init_state.mem[buffer0].uint32_t = fake_heap_addr 15 | init_state.mem[buffer1].uint32_t = fake_heap_addr + 9 16 | # can be substituted by the following two instructions 17 | # init_state.memory.store(buffer0, fake_heap_addr, endness=proj.arch.memory_endness) 18 | # init_state.memory.store(buffer1, fake_heap_addr+9, endness=proj.arch.memory_endness) 19 | 20 | init_state.memory.store(0x602000, password1) 21 | init_state.memory.store(0x602000+9, password2) 22 | 23 | simulation = proj.factory.simgr(init_state) 24 | simulation.explore(find=success, avoid=fail) 25 | 26 | if simulation.found: 27 | solu_state = simulation.found[0] 28 | flag = solu_state.solver.eval(password1, cast_to=bytes) + solu_state.solver.eval(password2, cast_to=bytes) 29 | print('flag: ', flag) 30 | else: 31 | raise Exception('Could not find the solution') 32 | 33 | def success(state): 34 | return b'Good Job.' in state.posix.dumps(sys.stdout.fileno()) 35 | 36 | def fail(state): 37 | return b'Try again.' in state.posix.dumps(sys.stdout.fileno()) 38 | 39 | 40 | if __name__ == '__main__': 41 | main() 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /solutions/07_angr_symbolic_file.py: -------------------------------------------------------------------------------- 1 | import angr 2 | import sys 3 | 4 | def main(): 5 | proj = angr.Project('../problems/07_angr_symbolic_file') 6 | start_addr = 0x080488E7 7 | init_state = proj.factory.blank_state(addr=start_addr) 8 | 9 | # prepare file name and file size 10 | filename = 'OJKSQYDP.txt' 11 | symbolic_file_size_bytes = 64 12 | 13 | # create a symbolic memory and set state 14 | #symbolic_file_backing_memory = angr.state_plugins.SimSymbolicMemory() 15 | #symbolic_file_backing_memory.set_state(init_state) 16 | 17 | # store bvs into symbolic memory 18 | password = init_state.solver.BVS('password', symbolic_file_size_bytes * 8) 19 | #symbolic_file_backing_memory.store(0, password) 20 | 21 | # create simulate file, and insert into init_state 22 | password_file = angr.storage.SimFile(filename, content=password, size=symbolic_file_size_bytes) 23 | init_state.fs.insert(filename, password_file) 24 | 25 | simulation = proj.factory.simgr(init_state) 26 | simulation.explore(find=success, avoid=fail) 27 | 28 | if simulation.found: 29 | solu_state = simulation.found[0] 30 | print('flag: ', solu_state.solver.eval(password,cast_to=bytes)) 31 | else: 32 | print('fail to get flag') 33 | 34 | def success(state): 35 | return b'Good Job.' in state.posix.dumps(sys.stdout.fileno()) 36 | 37 | def fail(state): 38 | return b'Try again.' in state.posix.dumps(sys.stdout.fileno()) 39 | 40 | if __name__ == '__main__': 41 | main() 42 | -------------------------------------------------------------------------------- /solutions/08_angr_constraints.py: -------------------------------------------------------------------------------- 1 | # we have to avoid loop with conditional branch, so maybe we have to do some works just like this task 2 | import angr 3 | import sys 4 | 5 | def main(): 6 | # create project 7 | proj = angr.Project('../problems/08_angr_constraints') 8 | # entry point 9 | init_state = proj.factory.blank_state(addr=0x08048622) 10 | 11 | password = init_state.solver.BVS('password', 16 * 8) 12 | init_state.memory.store(0x0804a050, password) 13 | 14 | # create simulation 15 | simulation = proj.factory.simgr(init_state) 16 | checkpoints_addr = 0x0804866C 17 | # start explore 18 | simulation.explore(find=checkpoints_addr) 19 | 20 | if simulation.found: 21 | solution_state = simulation.found[0] 22 | load_symbol = solution_state.memory.load(0x0804a050, 16) 23 | # add a constraint manually 24 | # solution_state.add_constraints(load_symbol == 'AUPDNNPROEZRJWKB') 25 | solution_state.solver.add(load_symbol == 'AUPDNNPROEZRJWKB') 26 | flag = solution_state.solver.eval(password, cast_to=bytes) 27 | print('flag: ', flag) 28 | else: 29 | print('no solution') 30 | 31 | if __name__ == '__main__': 32 | main() 33 | -------------------------------------------------------------------------------- /solutions/08_angr_constraints_hook.py: -------------------------------------------------------------------------------- 1 | # we have to avoid loop with conditional branch, so maybe we have to do some works just like this task 2 | import angr 3 | import sys 4 | import claripy 5 | 6 | def main(): 7 | # create project 8 | proj = angr.Project('../problems/08_angr_constraints') 9 | # entry point 10 | # init_state = proj.factory.blank_state(addr=0x08048622) 11 | init_state = proj.factory.entry_state() 12 | 13 | # create simulation 14 | 15 | @proj.hook(0x08048673, length=5) 16 | def skip_check(state): 17 | get_buff = state.memory.load(0x0804A050, 16) 18 | state.regs.eax = state.solver.If( 19 | get_buff == 'AUPDNNPROEZRJWKB', 20 | state.solver.BVV(1, 32), 21 | state.solver.BVV(0, 32) 22 | ) 23 | # start explore 24 | 25 | simulation = proj.factory.simgr(init_state) 26 | 27 | 28 | simulation.explore(find=success, avoid=fail) 29 | 30 | if simulation.found: 31 | solution_state = simulation.found[0] 32 | flag = solution_state.posix.dumps(sys.stdin.fileno()) 33 | print('flag: ', flag) 34 | else: 35 | print('no solution') 36 | 37 | def success(state): 38 | return b'Good Job.' in state.posix.dumps(sys.stdout.fileno()) 39 | 40 | def fail(state): 41 | return b'Try again.' in state.posix.dumps(sys.stdout.fileno()) 42 | 43 | if __name__ == '__main__': 44 | main() 45 | -------------------------------------------------------------------------------- /solutions/08_angr_constraints_veritesting.py: -------------------------------------------------------------------------------- 1 | # we have to avoid loop with conditional branch, so maybe we have to do some works just like this task 2 | import angr 3 | import sys 4 | import claripy 5 | 6 | def main(): 7 | # create project 8 | proj = angr.Project('../problems/08_angr_constraints') 9 | # entry point 10 | # init_state = proj.factory.blank_state(addr=0x08048622) 11 | init_state = proj.factory.entry_state() 12 | 13 | simulation = proj.factory.simgr(init_state,veritesting=True) 14 | simulation.explore(find=success, avoid=fail) 15 | 16 | if simulation.found: 17 | solution_state = simulation.found[0] 18 | flag = solution_state.posix.dumps(sys.stdin.fileno()) 19 | print('flag: ', flag) 20 | else: 21 | print('no solution') 22 | 23 | def success(state): 24 | return b'Good Job.' in state.posix.dumps(sys.stdout.fileno()) 25 | 26 | def fail(state): 27 | return b'Try again.' in state.posix.dumps(sys.stdout.fileno()) 28 | 29 | if __name__ == '__main__': 30 | main() 31 | -------------------------------------------------------------------------------- /solutions/09_angr_hook.py: -------------------------------------------------------------------------------- 1 | # we have to avoid loop with conditional branch, so maybe we have to do some works just like this task 2 | import angr 3 | import claripy 4 | import sys 5 | 6 | def main(): 7 | # create project 8 | proj = angr.Project('../problems/09_angr_hooks') 9 | # entry point 10 | init_state = proj.factory.entry_state() 11 | 12 | checkpoints_addr = 0x080486B3 13 | skip_len = 5 14 | 15 | @proj.hook(checkpoints_addr, length=skip_len) 16 | def skip_check_equal(state): 17 | buffer_addr = 0x0804A054 18 | load_buffer_symbol = state.memory.load(buffer_addr, 16) 19 | check_str = 'XYMKBKUHNIQYNQXE' 20 | state.regs.eax = claripy.If( 21 | load_buffer_symbol == check_str, 22 | claripy.BVV(1, 32), 23 | claripy.BVV(0, 32) 24 | ) 25 | 26 | # create simulation 27 | simulation = proj.factory.simgr(init_state) 28 | simulation.explore(find=success, avoid=fail) 29 | 30 | if simulation.found: 31 | solution_state = simulation.found[0] 32 | flag = solution_state.posix.dumps(sys.stdin.fileno()) 33 | print('flag: ', flag) 34 | else: 35 | print('no solution') 36 | 37 | 38 | def success(state): 39 | return b'Good Job.' in state.posix.dumps(sys.stdout.fileno()) 40 | 41 | def fail(state): 42 | return b'Try again.' in state.posix.dumps(sys.stdout.fileno()) 43 | 44 | if __name__ == '__main__': 45 | main() 46 | -------------------------------------------------------------------------------- /solutions/10_angr_simprocedures.py: -------------------------------------------------------------------------------- 1 | import angr 2 | import claripy 3 | import sys 4 | 5 | def main(): 6 | # create project 7 | proj = angr.Project('../problems/10_angr_simprocedures') 8 | # entry point 9 | init_state = proj.factory.entry_state() 10 | 11 | class ReplaceEqual(angr.SimProcedure): 12 | def run(self, to_check, length): 13 | input_addr = to_check 14 | user_inputlen = length 15 | 16 | user_input_str = self.state.memory.load( 17 | input_addr, 18 | user_inputlen 19 | ) 20 | 21 | check_againt_str = 'ORSDDWXHZURJRBDH' 22 | return self.state.solver.If( 23 | user_input_str == check_againt_str, 24 | self.state.solver.BVV(1, 32), 25 | self.state.solver.BVV(0, 32) 26 | ) 27 | 28 | check_symbol = 'check_equals_ORSDDWXHZURJRBDH' 29 | proj.hook_symbol(check_symbol, ReplaceEqual()) 30 | 31 | def success(state): 32 | return b'Good Job.' in state.posix.dumps(sys.stdout.fileno()) 33 | 34 | def fail(state): 35 | return b'Try again.' in state.posix.dumps(sys.stdout.fileno()) 36 | 37 | # create simulation 38 | simulation = proj.factory.simgr(init_state) 39 | simulation.explore(find=success, avoid=fail) 40 | 41 | if simulation.found: 42 | solution_state = simulation.found[0] 43 | flag = solution_state.posix.dumps(sys.stdin.fileno()) 44 | print('flag: ', flag) 45 | else: 46 | print('no solution') 47 | 48 | if __name__ == '__main__': 49 | main() 50 | -------------------------------------------------------------------------------- /solutions/11_angr_simscanf.py: -------------------------------------------------------------------------------- 1 | import angr 2 | import claripy 3 | import sys 4 | 5 | def main(): 6 | proj = angr.Project('../problems/11_angr_sim_scanf') 7 | init_state = proj.factory.entry_state() 8 | 9 | class ReplaceScanf(angr.SimProcedure): 10 | def run(self, formatstring, addr1, addr2): 11 | buffer0 = claripy.BVS('buffer0', 8*4) 12 | buffer1 = claripy.BVS('buffer1', 8*4) 13 | 14 | # self.state.memory.store(addr1, buffer0, endness=proj.arch.memory_endness) 15 | # self.state.memory.store(addr2, buffer1, endness=proj.arch.memory_endness) 16 | # be careful at the endness ! 17 | self.state.mem[addr1].uint32_t = buffer0 18 | self.state.mem[addr2].uint32_t = buffer1 19 | 20 | self.state.globals['solutions'] = (buffer0, buffer1) 21 | 22 | scanf_symbol = '__isoc99_scanf' 23 | proj.hook_symbol(scanf_symbol, ReplaceScanf()) 24 | 25 | simulation = proj.factory.simgr(init_state) 26 | 27 | def success(state): 28 | return b'Good Job.' in state.posix.dumps(sys.stdout.fileno()) 29 | 30 | def fail(state): 31 | return b'Try again.' in state.posix.dumps(sys.stdout.fileno()) 32 | 33 | simulation.explore(find=success, avoid=fail) 34 | 35 | if simulation.found: 36 | solution_state = simulation.found[0] 37 | flag = solution_state.globals['solutions'] 38 | print('flag: ', solution_state.solver.eval(flag[0]), solution_state.solver.eval(flag[1])) 39 | else: 40 | raise Exception('no flag') 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /solutions/12_angr_veritesting.py: -------------------------------------------------------------------------------- 1 | # veritesting is a magic tech to solve enormous path problem. veritesting niubi!!! 2 | import angr 3 | import claripy 4 | import sys 5 | 6 | proj = angr.Project('../problems/12_angr_veritesting') 7 | init_state = proj.factory.entry_state() 8 | simulation = proj.factory.simgr(init_state, veritesting=True) 9 | 10 | def success(state): 11 | return b'Good Job.' in state.posix.dumps(sys.stdout.fileno()) 12 | 13 | def fail(state): 14 | return b'Try again.' in state.posix.dumps(sys.stdout.fileno()) 15 | 16 | simulation.explore(find=success, avoid=fail) 17 | 18 | if simulation.found: 19 | solution_state = simulation.found[0] 20 | print('flag: ', solution_state.posix.dumps(sys.stdin.fileno())) 21 | else: 22 | print('no flag') 23 | -------------------------------------------------------------------------------- /solutions/13_static_binary.py: -------------------------------------------------------------------------------- 1 | import angr 2 | import sys 3 | # create project 4 | proj = angr.Project('../problems/13_angr_static_binary') 5 | # initial_state at the entry point of the binary 6 | # init_state = proj.factory.blank_state(addr=0x080488FE) 7 | init_state = proj.factory.entry_state() 8 | # 不用entry_state, 用blank_state指定从main开始的话,可以不用替换__libc_start_main 9 | # replace static libc function with sim_procedure 10 | proj.hook(0x0804ED40, angr.SIM_PROCEDURES['libc']['printf']()) 11 | proj.hook(0x0804ED80, angr.SIM_PROCEDURES['libc']['scanf']()) 12 | proj.hook(0x0804F350, angr.SIM_PROCEDURES['libc']['puts']()) 13 | proj.hook(0x08048D10, angr.SIM_PROCEDURES['glibc']['__libc_start_main']()) 14 | 15 | # create simulation 16 | simulation = proj.factory.simgr(init_state) 17 | # 如果用了veritesting这里会解不出来 18 | 19 | print_good = 0x080489E6 20 | avoid_addr = 0x080489CF 21 | simulation.explore(find=print_good, avoid=avoid_addr) 22 | 23 | if simulation.found: 24 | # if found stash is not empty, get the first state as the solution 25 | solution = simulation.found[0] 26 | print('flag: ', solution.posix.dumps(sys.stdin.fileno())) 27 | else: 28 | print('no flag') -------------------------------------------------------------------------------- /solutions/14_angr_just_loadso.py: -------------------------------------------------------------------------------- 1 | import angr 2 | import claripy 3 | import sys 4 | 5 | # rebase so 6 | base = 0x4000000 7 | proj = angr.Project( 8 | '../problems/lib14_angr_shared_library.so', 9 | load_options={ 10 | 'main_opts' : { 11 | 'custom_base_addr' : base 12 | } 13 | } 14 | ) 15 | 16 | # set the pointor addr (which won't be used by default) 17 | buff_pointer = claripy.BVV(0x9000000, 32) 18 | validate_addr = base + 0x6d7 19 | # set init state by call_state (function call) 20 | init_state = proj.factory.call_state(validate_addr, buff_pointer, claripy.BVV(8, 32)) 21 | password = claripy.BVS('password', 8*8) 22 | init_state.memory.store(buff_pointer, password) 23 | 24 | simulation = proj.factory.simgr(init_state) 25 | success_addr = base + 0x783 26 | 27 | simulation.explore(find=success_addr) 28 | 29 | if simulation.found: 30 | solution_state = simulation.found[0] 31 | # add constraint that the function return must be true 32 | solution_state.add_constraints(solution_state.regs.eax != 0) 33 | 34 | print('flag: ', solution_state.solver.eval(password, cast_to=bytes)) 35 | 36 | -------------------------------------------------------------------------------- /solutions/14_angr_load_so.py: -------------------------------------------------------------------------------- 1 | import angr 2 | import claripy 3 | import sys 4 | 5 | proj = angr.Project('../problems/14_angr_shared_library') 6 | 7 | init_state = proj.factory.entry_state() 8 | 9 | simulation = proj.factory.simgr(init_state) 10 | 11 | def success(state): 12 | return b'Good Job.' in state.posix.dumps(sys.stdout.fileno()) 13 | 14 | def fail(state): 15 | return b'Try again.' in state.posix.dumps(sys.stdout.fileno()) 16 | 17 | simulation.explore(find=success, avoid=fail) 18 | if simulation.found: 19 | solution_state = simulation.found[0] 20 | print(solution_state.posix.dumps(sys.stdin.fileno())) 21 | 22 | -------------------------------------------------------------------------------- /solutions/15_angr_arbitary_read.py: -------------------------------------------------------------------------------- 1 | import angr 2 | import claripy 3 | import sys 4 | 5 | def main(): 6 | proj = angr.Project('../problems/15_angr_arbitrary_read') 7 | init_state = proj.factory.entry_state() 8 | 9 | class ReplacementScanf(angr.SimProcedure): 10 | 11 | def run(self, formatstring, check_key_address, input_buffer_address): 12 | scanf0 = claripy.BVS('scanf0', 4*8) 13 | scanf1 = claripy.BVS('scanf1', 20 * 8) 14 | 15 | for char in scanf1.chop(bits=8): 16 | self.state.add_constraints(char >= '0', char <='z') 17 | 18 | self.state.memory.store(check_key_address, scanf0, endness=proj.arch.memory_endness) 19 | self.state.memory.store(input_buffer_address, scanf1) 20 | 21 | self.state.globals['solution0'] = scanf0 22 | self.state.globals['solution1'] = scanf1 23 | 24 | scanf_symbol = '__isoc99_scanf' 25 | proj.hook_symbol(scanf_symbol, ReplacementScanf()) 26 | 27 | def check_puts(state): 28 | puts_parameter = state.memory.load(state.regs.esp+4, 4, endness=proj.arch.memory_endness) 29 | 30 | if state.solver.symbolic(puts_parameter): 31 | good_job_string_address = 0x484F4A47 32 | 33 | copied_state = state.copy() 34 | 35 | copied_state.add_constraints(puts_parameter == good_job_string_address) 36 | if copied_state.satisfiable(): 37 | state.add_constraints(puts_parameter == good_job_string_address) 38 | return True 39 | else: 40 | return False 41 | else: 42 | return False 43 | 44 | simulation = proj.factory.simgr(init_state) 45 | 46 | def success(state): 47 | puts_address = 0x8048370 48 | 49 | if state.addr == puts_address: 50 | return check_puts(state) 51 | else: 52 | return False 53 | 54 | 55 | simulation.explore(find=success) 56 | 57 | if simulation.found: 58 | solution_state = simulation.found[0] 59 | 60 | scanf0 = solution_state.globals['solution0'] 61 | scanf1 = solution_state.globals['solution1'] 62 | solution0 = solution_state.solver.eval(scanf0) 63 | solution1 = solution_state.solver.eval(scanf1, cast_to=bytes) 64 | print('overflow:', solution0, solution1) 65 | 66 | 67 | if __name__ == '__main__': 68 | main() --------------------------------------------------------------------------------