0%

Angr学习

Angr学习

听闻Angr好久了,自己愣是没尝试过,这次网鼎杯有道vm虚拟机题目, 本来是手动盘的, 听说angr一把梭,故借此机会学习下angr

angr我觉得比较重要的有三个点

  1. 起始找寻位置
  2. 需要到达的路径
  3. 避免走的路径

网鼎 vm

起始找寻位置,我们可以选main, 也可以选特定验证函数, 但是需要注意的是, 数据的找寻

需要到达的路径为: success, flag这种成功的路径

避免走的路径便为失败路径

所以我们需要在ida找着三条路.

起初我选了vm_operate这个函数作为起始找寻位置,但是没有成功, 后面我选了main函数

需要到达的路径便为输出flag处

避免走的路径则是exit这种

最后执行即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python
# coding=utf-8
import angr

p = angr.Project('./signal.exe')
good = (0x0040179E)
bad = (0x004016E6)

start = 0x00401760

state = p.factory.blank_state(addr=start)
simgr = p.factory.simulation_manager(state)
simgr.explore(find=good, avoid=bad)
result = simgr.found[0]

for i in range(3):
print (result.posix.dumps(i))

不用一会就拿到flag了

757515121f3d478

angr-ctf-0

学习angr的基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import angr
import sys
binary = './angr_0'
good = 0x401329

p = angr.Project(binary)
state = p.factory.entry_state()
simulation = p.factory.simgr(state)
simulation.explore(find=good)
if simulation.found:
solution_state = simulation.found[0]
for i in range(3):
print (solution_state.posix.dumps(i))
else:
raise Exception("Could not find the solution")

angr-ctf-1

这道题需要找到avoid, 这里有个小技巧,就是跑进avoid里去选

image-20200519083900641

不然外部有多个avoid的话, 你要写很多个avoid

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import angr
import sys
binary = './angr_1'

good = (0x4012D0)
bad = (0x40127B)

p = angr.Project(binary)
state = p.factory.entry_state()
simulation = p.factory.simgr(state)
simulation.explore(find=good, avoid=bad)
if simulation.found:
solution_state = simulation.found[0]
for i in range(3):
print (solution_state.posix.dumps(i))
else:
raise Exception("Could not find the solution")

angr-ctf-2

该节学习angr的found_condition, 也就是说条件可以为一个函数,而不一定非得是一个地址, 这里自己写good跟bad函数, 然后让其通过判断, 还记得文件描述符吗

0 代表标准输入

1 代表标准输出

所以state.posix.dumps(1)才是输出,我们要输出包含good job

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import angr
import sys
binary = './angr_2'

good = (0x401245,0x4013C7)
bad = (0x4013B0)

def is_good(state):
return b'Good Job' in state.posix.dumps(1)
def is_bad(state):
return b'Try again' in state.posix.dumps(1)

p = angr.Project(binary)
state = p.factory.entry_state()
simulation = p.factory.simgr(state)
simulation.explore(find=is_good, avoid=is_bad)
if simulation.found:
solution_state = simulation.found[0]
for i in range(3):
print (solution_state.posix.dumps(i))
else:
raise Exception("Could not find the solution")

angr-ctf-3

这道题由于angr不能处理scanf多参数问题, 这里需要自己设置寄存器的值,同时设置输出形式

这道题有坑, 不能用函数形式的判断, 我用函数形式拿不到结果,用地址可以跑出来

同时因为我们没有用scanf,所以需要用solver求解

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
import angr
import sys
import claripy

binary = './angr_3'
start = 0x4015BD
good = (0x401621)
bad = (0x40160B)

def is_good(state):
print(state.posix.dumps(1))
return b'Good Job' in state.posix.dumps(sys.stdout.fileno())
def is_bad(state):
print(state.posix.dumps(1))
return b'Try again' in state.posix.dumps(sys.stdout.fileno())

p = angr.Project(binary)
state = p.factory.blank_state(addr=start)
bits = 32
password0 = claripy.BVS('password0', bits)
password1 = claripy.BVS('password1', bits)
password2 = claripy.BVS('password2', bits)
state.regs.eax = password0
state.regs.ebx = password1
state.regs.edx = password2


simulation = p.factory.simgr(state)
simulation.explore(find=good, avoid=bad)
if simulation.found:
solution_state = simulation.found[0]
solution0 = solution_state.se.eval(password0)
solution1 = solution_state.se.eval(password1)
solution2 = solution_state.se.eval(password2)
solution = ' '.join(map('{:x}'.format, [ solution0, solution1, solution2]))
print(solution)
else:
raise Exception("Could not find the solution")

angr-ctf-4

这道题修复栈就可以了, 我们知道常规函数调用通常是

push ebp

mov ebp,esp

sub esp, 0x2333

所以我们伪造一个栈给他, 然后再将参数传递

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
import angr
import sys
import claripy

binary = './angr_4'
start = 0x4013FB
good = (0x401447)
bad = (0x401433)

def is_good(state):
print(state.posix.dumps(1))
return b'Good Job' in state.posix.dumps(sys.stdout.fileno())
def is_bad(state):
print(state.posix.dumps(1))
return b'Try again' in state.posix.dumps(sys.stdout.fileno())

p = angr.Project(binary)
state = p.factory.blank_state(addr=start)
state.stack_push(state.regs.ebp)
state.regs.ebp = state.regs.esp
state.regs.esp -= 0x8

bits = 32
password0 = claripy.BVS('password0', bits)
password1 = claripy.BVS('password1', bits)
state.stack_push(password0)
state.stack_push(password1)


simulation = p.factory.simgr(state)
simulation.explore(find=good, avoid=bad)
if simulation.found:
solution_state = simulation.found[0]
solution0 = solution_state.se.eval(password0)
solution1 = solution_state.se.eval(password1)
solution = ' '.join(map('{:}'.format, [ solution0, solution1]))
print(solution)
else:
raise Exception("Could not find the solution")

angr-ctf-5

本文作者:NoOne
本文地址https://noonegroup.xyz/posts/4c8e6fd4/
版权声明:转载请注明出处!