全系统动态污点分析-概要
全系统污点分析需要完成以下几点:
1. 标记某个来自I/O device的数据为污点
2. 可以监视全系统的执行,知道哪一块代码在传播了污点数据。要实现这一点,需要基于qemu.
Qemu的动态翻译系统,把目标的CPU指令翻译成host的CPU指令,翻译好的指令会被存储在一个cache中,以提高效率。
目前,QEMU有两种模式:emulated mode (禁用KQEMU)和virtualized mode (启用KQEMU)
我们对qemu做了修改,使得它在运行时可以在两种模式之间切换:当需要执行分析指令时,跑emulated mode,否则跑virtualized mode.
我们使用一个影子内存来映射内存的每个字节和cpu寄存器的状态。
每个被taint的字节,都关联一个数据结构,这个数据结构存储它的taint source和一些其他备用信息。
影子内存以一个类似page-table的结构存储,这使得在实际应用中,影子内存并不需要占用太大空间。
在当前的设计和实现中,我们把键盘、网卡和硬盘的数据作为污点。污点源的粒度也可以更细一点,比如我们可以选择一个函数的输出、内核的某个数据结构。
选择键盘作为污点源很简单,只需要监测虚拟键盘就行,我们可以检测到keylogger的存在。
选择网络作为污点源有些麻烦,对于ICMP/TCP/UDP要有不同的策略。
选择硬盘作为污点源,我们可以以sector为单位。
污点源确定之后,我们需要跟踪每条操作污点的指令,进一步确认指令产生的结果是否被污染了。
在QEMU中,目标CPU的指令被分为一些微操作,这些微操作分为3类:数据转移操作、算数操作、什么都不做的操作。
我们对数据转移操作和算术操作进行instrument.
对数数据转移操作来说,只有源点被污染,目标点才会被污染。
对于算数操作来说,任何一个操作数被污染,操作结果就被污染。
3.1 Constant function
有些指令总是产生相同的结果,比如“xor eax eax”.
这种类型的指令,如果输入是tainted,输出就不是tainted.
3.2 Table lookup
有时候一个tainted的值被用来当做一个非tainted的内存区域的指针。
考虑到这种情形,我们制定规则如下:
如果内存的index是tainted,结果也是tainted.
3.3 Propagating to I/O devices
taints有时候回传播到磁盘或者网卡上。
传播到磁盘上,可能会导致一个tainted page被交换,或写入到文件。
我们通过一个数据结构,保存tainted data的文件位置,如果这些数据重新被读入内存,内存的相应数据被标记为tainted。
当产生taint graph时,我们只对被写入文件的tainted data感兴趣,但是由于某些内存数据作为虚拟内存也会经常被写入文件,我们需要能够区分这两种情况。
4.1 Resolving process and module information.
我们观察到某条指令访问了某个数据。进一步我们需要知道这条指令是哪个进程的。
为此我们需要在内存地址和操作系统模块信息之间建立一个映射。我们通过一个内核模块收集和更新内存地址和操作系统模块信息之间的映射。当一个进程创建或删除时,会调用内核模块的回调函数,当一个进程的模块载入时,也会调用内核模块的回调函数。
4.2 Resolving filesystem and network information.
当tainted data被写入硬盘或网络时,我们希望知道它被写入到了那个文件,我们需要建立硬盘block和文件路径的映射。
当tainted data被发送到网络时,我们希望知道它是通过那个连接发送的,我们只需要检查下报文的头部信息就可以知道了。
- 上一篇: ASP.NET Cookie的存储与读取
- 下一篇: 在jsp中使用for循环