angr原理与实践(一)

您所在的位置:网站首页 整数溢出漏洞原理与利用 angr原理与实践(一)

angr原理与实践(一)

2024-07-13 19:28| 来源: 网络整理| 查看: 265

1本文系原创,转载请说明出处

关注微信公众号 信安科研人,获取更多的原创安全资讯

网上已经有很多介绍angr的官方文档的博客,但是怎么去用angr做一次有意义且成就感满满的分析的教程很少,目前比较常见的就是CTF中的应用,很少有从二进制程序分析技术角度介绍。

同时,也没有几篇文章介绍angr对应的论文,这篇论文很棒很经典。

因此,本博客从理论与实践两个方面介绍angr,以求让让自己更熟练掌握这个库是怎么用的,并应用到自己的工作中。

目录

一 angr简介

        angr是加州大学圣巴巴拉分校Giovanni Vigna大佬领衔的安全实验室的杰作,对应的论文发表在2016年的网络安全顶会IEEE S&P上,原论文链接在这

二 研究背景

        在这篇文章出来之前,安全界对程序进行漏洞分析的技术存在以下两种问题:

(1)研究的重复工作太多。每一个安全分析研究工作都要重新实现并调用一些以前的技术,浪费时间。

(2)其次,由于复制这些系统所需的工作量不可接受,复制其他人的结果变得不切实际。结果,单个二进制分析技术相对于其他技术的适用性变得模糊不清。再加上现代操作系统固有的复杂性,很难建立一个共同的比较基础。

批注:可以看出来,发表在CCF A上的文章所解决的问题往往是能够推动整个领域前进的问题,或者是解决一个领域内的巨大阻碍。同时,可以看到,真正的科研,往往是问题驱动,就是说解决一个问题而去做科研,往往是能够做出比为了科研而去解决问题更多的成功。

        因此,angr的实现的意义来了:

        大佬们创建了angr以解决这些技术共用性的问题,集成了众多文献中最先进的二进制分析技术。这样做的目的是通过以一种可访问、开放和可用的方式实施当前研究工作中的有效技术,使该领域系统化,并鼓励开发下一代二进制分析技术,以便能够轻松地相互比较。

        angr 使用静态和动态分析技术为多种类型的分析提供构建分析块,以便可以轻松实现所提出的研究方法并比较这些方法之间的有效性。此外,这些构建的分析块的组合能够利用它们的不同的组合优势。

        angr做出的三个贡献:

1) 在一个单一、连贯的框架中再现了攻击性二进制分析中的许多现有方法,以了解当前攻击性二进制分析技术的相对有效性。

2) 展示了将各种二进制分析技术结合起来并大规模应用的困难(以及解决这些困难的方法)。

3) 将angr开源,以供后代研究二进制代码分析之用。

三 背景知识 3.1 漏洞挖掘的静态分析技术

        静态技术在不执行程序的情况下对程序进行推理。通常,程序会被抽象表示。例如,诸如存储器布局或甚至所采用的执行路径之类的程序构造也可以被抽象表示。

        这篇文章将静态分析分为两种样式:

        (1)将程序属性建模成图

        (2)对程序数据本身进行建模的范式

        静态分析的两个缺点:

        (1)首先,结果不可重复:静态分析的检测必须手动验证,因为无法恢复有关如何触发检测到的漏洞的信息。

        (2)其次,这些分析往往在更简单的数据域上操作,降低了对语义的洞察。简言之,分析过于近似:虽然通常可以权威性地推理某些程序属性(例如漏洞)的缺失,但在就漏洞是否存在而证明时,静态分析的误报率很高。

技术一 CFG图的恢复

        控制流图 (CFG) 的恢复是几乎所有用于漏洞发现的静态技术的先决条件,其中图节点是基本的指令块,边缘是指令块之间可能的控制流传输。

        主流的CFG图的生成方法为递归算法,例如,从基本块BA开始,分解并分析BA基本快,识别可能的出口点BC、BD,那么就将BC、BD接到BA上,然后从BC、BD递归地重复分析,直到识别不出新的出口点。

        CFG控制流恢复有一个到目前为止都存在的挑战点:指令的间接跳转。 与直接跳转不同,在直接跳转中,目标被编码到指令本身中,因此很容易解析,而间接跳转的目标可以基于许多因素而变化,如链接库。

具体来说,间接跳转分为几类:

计算跳转。如跳转表,跳转表中的索引地址需要依据当时运行的寄存器或者内存的值来确定。上下文敏感。间接跳转可能取决于应用程序的上下文。常见的例子是标准C库中的qsort()——该函数接受一个回调,用于比较传入的值。因此,qsort()中基本块的一些跳转目标取决于其调用方,因为调用方提供回调函数。对象敏感(object-sensitive)。上下文敏感的一种特殊情况是对象敏感。在面向对象的语言中,对象多态性需要使用虚函数,通常实现为在运行时查询的函数指针的虚表,以确定跳转目标。因此,跳转目标取决于其调用方传递给函数的对象的类型。

        angr对如上的CFG图恢复工作的难点一个个攻克,并定义了CFG恢复技术的两个属性:

(1)可靠性。如果在生成的图中表示所有潜在控制流传输的集合,则认定这个CFG图恢复技术是合理的。

(2)完整性。指CFG图恢复成一个其中所有边都表示实际可能的控制流传输的CFG图。

技术二 基于流模型的漏洞检测

        通过分析程序属性图可以发现程序中的一些漏洞。程序属性图(例如,控制流图、数据流图和控制依赖图)可用于识别软件中的漏洞。最初应用于源代码的相关技术已经扩展到二进制程序。这些技术依赖于构建漏洞的模型(由控制流或数据依赖图中的一组节点表示),并识别该模型是否在应用程序中的出现,这样的技术倾向于已知漏洞的模型构建。

技术三 基于数据建模的漏洞检测

        一种代表方法:Ø值集分析(Value-Set Analysis, VSA)。VSA尝试识别程序中任何给定点的程序状态(即内存和寄存器中的值),这可以用来解决间接跳转的可能目标,或内存写入操作的可能目标识别问题。虽然这些近似值缺乏准确性,但它们是比较可靠的。也就是说,它们可能过近似,但决不可能能欠近似。

        例如:使用值集分析,通过分析内存读写的近似访问模式,可以在二进制文件中识别变量和缓冲区的位置。完成后,可以分析恢复的变量和缓冲区位置,以找到重叠的缓冲区。例如,这种重叠缓冲区可能是由缓冲区溢出漏洞引起的,因此每次检测都是一个潜在漏洞。

3.2 漏洞挖掘的动态分析技术

        该论文将动态分析技术分为两大类:

        具体执行和(动态)符号执行。

具体执行:

        具体执行的代表方案就是Fuzzing,也就是我们常说的模糊测试。这里不多介绍其概念,这里介绍几种现有的fuzzing的种类:

(1)基于覆盖率的fuzzing。基于代码覆盖率的模糊测试技术尝试产生的输入用例,使目标应用程序中执行的代码量最大化,因为执行的代码越多,执行易受攻击代码的可能性越高。经典的工具有AFL。

        基于覆盖的Fuzzing缺乏对目标应用程序的语义洞察。这意味着,虽然它能够检测到某段代码尚未执行,但它无法理解输入的哪些部分发生变异以导致代码被执行。

(2)基于污点分析的Fuzzing。这样的模糊测试工具分析应用程序如何处理输入,以了解输入的哪些部分在未来运行时需要修改。

(动态)符号执行:

        符号技术弥合了静态和动态分析之间的差距,并提供了一种解决方案来应对模糊测试的有限语义洞察力。动态符号执行是符号执行的一个子集,是一种动态技术,因为它在模拟环境中执行程序。

        然而,这种执行发生在符号变量的抽象域中。当这些系统模拟应用程序时,它们在整个程序执行过程中跟踪寄存器和内存的状态以及对这些变量的约束。每当到达条件分支时,执行分支并遵循两条路径,将分支条件保存为对采用分支的路径的约束,并将分支条件的逆作为对未采用分支的路径的约束。

四 angr的设计 4.1 设计目标 跨架构跨平台支持不同的分析范式可用性 4.2 子模块设计 中间语言表示。angr借鉴的是libVEX,目前支持ARM、MIPS、PPC和x86和amd64,libVEX项目的研究者目前正在对SPARC架构进行工作移植。二进制文件加载。angr的这个模块主要由CLE实行,CLE 是 CLE Loads Everything 的递归首字母缩写词。 CLE 对不同的二进制格式进行抽象,以处理加载给定的二进制文件和它所依赖的任何库、解析动态符号、执行重定位以及正确初始化程序状态。CLE 通过提供众多表示二进制对象(即应用程序二进制文件、POSIX .so 或 Windows .dll)的基类、这些对象中的段和节以及表示内部位置的符号,为二进制加载程序提供了一个可扩展的接口。CLE 使用文件格式解析库(特别是用于 Linux 二进制文件的 elftools 和用于 Windows 二进制文件的 pefile)来解析对象本身,然后执行必要的重定位以公开已加载应用程序的内存映像。程序状态表示与修改。angr这部分使用的是SimuVEX模块。SimuVEX 提供了通过 VEX 表示的代码块处理输入状态的能力,并生成输出状态。SimuVEX 模块负责表示程序状态(即寄存器和内存中值的快照、打开的文件等)。 在 SimuVEX 术语中名为 SimState 的状态被实现为状态插件的集合,这些插件由用户指定的状态选项控制或在状态创建时进行分析。 目前,存在以下状态插件: 寄存器符号内存(以帮助符号执行)抽象内存POSIX日志记录调试求解器架构(用来分析架构的特定信息)数据模型。存储在SimState的寄存器和存储器中的值由另一个模块Claripy提供的抽象表示。这种模块化设计允许 Claripy 以强大的方式组合各种数据域提供的功能,并将其提供给 angr 的其余部分使用。Claripy 将所有值抽象为表达式的内部表示,该表达式跟踪使用它的所有操作。具体来说,Claripy 提供支持具体域(整数和浮点数)、符号域(由 Z3 SMT 求解器 提供的符号整数和符号浮点数)和值集抽象域的后端用于值集分析。例如,将后端提供的构造(例如,Z3 后端提供的符号表达式 x+1)解释为 Python 原语(例如作为约束求解结果的 x+1 的可能整数解)由前端提供。 前端增加了具有不同复杂性的附加功能的后端。Claripy 目前提供了几个前端: 全前端(FullFrontend)。 此前端向用户公开符号求解、跟踪约束、使用 Z3 后端求解并缓存结果。复合前端(CompositeFrontend)。 正如 KLEE 和 Mayhem等人工作中所建议的,将约束拆分为独立的集合可以减少求解器的负载。轻量级前端(LightFrontend)。此前端不支持约束跟踪,仅使用 VSA (值集分析)后端来解释 VSA 域中的表达式。替换前端(ReplacementFrontend)。  ReplacementFrontend 扩展 LightFrontend 以添加对 VSA 值约束的支持。 当引入约束(即 x+1 < 10)时,ReplacementFrontend 会对其进行分析以识别所涉及变量的界限(即 0


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3