mirror of
https://github.com/nganhkhoa/CTF-All-In-One.git
synced 2024-12-24 19:21:15 +07:00
update 5.3
This commit is contained in:
parent
228b9c9d7a
commit
3687865931
205
doc/5.3_angr.md
205
doc/5.3_angr.md
@ -2,6 +2,7 @@
|
||||
|
||||
- [安装](#安装)
|
||||
- [使用 angr](#使用-angr)
|
||||
- [基础功能](#基础功能)
|
||||
- [angr 在 CTF 中的运用](#angr-在-ctf-中的运用)
|
||||
- [参考资料](#参考资料)
|
||||
|
||||
@ -19,7 +20,7 @@ $ sudo apt install python-dev libffi-dev build-essential virtualenvwrapper
|
||||
|
||||
对于大多数 *nix系统,只需要 `mkvirtualenv angr && pip install angr` 安装就好了。
|
||||
|
||||
如果这样安装失败的话,那么你可以按照这样的顺序:
|
||||
如果这样安装失败的话,那么你可以按照下面的顺序从 angr 的官方仓库安装:
|
||||
```text
|
||||
1. claripy
|
||||
2. archinfo
|
||||
@ -27,9 +28,7 @@ $ sudo apt install python-dev libffi-dev build-essential virtualenvwrapper
|
||||
4. cle
|
||||
5. angr
|
||||
```
|
||||
从angr的官方仓库安装。
|
||||
|
||||
附安装方法:
|
||||
如:
|
||||
```shell
|
||||
$ git clone https://github.com/angr/claripy
|
||||
$ cd claripy
|
||||
@ -37,50 +36,168 @@ $ sudo pip install -r requirements.txt
|
||||
$ sudo python setup.py build
|
||||
$ sudo python setup.py install
|
||||
```
|
||||
其他几个库也是一样的。
|
||||
|
||||
其他几个 angr 官方库的安装也是如此。
|
||||
|
||||
#### 一些 `import angr` 可能出现的问题
|
||||
如果你在安装angr之后,进入python环境,在import之后有这样的报错:
|
||||
```python
|
||||
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
|
||||
[GCC 5.4.0 20160609] on linux2
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> import angr
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
File "angr/__init__.py", line 25, in <module>
|
||||
from .project import *
|
||||
File "angr/project.py", line 592, in <module>
|
||||
from .analyses.analysis import Analyses
|
||||
File "angr/analyses/__init__.py", line 22, in <module>
|
||||
from .reassembler import Reassembler
|
||||
File "angr/analyses/reassembler.py", line 9, in <module>
|
||||
import capstone
|
||||
File "/usr/local/lib/python2.7/dist-packages/capstone/__init__.py", line 6, in <module>
|
||||
from . import arm, arm64, mips, ppc, sparc, systemz, x86, xcore
|
||||
ImportError: cannot import name arm
|
||||
>>>
|
||||
```
|
||||
可以看到,是 capstone 出现了问题,解决方法是重新安装 angr:
|
||||
```shell
|
||||
$ sudo pip install -I --no-use-wheel capstone
|
||||
```
|
||||
|
||||
若是问题依然存在,那么请先卸载所有的 capstone:
|
||||
```shell
|
||||
$ sudo pip3 uninstall capstone
|
||||
$ sudo pip uninstall capstone
|
||||
```
|
||||
然后再从 pypi 源中获取最新版本安装:
|
||||
```shell
|
||||
$ wget https://pypi.python.org/packages/fd/33/d1fc2d01b85572b88c9b4c359f36f88f8c32f2f0b9ffb2d21cd41bad2257/capstone-3.0.5rc2-py2-none-manylinux1_x86_64.whl#md5=ecd7e1e39ea6dacf027c0cfe7eb1bf94
|
||||
$ sudo pip2 install capstone-3.0.5rc2-py2-none-manylinux1_x86_64.whl
|
||||
```
|
||||
其他问题可以到官方文档中查看。
|
||||
安装过程中可能会有一些奇怪的错误,可以到官方文档中查看。
|
||||
|
||||
|
||||
## 使用 angr
|
||||
#### 基础功能
|
||||
使用 angr 的第一步是新建一个工程,几乎所有的操作都是围绕这个工程展开的:
|
||||
```python
|
||||
>>> import angr
|
||||
>>> proj = angr.Project('/bin/true')
|
||||
WARNING | 2017-12-08 10:46:58,836 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000.
|
||||
```
|
||||
这样就得到了二进制文件的各种信息,如:
|
||||
```python
|
||||
>>> proj.filename
|
||||
'/bin/true'
|
||||
>>> proj.arch
|
||||
<Arch AMD64 (LE)>
|
||||
>>> hex(proj.entry)
|
||||
'0x4013b0'
|
||||
```
|
||||
|
||||
程序加载时会将二进制文件和共享库映射到虚拟地址中,CLE 模块就是用来处理这些东西的。
|
||||
```python
|
||||
>>> proj.loader
|
||||
<Loaded true, maps [0x400000:0x5008000]>
|
||||
```
|
||||
所有对象文件如下,其中二进制文件是 main object:
|
||||
```
|
||||
>>> proj.loader.all_objects
|
||||
[<ELF Object true, maps [0x400000:0x60721f]>, <ELF Object libc-2.26.so, maps [0x1000000:0x13b78cf]>, <ELF Object ld-2.26.so, maps [0x2000000:0x22260f7]>, <ELFTLSObject Object cle##tls, maps [0x3000000:0x300d010]>, <ExternObject Object cle##externs, maps [0x4000000:0x4008000]>, <KernelObject Object cle##kernel, maps [0x5000000:0x5008000]>]
|
||||
>>> proj.loader.main_object
|
||||
<ELF Object true, maps [0x400000:0x60721f]>
|
||||
>>> proj.loader.main_object.pic
|
||||
True
|
||||
```
|
||||
通常我们在创建工程时选择关闭 `auto_load_libs` 以避免 angr 加载共享库:
|
||||
```
|
||||
>>> p = angr.Project('/bin/true', auto_load_libs=False)
|
||||
WARNING | 2017-12-08 11:09:28,629 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000.
|
||||
>>> p.loader.all_objects
|
||||
[<ELF Object true, maps [0x400000:0x60721f]>, <ExternObject Object cle##externs, maps [0x1000000:0x1008000]>, <KernelObject Object cle##kernel, maps [0x2000000:0x2008000]>, <ELFTLSObject Object cle##tls, maps [0x3000000:0x300d010]>]
|
||||
```
|
||||
|
||||
`project.factory` 提供了很多类对二进制文件进行分析,它提供了几个方便的构造函数。
|
||||
|
||||
`project.factory.block()` 用于从给定地址解析一个 basic block:
|
||||
```python
|
||||
>>> block = proj.factory.block(proj.entry) # 从程序头开始解析一个 basic block
|
||||
>>> block
|
||||
<Block for 0x4013b0, 42 bytes>
|
||||
>>> block.pp() # pretty-print,即打印出反汇编代码
|
||||
0x4013b0: xor ebp, ebp
|
||||
0x4013b2: mov r9, rdx
|
||||
0x4013b5: pop rsi
|
||||
0x4013b6: mov rdx, rsp
|
||||
0x4013b9: and rsp, 0xfffffffffffffff0
|
||||
0x4013bd: push rax
|
||||
0x4013be: push rsp
|
||||
0x4013bf: lea r8, qword ptr [rip + 0x32ca]
|
||||
0x4013c6: lea rcx, qword ptr [rip + 0x3253]
|
||||
0x4013cd: lea rdi, qword ptr [rip - 0xe4]
|
||||
0x4013d4: call qword ptr [rip + 0x205b26]
|
||||
>>> block.instructions # 指令数量
|
||||
11
|
||||
>>> block.instruction_addrs # 指令地址
|
||||
[4199344L, 4199346L, 4199349L, 4199350L, 4199353L, 4199357L, 4199358L, 4199359L, 4199366L, 4199373L, 4199380L]
|
||||
```
|
||||
另外,还可以将 block 对象转换成其他形式:
|
||||
```python
|
||||
>>> block.capstone
|
||||
<CapstoneBlock for 0x4013b0>
|
||||
>>> block.capstone.pp()
|
||||
>>>
|
||||
>>> block.vex
|
||||
<pyvex.block.IRSB object at 0x7fe526b98670>
|
||||
>>> block.vex.pp()
|
||||
```
|
||||
|
||||
程序的执行需要初始化一个 `SimState` 对象:
|
||||
```python
|
||||
>>> state = proj.factory.entry_state()
|
||||
>>> state
|
||||
<SimState @ 0x4013b0>
|
||||
```
|
||||
该对象包含了程序的内存、寄存器、文件系统数据等:
|
||||
```python
|
||||
>>> state.regs.rip
|
||||
<BV64 0x4013b0>
|
||||
>>> state.regs.rsp
|
||||
<BV64 0x7fffffffffeff98>
|
||||
>>> state.regs.rdi
|
||||
<BV64 reg_48_0_64{UNINITIALIZED}> # 符号变量,它是符号执行的基础
|
||||
>>> state.mem[proj.entry].int.resolved
|
||||
<BV32 0x8949ed31>
|
||||
```
|
||||
这里的 BV,即 bitvectors,用于表示 angr 里的 CPU 数据。下面是 python int 和 bitvectors 之间的转换:
|
||||
```python
|
||||
>>> bv = state.solver.BVV(0x1234, 32)
|
||||
>>> bv
|
||||
<BV32 0x1234>
|
||||
>>> hex(state.solver.eval(bv))
|
||||
'0x1234'
|
||||
>>> bv = state.solver.BVV(0x1234, 64)
|
||||
>>> bv
|
||||
<BV64 0x1234>
|
||||
>>> hex(state.solver.eval(bv))
|
||||
'0x1234L'
|
||||
```
|
||||
使用 bitvectors 来设置寄存器和内存的值,当直接传入 python int 时,angr 会自动将其转换成 bitvectors:
|
||||
```python
|
||||
>>> state.regs.rsi = state.solver.BVV(3, 64)
|
||||
>>> state.regs.rsi
|
||||
<BV64 0x3>
|
||||
>>> state.mem[0x1000].long = 4
|
||||
>>> state.mem[0x1000].long.resolved # .resolved 获取 bitvectors
|
||||
<BV64 0x4>
|
||||
>>> state.mem[0x1000].long.concrete # .concrete 获得 python int
|
||||
4L
|
||||
```
|
||||
|
||||
初始化的 state 可以经过模拟执行得到一系列的 states,simulation 管理器的作用就是对这些 states 进行管理:
|
||||
```python
|
||||
>>> simgr = proj.factory.simulation_manager(state)
|
||||
>>> simgr
|
||||
<SimulationManager with 1 active>
|
||||
>>> simgr.active
|
||||
[<SimState @ 0x4013b0>]
|
||||
>>> simgr.step() # 模拟一个 basic block 的执行
|
||||
<SimulationManager with 1 active>
|
||||
>>> simgr.active # 模拟状态被更新
|
||||
[<SimState @ 0x1020e80>]
|
||||
>>> simgr.active[0].regs.rip # active[0] 是当前 state
|
||||
<BV64 0x404620>
|
||||
>>> state.regs.rip # 但原始的 state 没有变
|
||||
<BV64 0x4013b0>
|
||||
```
|
||||
|
||||
`project.analyses` 提供了大量函数用于程序分析。
|
||||
```python
|
||||
>>> cfg = p.analyses.CFGFast() # 得到 control-flow graph
|
||||
>>> cfg
|
||||
<CFGFast Analysis Result at 0x7f4626f15090>
|
||||
>>> cfg.graph
|
||||
<networkx.classes.digraph.DiGraph object at 0x7f462316ef90> # 详细内容请查看 networkx
|
||||
>>> len(cfg.graph.nodes())
|
||||
937
|
||||
>>> entry_node = cfg.get_any_node(proj.entry) # 得到给定地址的节点
|
||||
>>> entry_node
|
||||
<CFGNode 0x4013b0[42]>
|
||||
>>> len(list(cfg.graph.successors(entry_node)))
|
||||
2
|
||||
```
|
||||
如果要想画出图来,还需要安装 matplotlib,Tkinter 等。
|
||||
```python
|
||||
>>> import networkx as nx
|
||||
>>> import matplotlib.pyplot as plt
|
||||
>>> nx.draw(cfg.graph) # 画图
|
||||
>>> plt.show() # 显示
|
||||
>>> plt.savefig('temp.png') # 保存
|
||||
```
|
||||
|
||||
|
||||
## angr 在 CTF 中的运用
|
||||
|
@ -1,4 +1,4 @@
|
||||
# 第八章 附录篇
|
||||
# 第八章 附录
|
||||
|
||||
- [8.1 更多 Linux 工具](8.1_Linuxtools.md)
|
||||
- [8.2 更多 Windows 工具](8.2_wintools.md)
|
||||
|
Loading…
Reference in New Issue
Block a user