Angr_CTF Writeups 2

kazma 成大資安社 創辦人/社長

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.
  • Title: Angr_CTF Writeups 2
  • Author: kazma
  • Created at : 2024-05-04 17:15:08
  • Updated at : 2024-05-05 00:51:42
  • Link: https://kazma.tw/2024/05/04/Angr-CTF-Writeups-2/
  • License: This work is licensed under CC BY-NC-SA 4.0.
 Comments