What:
pyrebox是一个python可编程的逆向工程沙箱
Why:为什么使用pyrebox
- 使用简单,提供了一套命令来检查或者修改正在运行的虚拟机的状态
- 使用QEMU支持多系统,集成了volatility
- 用pyrebox调试系统(或特定进程)相当隐蔽,和传统的调试器完全不一样。传统调试器会存在在被调试的系统中,升职修改调试进程的内存来插入断点;而pyrebox完全留在被调试的系统之外,而且不需要安装任何驱动或者组件到被调试虚拟机中。
How:
pyrebox提供了两个主要的用户界面,一方面是IPython的shell界面(sh进入shell),另一方面是编写为系统上某些特定事件注册回调函数的python脚本。
Ipython Shell
- list_command:列出所有pyrebox提供的命令
- list_vol_command:虚拟机执行的时候可以运行任何volatility的插件,这个命令列出所有安装在pyrebox的volatility/path下的volatility的插件命令
- 执行volatility的插件:vol 命令
- 可以在脚本中自定义自己的命令
- 需要创建一个以"do_"开头的函数即可
- 如果需要比命令更具体、表达内容跟多的可以直接在shell中编写python代码片段
- 先输入clear,就可以直接编写
- 如果需要API的详细描述,可以在shell中键入help(api)
脚本
pyrebox允许动态加载可以注册回调函数的脚本,这些函数在以下事件发生时被调用:
- 指令和/或基本块的执行
- 内存读/写
- 进程创建/停止
- 上下文转换
- TLB miss
- Translation Lookaside Buffer,转换检测缓冲区,它是一个内存管理单元,用于改进虚拟地址到物理地址转换速度的缓存
- TLB中的每一行都保存着由单个PTE(Page Table Entry,页表项)组成的块
- 如果没有TLB,则每次取数据都要两次访问内存,即查页表获得物理地址和取数据
- 如果TLB中刚好存放着所需的页表,就叫TLB命中(TLB Hit);否则就叫TLB失败(TLB miss)
- 网络连接和键盘事件
由于pyrebox是受DECAF的启发,所以pyrebox也支持很多DECAF支持的回调函数类型
脚本界面允许用户自定义命令,脚本只需要在一个特定原型后声明一个函数就可以创建一个新命令。这个特性允许在脚本引擎或shell上集成任何python库,只需要编写一个简单的包装器即可。
只要发生特定的事件或者满足某些条件时,脚本可以自动启动shell。所以,用户可以监视并记录事件,然后在当条件满足的时候,对start_shell()函数的调用就可以在这个特定的点暂停虚拟机并启动shell
一个简单脚本的例子,这个脚本注册了一个脚本加载进pyrebox后对于进程创建的回调函数,每当有新进程创建时,pyrebox会自动启动shell,该脚本还自定义了一个叫做my_command的自定义命令,每当在shell中输入custom my_command的时候就会调用:
#!/usr/bin/python
import sys
import api
from ipython_shell import start_shell
from api import CallbackManager
#Callback Manager
cm = None
#Printer
pyrebox_print = None
if __name__ == "__main__":
#这条消息会当脚本被载入内存时显示
print "[*] Loading python module %s" % (__file__)
def new_proc(pid, pgd, name):
'''
进程创建回调函数,接受三个参数:
pid:进程的pid,类型是int
pgd:进程的PGD,类型是int
name:进程名字,类型是str
'''
global pyrebox_print
global cm
# 打印消息
pyrebox_print("New process created! pid:%x, pgd:%x, name:%s" % (pid, pgd, name))
# 当进程创建的时候立马启动pyrebox
start_shell()
def initialize_callbacks(module_hdl, printer):
'''为这个模块初始化回调函数'''
global cm
global pyrebox_print
# 初始化打印函数
pyrebox_print = printer
pyrebox_print("[*] Initializing callbacks")
# 初始化回调函数管理器
cm = CallbackManager(module_hdl)
# 注册一个进程创建的回调函数
new_proc_cb = cm.add_callback(CallbackManager.CREATEPROC_CB, new_proc)
pyrebox_print("[*] Initialized callbacks")
def clean():
'''将所有东西清洁干净'''
global cm
print "[*] Cleaning module"
# 这个调用会注销所有的已存在的回调函数
cm.clean()
print "[*] Cleaned module"
def do_my_command(line):
'''自定义命令的简单描述和详细描述'''
global pyrebox_print
global cm
# 要执行的命令功能
pyrebox_print("This is a custom command")
最后,考虑到python回调函数可能会有性能损失,尤其是对于像指令执行之类的频繁事件,可以改进的做法有创建触发器。触发器是本地代码插件(用C/C++)开发,可以在执行python回调函数之前动态插入任何运行的事件中。这样一来就可以限制调用python代码的事件数量,同样可以预编译本地代码中的值