二进制插桩
所谓插桩,其实就是在二进制程序指定位置(指令,函数)插入监控代码,类似hook,静态二进制插桩(Static Binary Instrumentation,SBI,反汇编,会修改磁盘文件)和动态二进制插桩(Dynamic Binary Instrumentation, DBI,对动态指令流进行修改,慢4倍)。常用框架有Intel Pin或者valgrind。(虚拟机对指令流进行修改)
DTA
动态污点分析(Dynamic Taint Analysis,DTA)也称为数据流追踪(Data Flow Tracking,DFT)、污点追踪(taint tracking) 或污点分析(taint analysis) , DTA通常在动态二进制插桩平台(如 Intel Pin)的基础上实现
过程
攻击数据(污点)从网络、磁盘的系统调用或指令进入内存(污点源),传播开(移动,拷贝。计算),到达攻击点(污点槽),被插桩代码(回调函数)检测,组织攻击
例子:
'./virus_code'-->recvfrom-->exec_cmd-->execve
'./virus_code'-->recvfrom(插桩post标记污点)-->exec_cmd-->(插桩pre检测污点)execve
DBI&SBI原理
静态二进制插桩:
- 相对较快(10%至2倍)
- 独立的二进制程序
- 需要明确指定要插桩的库
- 不支持动态生成的代码
- 对整个执行过程插桩
- 容易出现反汇编错误
- 需要重写二进制程序且容易出错
- 需要符号信息来减少错误
动态二进制插桩:
- 相对较慢(4倍或更多)
- 依赖DBI库和工具
- 不需要指定要插桩的库
- 可处理动态生成的代码
- 可动态附加和分离
- 不需要反汇编
- 不需要修改二进制程序
- 不需要符号信息
SBI插桩方法
- jmp方法,占5字节
直接写入jmp 会占用后面的指令 容易破坏多条指令
jmp过去 然后恢复再jmp回来 (类似HOOK) - int3 指令会生成一个软中断,用户空间的程序(如SBI库或调试器)能过通过操作系统提供的SIGTRAP信号(在linux上)捕获该中断,int3 的关键在于他只有1字节,可以随便破坏,都只会破坏一条指令,不用担心或破坏多条 操作码是0xcc。 从SBI的角度来看,使用int3 对指令进行插桩,只需用0xcc 覆盖该指令的第一字节。当SIGTRAP信号产生时,可以使用Linux操作系统的 ptrace API 找出中断发生的地址,从而获取插桩点地址没然后根据插桩点位置调用响应的插桩代码
int 3 这样的软中断很慢,会导致插桩后的应用程序的运行开销过大。此外,int3 方法与正在将int3 作为断点调试的程序不兼容 - 跳板方法(trampoline)
不会对原始代码进行插桩。创建一个原始代码的副本并只对这个副本进行插桩,该方法不会破坏任何代码或数据引用,因为其任然指向原始的、未更改的位置。为了确保二进制程序运行插桩代码而不是原始代码,跳板方法使用 jmp 指令,即跳转指令,将原始代码重定向到插桩后的副本。每当有调用或跳转指令将控制流转移到原始代码中时,该位置的跳板将立即跳转到相应的插桩代码。
DBI 系统的架构
DBI 系统的架构
DBI计算程序执行了多少基本块(BBL,basic block,是一个单入口单出口的代码段。同样,一个 BBL 内部可能开始一个新的 BBL)。实现方案为使用 DBI 引擎的API 对每个基本块的最后一条指令进行插桩,插入回调对基本块递增计数。(主要就是这个虚拟机)
PIN
Pin读取和实时编译代码的粒度为踪迹(trace)。踪迹是一种类似基本块的抽象方式,与常规的基本块不同,其只能在顶部进入,但可能包含多个出口。 Pin 定义踪迹为直线指令序列,该序列在遇到无条件控制流转移(call, ret)、达到预定义的最大长度或最大条件控制流指令数时结束。 Pin 总是以踪迹粒度实时编译代码,但它支持在多种粒度上插桩代码,包括指令、基本块、踪迹、函数及映像
DTA分析
污染源、污点槽及污点传播
污点源是指你选择追踪的数据所在的程序的位置。系统调用、函数入口点或单条指令都可作为污点源,recv和recvfrom 系统调用就是污点源
污点槽是指进行检查的程序位置,以确定这些位置是否会受到污点数据的影响,用回调函数插桩间接调用、间接跳转及返回指令,以检查这些指令的目标地址是否收到污点数据的影响,这些插桩过的指令就是污点槽。DTA库提供用于检查寄存器或内存位置是否被污染的函数,当污点槽被检测出污染的时候,程序应该触发一些响应机制
污点传播:
污点信息的存储:影子内存
为了存储寄存器或内存的污点位置和污点颜色等信息,DTA引擎维护专用的影子内存(shadow memory) 影子内存是由DTA系统分配的虚拟内存区域,用于追踪其余内存的污点状态。通常,DTA系统还在内存中分配一个特殊的结构,用于追踪CPU寄存器的污点信息