最近做了一遍angr_CTF的例题,收获还是挺大的,先看目录下的PPT,了解符号执行的原理和过程
而后可以使用angr解决例题,学会如何使用angr
我并不是刚刚知道有angr,之所以拖到现在学习,是我一直想不通:
符号执行在什么情况下适用?
这里,我写一些我个人的看法与见解,供同样有这个问题的师傅参考
首先是文件大小,文件越大,符号执行越复杂,分支越多。当然,文件小,不代表分支少。
如果分支太多,且约束条件太少,那么angr可能并不适用。
加粗字体为判断条件
参考文档
由于angr版本迭代,在练习过程中,一些API发生了更改,下面是一些纠正后的解题脚本
00_angr_find
import angr import sys # ! ELF 符号执行的二进制文件 elfPath = "/home/kali/Desktop/angr_ctf-master/dist/00_angr_find" # ? 创建一个Angr工程,用于加载ELF pjt = angr.Project(elfPath) # * 指定angr入口地址 initState = pjt.factory.entry_state() # ! 创建模拟管理器 simulation = pjt.factory.simgr(initState) # ? 指定正确路径地址 simulation.explore(find=0x08048678, avoid=0x08048666) # * 判断是否寻找到 if simulation.found: relState = simulation.found[0] print("Solved: ", relState.posix.dumps(sys.stdin.fileno())) else: print("no solve result")
01_angr_avoid
import angr import sys # ! ELF 符号执行的二进制文件 path = "/home/kali/Desktop/angr_ctf-master/dist/01_angr_avoid" # ? 创建一个Angr工程,用于加载ELF project = angr.Project(path) # * 指定angr入口状态 state = project.factory.entry_state() # ! 创建模拟管理器 simulation = project.factory.simgr(state) # ? 指定正确路径地址 simulation.explore(find=0x080485E0, avoid=0x080485A8) # * 判断是否寻找到 if simulation.found: relState = simulation.found[0] print("Solved: ", relState.posix.dumps(sys.stdin.fileno())) else: print("no found")
02_angr_find_condition
import angr import sys path = "/home/kali/Desktop/angr_ctf-master/dist/02_angr_find_condition" project = angr.Project(path) entryState = project.factory.entry_state() simulation = project.factory.simgr(entryState) # ! explore 所有state,dump出所有stdout缓冲区的value (格式化输出),判断是否存在字段,响应~ def findfunc(state:angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Good Job." in value def avoidfunc(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Try again." in value simulation.explore(find=findfunc, avoid=avoidfunc) if simulation.found: relstate = simulation.found[0] print(relstate.posix.dumps(sys.stdin.fileno())) else: print("not found")
03_angr_symbolic_registers
import angr import sys path = "/home/kali/Desktop/angr_ctf-master/dist/02_angr_find_condition" project = angr.Project(path) entryState = project.factory.entry_state() simulation = project.factory.simgr(entryState) # ! explore 所有state,dump出所有stdout缓冲区的value (格式化输出),判断是否存在字段,响应~ def findfunc(state:angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Good Job." in value def avoidfunc(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Try again." in value simulation.explore(find=findfunc, avoid=avoidfunc) if simulation.found: relstate = simulation.found[0] print(relstate.posix.dumps(sys.stdin.fileno())) else: print("not found")
04_angr_symbolic_stack
import angr import sys import claripy path = "/home/kali/Desktop/angr_ctf-master/dist/04_angr_symbolic_stack" project = angr.Project(path) blankState = project.factory.blank_state(addr=0x08048697) # ! 创建符号变量 arg1 arg2 arg1 = claripy.BVS("arg1", 32) arg2 = claripy.BVS("arg2", 32) # ! 设置ebp为当前esp (由于跳过了scanf函数的缘故,需要模拟前面执行: push ebp esp) blankState.regs.ebp = blankState.regs.esp # ! 入栈的都是地址~ 8个字节 blankState.regs.esp -= 8 # ! 入栈顺序~ blankState.stack_push(arg1) blankState.stack_push(arg2) simulation = project.factory.simgr(blankState) def is_successful(state): stdout_output = state.posix.dumps(sys.stdout.fileno()) return b'Good Job.' in stdout_output def should_abort(state): stdout_output = state.posix.dumps(sys.stdout.fileno()) return b'Try again.' in stdout_output simulation.explore(find=is_successful, avoid=should_abort) if simulation.found: relState = simulation.found[0] value1 = relState.solver.eval(arg1) value2 = relState.solver.eval(arg2) print("solved: ", "%u" % value1, "%u" % value2) else: print("not found")
05_angr_symbolic_memory
import claripy import angr import sys path = "/home/kali/Desktop/angr_ctf-master/dist/05_angr_symbolic_memory" project = angr.Project(path) state = project.factory.blank_state(addr=0x08048601) # angr.SimState.memory.store() # ! 8 (bytes) * 8 (bits) input1 = claripy.BVS("input1", 64) input2 = claripy.BVS("input2", 64) input3 = claripy.BVS("input3", 64) input4 = claripy.BVS("input4", 64) state.memory.store(0x0A1BA1C0, input1) state.memory.store(0x0A1BA1C8, input2) state.memory.store(0x0A1BA1D0, input3) state.memory.store(0x0A1BA1D8, input4) simulation = project.factory.simgr(state) def is_successful(state: angr.SimState): stdout_output = state.posix.dumps(sys.stdout.fileno()) return b'Good Job.' in stdout_output def should_abort(state: angr.SimState): stdout_output = state.posix.dumps(sys.stdout.fileno()) return b'Try again.' in stdout_output simulation.explore(find=is_successful, avoid=should_abort) if simulation.found: relState = simulation.found[0] value1 = relState.solver.eval(input1, cast_to=bytes).decode('utf-8') value2 = relState.solver.eval(input2, cast_to=bytes).decode('utf-8') value3 = relState.solver.eval(input3, cast_to=bytes).decode('utf-8') value4 = relState.solver.eval(input4, cast_to=bytes).decode('utf-8') print("solved: ", value1, value2, value3, value4) else: print("not found")
06_angr_symbolic_dynamic_memory
import angr import claripy import sys path = "/home/kali/Desktop/angr_ctf-master/dist/06_angr_symbolic_dynamic_memory" project = angr.Project(path) state = project.factory.blank_state(addr=0x08048699) arg1 = claripy.BVS("arg1", 64) arg2 = claripy.BVS("arg2", 64) randAdrr1 = state.regs.esp-0x100 randAdrr2 = state.regs.esp-0x188 state.memory.store(0x0ABCC8A4, randAdrr1, endness=project.arch.memory_endness) state.memory.store(0x0ABCC8AC, randAdrr2, endness=project.arch.memory_endness) state.memory.store(randAdrr1, arg1) state.memory.store(randAdrr2, arg2) simulation = project.factory.simgr(state) def isSuccessful(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Good Job." in value def isAvoid(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Try again." in value simulation.explore(find=isSuccessful, avoid=isAvoid) if simulation.found: relState = simulation.found[0] value1 = relState.solver.eval(arg1, cast_to=bytes).decode('utf-8') value2 = relState.solver.eval(arg2, cast_to=bytes).decode('utf-8') print("solved: ", value1, value2) else: print("not found")
07_angr_symbolic_file
import angr import claripy import sys path = "/home/kali/Desktop/angr_ctf-master/dist/07_angr_symbolic_file" project = angr.Project(path) # ! 此题多解 可以使用simSymbolcMemory模拟文件系统 def isSuccessful(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Good Job." in value def isAvoid(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Try again." in value # ! 方案1 # state = project.factory.blank_state(addr=0x0804893C) # arg1 = claripy.BVS("arg1", 64) # state.memory.store(0x0804A0A0, arg1) # ! 方案2 state = project.factory.blank_state(addr=0x080488ED) arg1 = claripy.BVS("arg1", 64) filename = "OJKSQYDP.txt" file = angr.SimFile(filename, content=arg1,size=40*8) file.set_state(state) state.fs.insert(filename, file) assert state.fs.get(filename) is file # * go simulation = project.factory.simgr(state) simulation.explore(find=isSuccessful, avoid=isAvoid) if simulation.found: relState = simulation.found[0] value1 = relState.solver.eval(arg1, cast_to=bytes).decode('utf-8') print("solved: ", value1) else: print("not found")
08_angr_constraints
import angr import claripy import sys path = "/home/kali/Desktop/angr_ctf-master/dist/08_angr_constraints" project = angr.Project(path) state = project.factory.blank_state(addr=0x08048625) arg = claripy.BVS("arg", 16*8) state.memory.store(0x0804A050, arg) simulation = project.factory.simgr(state) simulation.explore(find=0x08048673) if simulation.found: relState = simulation.found[0] # ! 添加约束条件 简化规则,不然复杂度太大 bitvector = relState.memory.load(0x0804A050, 16) key = claripy.BVV("AUPDNNPROEZRJWKB".encode("utf-8"), 16*8) relState.add_constraints(bitvector == key) arg = relState.solver.eval(arg, cast_to=bytes).decode('utf-8') print("solved: ", arg) else: print("not found")
09_angr_hooks
import angr import claripy import sys path = "/home/kali/Desktop/angr_ctf-master/dist/08_angr_constraints" project = angr.Project(path) state = project.factory.blank_state(addr=0x08048625) arg = claripy.BVS("arg", 16*8) state.memory.store(0x0804A050, arg) simulation = project.factory.simgr(state) simulation.explore(find=0x08048673) if simulation.found: relState = simulation.found[0] # ! 添加约束条件 简化规则,不然复杂度太大 bitvector = relState.memory.load(0x0804A050, 16) key = claripy.BVV("AUPDNNPROEZRJWKB".encode("utf-8"), 16*8) relState.add_constraints(bitvector == key) arg = relState.solver.eval(arg, cast_to=bytes).decode('utf-8') print("solved: ", arg) else: print("not found")
10_angr_simprocedures
import angr import claripy import sys path = "/home/kali/Desktop/angr_ctf-master/dist/10_angr_simprocedures" project = angr.Project(path) class replaceHook(angr.SimProcedure): def run(self, a1: int, a2: int): stateVector = self.state.memory.load(a1, 16) equalsVector = claripy.BVV("ORSDDWXHZURJRBDH".encode('utf-8'), size=16*8) return claripy.If(equalsVector == stateVector, claripy.BVV(1, 32), claripy.BVV(0, 32)) project.hook_symbol("check_equals_ORSDDWXHZURJRBDH", replaceHook()) def isSuccessful(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Good Job." in value def isAvoid(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Try again." in value state = project.factory.entry_state() simulation = project.factory.simgr(state) simulation.explore(find=isSuccessful, avoid=isAvoid) if simulation.found: relState = simulation.found[0] value = relState.posix.dumps(sys.stdin.fileno()).decode('utf-8') print("solved: ", value) else: print("not found")
11_angr_sim_scanf
import angr import claripy import sys path = "/home/kali/Desktop/angr_ctf-master/dist/11_angr_sim_scanf" project = angr.Project(path) state = project.factory.entry_state() # ! SimProcedure 替代 scanf, 这里不能使用blank_state指定入口状态 class replaceHook(angr.SimProcedure): def run(self, format, arg1, arg2): # ! unsigned int 8 bits * 4 bytes param1 = claripy.BVS("arg1", 32) param2 = claripy.BVS("arg2", 32) self.state.memory.store(arg1, param1, endness=project.arch.memory_endness) self.state.memory.store(arg2, param2, endness=project.arch.memory_endness) self.state.globals["params"] = (param1, param2) project.hook_symbol("__isoc99_scanf", replaceHook()) simulation = project.factory.simgr(state) def isSuccessful(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Good Job." in value def isAvoid(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Try again." in value simulation.explore(find=isSuccessful, avoid=isAvoid) if simulation.found: relState = simulation.found[0] value1 = relState.solver.eval(relState.globals["params"][0]) value2 = relState.solver.eval(relState.globals["params"][1]) print("solved: ", value1, value2) else: print("not found")
12_angr_veritesting
import angr import claripy import sys path = "/home/kali/Desktop/angr_ctf-master/dist/12_angr_veritesting" project = angr.Project(path) state = project.factory.entry_state() simulation = project.factory.simgr(state, veritesting=True) def isSuccessful(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Good Job." in value def isAvoid(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Try again." in value simulation.explore(find=isSuccessful, avoid=isAvoid) if simulation.found: relState = simulation.found[0] value1 = relState.posix.dumps(sys.stdin.fileno()).decode('utf-8') print("solved: ", value1) else: print("not found")
13_angr_static_binary
import angr import claripy import sys path = "/home/kali/Desktop/angr_ctf-master/dist/13_angr_static_binary" project = angr.Project(path) state = project.factory.entry_state() # ? https://github.com/angr/angr/tree/master/angr/procedures/libc project.hook(0x0804ED40, angr.SIM_PROCEDURES['libc']['printf']()) project.hook(0x0804ED80, angr.SIM_PROCEDURES['libc']['scanf']()) project.hook(0x0804F350, angr.SIM_PROCEDURES['libc']['puts']()) project.hook(0x08048D10, angr.SIM_PROCEDURES["glibc"]["__libc_start_main"]()) project.hook(0x08048280, angr.SIM_PROCEDURES["libc"]["strcmp"]()) simulation = project.factory.simgr(state) def isSuccessful(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Good Job." in value def isAvoid(state: angr.SimState): value = state.posix.dumps(sys.stdout.fileno()) return b"Try again." in value simulation.explore(find=isSuccessful, avoid=isAvoid) if simulation.found: relState = simulation.found[0] value1 = relState.posix.dumps(sys.stdin.fileno()).decode('utf-8') print("solved: ", value1) else: print("not found")
14_angr_shared_library
import angr import claripy # ! 载入动态链接库 path = "/home/kali/Desktop/angr_ctf-master/dist/lib14_angr_shared_library.so" # ! 随机基址 baseAddr = 0x4000000 project = angr.Project(path, load_options= { "main_opts": { "base_addr": baseAddr }, }) # ! 随机地址 置参数(符号向量) strPointer = claripy.BVV(0x3000000, size=8*4) arg = claripy.BVS("arg", size=8*8) # ! 调用函数 state = project.factory.call_state(baseAddr+0x000006D7, strPointer, claripy.BVV(8, 32)) state.memory.store(strPointer, arg) simulation = project.factory.simgr(state) # ! 到达函数结尾 simulation.explore(find=baseAddr+0x783) if simulation.found: relState = simulation.found[0] # ! 添加约束条件 返回值 != 0 relState.add_constraints(relState.regs.eax != 0) value1 = relState.solver.eval(arg, cast_to=bytes).decode('utf-8') print("solved: ", value1) else: print("not found")
发表回复