技术概览:动态污点分析技术是旨在通过对运行时间内重写二进制代码的表现进行分析,从而检测和过滤攻击行为并以此提高系统安全性。通过试验表明,动态污点分析技术能够检测出绝大多数的软件漏洞,如果使用混合检测器的话,使用该技术带来的性能开销还将进一步地减小。除此之外,作者还提出了一种基于语义分析的签名生成方法,使用这种签名算法会使得污点分析的可靠性和准确性进一步提高,从而更好地检测和标记出安全漏洞,避免造成重大损失。
产生背景:为了现实网络中成千上万台计算机免受恶意攻击,我们需要有一套自动化的机制能够自动发现和识别计算机系统中存在的漏洞,避免这些漏洞被攻击者利用,从而造成严重的后果。显然,若只是靠人工识别的话是远远不够的,因为像蠕虫这样的攻击可以在任何时刻、任何地点发起并且在短时间内迅速扩散。同时这种技术应该是便于实施并且具有一定的预见性(不能等到攻击已经发生之后再来预警),所以动态污点分析技术应运而生。
前人研究:在此之前,对于攻击的自动检测主要可以分为两大类:粗粒度检测(Coarse-Grained Detectors)和细粒度检测(Fine-Grained Detectors)。粗粒度检测一般是基于扫描或是异常的操作行为,这就往往会导致一些检测误报,并且不能提供漏洞信息以供修补。而细粒度检测则是检查程序的脆弱性,它检测那些要求获取源代码或是重新编译的程序从而发现潜在的漏洞。然而在商用软件当中,源代码和重编译往往都是不可能获取的,因此需要一种新的检测方式,以满足这一大类程序的安全需求。除此之外,对于一个漏洞检测系统来说,仅仅检测出攻击是远远不够的,系统还应该有一个“响应”的机制防止危害的进一步扩大。研究证明,基于内容匹配的过滤器比基于源地址的过滤器有更好的效果,自然而然地就需要有一个对内容的“标记”算法帮助过滤器更好的筛除恶意数据包。
方案亮点:将从不信任网络来源的数据标记为污点,随着程序的执行持续追踪污点数据的流动情况,当污点数据有出现高危的使用方式时则可能即将发生攻击行为。比如可以用来检测重写(Overwrite)攻击(我觉得是不是类似于我们上课所讲的overflow?):例如返回地址被修改、函数指针被改写等等,并且自动生成日志报告系统可能存在的漏洞。大多数的漏洞检测方法并不能识别此类攻击。除此之外,动态污点分析具有下面几个优势:一、不需要源代码或是特殊的二进制编码;二、没有显著的误报性;三、提供针对攻击漏洞的输入纠正;四、使用混杂模式下的低性能开销(为什么引入了感觉很复杂的数据追踪机制带来的额外开销却很小?);五、基于签名的自动敏感数据分析等。
技术实现(污点校验):动态污点检测技术是对异常操作的检测:那些企图改变程序正常执行的操作,通常来说攻击者总是希望能够将从可信来源的数据篡改为自己的设计数据(Shellcode就是这样的)。在动态污点分析中把来自不受信任的节点或是数学派生出的数据都标记为污点,监视器会在程序运行的过程中持续监控污点污染的其他内存数据和高危操作(比如使用被污染的数据作为跳转地址)。与之前试图在内存中检测是否出现了覆盖重写的方法相比较,动态污点分析是伴随着程序的运行同步进行的,因此响应速度更快(这也回答了为什么污点分析的方法更快,可以检测出更多类型的漏洞)。要实现污点校验需要两个组件,在X86中使用开源的Valgrind命令对运行中的程序进行插桩操作,在Windows中可以用DynamoRIO命令二进制插桩。污点校验有三个关键部件:污点生成器(Taint Seed)、污点追踪器(Taint Tracker)、污点判决器(Taint Assert)。污点生成器会把所有不可信来源的数据都打上标记,即污点,作为可能的威胁来源。 污点追踪器主要关注的是对于污点操作的两类指令:数据移动操作和算计操作。默认的设计是源节点被污染后接收节点的所有数据也是被污染的,忽略算数操作对处理器状态标识的影响等等。污点判决器会按照其策略判定污点数据的使用方式是否是合法的。默认的策略是检测对于格式串的攻击:比如跳转地址、函数指针、函数指针偏置量等。一旦检测到污染数据被错误利用,就会激活漏洞分析器对可能的攻击进行分析。
漏洞分析器是当污点数据的使用违反了它的安全策略时自动标记漏洞。因此它能为漏洞产生的分析工作提供有用的信息。这些信息可以用来标记新的脆弱点(Vulnerable)和漏洞指纹(Signatures)。
技术改进一:基于污点校验的全混合漏洞检测
改进方法主要是对性能负载和精确性的优化。理想情况下站点能够实时保护它的所有服务,但是在实际中无法实现,因为这样会导致性能过载。更理想的情况是污点校验程序能够比目标程序执行的快的多(这样就会留下更多的时间用于污点测试的响应,同时使用户感受不到检验程序的存在),然后发现污点校验总是会引起性能惩罚,所以作者又设计了一种低开销的混合漏洞检测器。(要降低开销多半要用到概率)作者设计了一个两级的漏洞检测器,第一级是将进入系统的流量进行一次分类,把最近一段时间内使用最后的流量选到流量选择器中,选择器根据不同的安全标准把选择后的数据流送往第二级,完成第一次分流。接下来数据路又被分为两支,其中一支是把所有的流量都以P的概率被选中,这样就保证了最坏的情况下P次也能检测到异常数据,另一支则是根据基于网络和主机的入侵检测器提供的信息对一定数量的可疑流进行污点分析,提高检测成功的概率。我们发现这个设计基于一定数学原理,即优先对可能性大数据流进行处理,而不是盲目的、不加选择的对所有数据处理,有一个预处理的机制在里面。这也回答了我上面的疑问,即为什么使用了动态污点分析以后没有引入过量的开销。同时我们也发现了,到目前为止这个设计还有一个漏洞。那就是系统还有一定的漏检概率,对于漏检的这一部分还没有作处理。所以作者在后面有补上了一段:一旦系统发现服务器已经被攻击(这应该算是事后处理了),那么这个服务器将会被立刻隔离,以最小化的减少损失。
技术改进二:自动签名生成
通过上面部分的系统设计,分析器成功的把可疑的数据分离了出来,接下来当务之急就是把这一份的数据流打上一个标签,也就是一个指纹,能够让我们的过滤器能及时的识别出恶意的信息流,避免漏洞被继续利用,为此就需要有一种签名生成算法,能自动对污点信息进行签名标记。
之前的自动签名生成技术都是通过对内容进行提取,这种方式是试图找到一种发动攻击时的内容模式,利用对负载内容的模式识别实现消息签名认证。这种方式的缺点也是显而易见的:需要观察的数据太多,并且准确程度无法得到保证。因此本文的作者提出了一种新的签名生成方式:基于负载内容的语义识别实现消息认证。这种语义识别的签名算法不仅能够在更早的阶段识别出攻击数据,同时还能分辨出已经生效的攻击代码和还未激活的攻击代码。除此之外根据攻击代码的攻击模式研究发现,攻击者总是需要在复写地址当中写入一些固定的值用来操作他的真实意图,通过动态污点分析生成签名之后,就能够找到这些值所在的区域从而发现攻击者的真实意图。
当然了,基于语义分析的签名算法未来还有更多的用途。一是,将语义分析应用到过滤器(Filter)的升级改进中去,它可以帮助过滤器去追踪每一比特请求信息,以及他们的作用。在传输过程中存在一种过滤器比特(Filter byte)的信息,它既没有影响系统,也不会引起系统响应,同时也不会触发蠕虫代码的执行,它就像是一种毫无意义的数据。但是攻击者则可以利用这种数据去干扰和降低系统的运行。使用语义分析的签名技术以后就能帮助过滤器理解什么样的操作是“有意义的”,什么样的操作是“无效的”,从而提高过滤器的效率。二是任何一比特的关键信息在没有被恶意程序利用之前,对恶意程序来说,它是必不可少的(这里很绕)。因此如果我们能在被恶意利用之前给这些“关键信息”打上“标签”,就能帮助我们很好的追踪污点数据的流向和目的。
总结:为了在蠕虫病毒造成大量主机瘫痪之前,我们需要一种自动的防御和识别机制。这篇论文就提出了一种动态污点分析的技术,能够在不需要源代码或是特殊解析程序的帮助下对商用软件漏洞进行自动的检测和识别。在实验过程中,这种方法没有显著的误报,同时通过污点检测还能提供攻击的具体信息,能够提供造成漏洞泄露的输入以及这些输入是如何导致攻击的(通过插桩的方式),并且还能知道重写覆盖的真实值是多少。
最后文章还提到了一种基于语义分析的签名算法,这种签名算法能够强化签名的准确性同时验证已经生成的签名质量。
原文地址:Google学术——《dynamic taint analysis for automatic detection》