Angr_CTF Writeups 2
04_angr_symbolic_stack
這題要學的是把 stack 上的變數符號化,先附上 exploit04.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| from angr import * from claripy import *
p = Project('./04_angr_symbolic_stack') start = 0x8048697 state = p.factory.blank_state(addr = start)
state.regs.ebp = state.regs.esp state.regs.esp -= 0x8
pw0 = BVS('pw0', 32) pw1 = BVS('pw1', 32)
state.stack_push(pw0) state.stack_push(pw1)
simgr = p.factory.simgr(state)
def find(simgr): output = simgr.posix.dumps(1) return b'Good Job.' in output
def avoid(simgr): output = simgr.posix.dumps(1) return b'Try again.' in output
simgr.explore(find = find, avoid = avoid) if simgr.found: sol = simgr.found[0] flag1 = sol.solver.eval(pw0) flag2 = sol.solver.eval(pw1) print(flag1, flag2) else: print("qq")
|
第八、九行的目的是要模擬 stack 的正常運行的情況,然後再把我們符號化的兩個變數推進去。
剩下的部分幾乎都跟前面差不多。
Result:
1 2 3 4
| └─$ ./04_angr_symbolic_stack Enter the password: 1704280884 2382341151 Good Job.
|
05_angr_symbolic_memory
這次要學的是符號化記憶體。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| from angr import * from claripy import *
p = Project('./05_angr_symbolic_memory') start = 0x080485FE state = p.factory.blank_state(addr = start)
pw0 = BVS('pw0', 64) pw1 = BVS('pw1', 64) pw2 = BVS('pw2', 64) pw3 = BVS('pw3', 64)
pw_addr = 0x0A1BA1C0 state.memory.store(pw_addr, pw0) state.memory.store(pw_addr + 0x8, pw1) state.memory.store(pw_addr + 0x10, pw2) state.memory.store(pw_addr + 0x18, pw3)
simgr = p.factory.simgr(state)
def find(simgr): output = simgr.posix.dumps(1) return b'Good Job.' in output
def avoid(simgr): output = simgr.posix.dumps(1) return b'Try again.' in output
simgr.explore(find = find, avoid = avoid)
if simgr.found: sol = simgr.found[0] flag1 = sol.solver.eval(pw0, cast_to = bytes).decode() flag2 = sol.solver.eval(pw1, cast_to = bytes).decode() flag3 = sol.solver.eval(pw2, cast_to = bytes).decode() flag4 = sol.solver.eval(pw3, cast_to = bytes).decode() print(flag1, flag2, flag3, flag4) else: print('qq')
|
這次一樣把開始的位置設定在 scanf 後,然後模擬他把四個 8 bytes 的輸入存到 bss 段的動作,最後把結果轉成 bytes 再 decode 成 utf8。
剩下的部分照抄前面就行。
Result:
1 2 3 4
| └─$ ./05_angr_symbolic_memory Enter the password: NAXTHGNR JVSFTPWE LMGAUHWC XMDCPALU Good Job.
|
06_angr_symbolic_dynamc_memory
這題要符號化的是 heap 段的資料。
先附上 exploit06.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| from angr import * from claripy import *
p = Project("./06_angr_symbolic_dynamic_memory") start = 0x8048699 state = p.factory.blank_state(addr=start)
pw0 = BVS("pw0", 64) pw1 = BVS("pw1", 64)
fake_chunk0 = 0xFFFFC93C buffer0 = 0xABCC8A4 fake_chunk1 = 0xFFFFC94C buffer1 = 0xABCC8AC state.memory.store(buffer0, fake_chunk0, endness=p.arch.memory_endness) state.memory.store(buffer1, fake_chunk1, endness=p.arch.memory_endness)
state.memory.store(fake_chunk0, pw0) state.memory.store(fake_chunk1, pw1)
simgr = p.factory.simgr(state)
def find(simgr): output = simgr.posix.dumps(1) return b"Good Job." in output
def avoid(simgr): output = simgr.posix.dumps(1) return b"Try again." in output
simgr.explore(find=find, avoid=avoid)
if simgr.found: sol = simgr.found[0] flag1 = sol.solver.eval(pw0, cast_to=bytes).decode() flag2 = sol.solver.eval(pw1, cast_to=bytes).decode() print(flag1, flag2) else: print("qq")
|
我們造了兩個任意的 fake chunk 指定給 buffer,去模仿 malloc 的行為,其他的基本上都一樣 XD。
Result:
1 2 3
| └─$ ./06_angr_symbolic_dynamic_memory Enter the password: UBDKLMBV UNOERNYS Good Job.
|