《0day》-1-基础知识

第 1 章 基础知识

1. 漏洞概述

1.3 漏洞挖掘、漏洞分析、漏洞利用

利用漏洞进行攻击可以大致分为漏洞挖掘、漏洞分析、漏洞利用三个步骤。这三部分所用
的技术有相同之处,比如都需要精通系统底层知识、逆向工程等;同时也有一定的差异。

漏洞挖掘

安全性漏洞往往不会对软件本身功能造成很大影响,很难被 QA 工程师和普通用户发现。

寻找漏洞的人并非全是攻击者。大型的软件企业也会雇用一些安全专家来测试自己产品中的漏洞,这种测试工作被称做 Penetration test (攻击测试),这些测试团队则被称做 Tiger team或者 Ethic hacker。

从技术角度讲,漏洞挖掘实际上是一种高级的测试(QA)。学术界一直热衷于使用静态分析的方法寻找源代码中的漏洞;而在工程界,不管是安全专家还是攻击者,普遍采用的漏洞挖掘方法是 Fuzz,这实际是一种“灰”盒测试。

我们会在第 3 篇的相关章节中进一步介绍漏洞挖掘与产品安全性测试方面的知识。

漏洞分析

当 fuzz 捕捉到软件中一个严重的异常时,当您想透过厂商公布的简单描述了解漏洞细节的
时候,您就需要具备一定的漏洞分析能力。一般情况下,我们需要调试二进制级别的程序。
在分析漏洞时,如果能够搜索到 POC(proof of concept)代码,就能重现漏洞被触发的现
场。这时可以使用调试器观察漏洞的细节,或者利用一些工具(如 Paimei)更方便地找到漏洞
的触发点。

当无法获得 POC 时,就只有厂商提供的对漏洞的简单描述了。一个比较通用的办法是使
用补丁比较器,首先比较 patch 前后可执行文件都有哪些地方被修改,之后可以利用反汇编工
具(如 IDA Pro)重点逆向分析这些地方。

漏洞分析需要扎实的逆向基础和调试技术,除此以外还要精通各种场景下的漏洞利用方
法。这种技术更多依靠的是经验,很难总结出通用的条款。本书将在第 5 篇中用若干个实际的
分析案例来帮助您体会漏洞分析的过程,希望能够起到抛砖引玉的效果。

1.4 漏洞的公布与 0 day 响应

公布漏洞的权威机构有两个:

微软的安全中心所公布的漏洞也是所有安全工作者和黑客们最感兴趣的地方。微软每个月第二周的星期二发布补丁,这一天通常被称为“Black Tuesday”,因为会有许多攻击者通宵达旦地去研究这些补丁 patch 了哪些漏洞,并写出 exploit。

因为在补丁刚刚发布的一段时间内,并非所有用户都能及时修复,故这种新公布的漏洞也有一定利用价值。有时把攻击这种刚刚被 patch 过的漏洞称为 1 day 攻击。

2. 二进制文件概述

2.1 PE 文件格式

一个典型的 PE 文件中包含的数据节(section)如下:

  • .text 由编译器产生,存放着二进制的机器代码,也是我们反汇编和调试的对象。
  • .data 初始化的数据块,如宏定义、全局变量、静态变量等。
  • .idata 可执行文件所使用的动态链接库等外来函数与文件的信息。
  • .rsrc 存放程序的资源,如图标、菜单等。

除此以外,还可能出现的节包括“.reloc”、“.edata”、“.tls”、“.rdata”等。

[外链图片转存失败(img-xAzSugAw-1562222484939)(http://r.photo.store.qq.com/psb?/V11kR0B93CzQxe/npAvoqK4*nNpHx6bJ0F8D.P.YUjJldBiNE5yfninez8!/r/dFIBAAAAAAAA)]

使用 Microsoft Visual C++中的编译指示符#pragma dat a_seg()可以把代码中的任意部分编译到 PE 的任意节中,节名也可以自己定义。

.2.2 虚拟内存

Windows 的内存可以被分为两个层面:物理内存和虚拟内存。

物理内存比较复杂,需要进入 Windows 内核级别 ring0 才能看到。

在用户模式下,我们用调试器看到的内存地址都是虚拟内存。

Windows 让所有的进程都“相信”自己拥有独立的 4GB 内存空间。如果进程(储户)不使用这些“虚拟地址”,它们对进
程来说就只是一笔“无形的数字财富”;当需要进行实际的内存操作时,内存管理器(银行)才会把虚拟地址(存款)和物理地址(钞票)联系起来。

操作系统原理中也有“虚拟内存”的概念,那是指当实际的物理内存不够时,有时操作系统会把“部分硬盘空间”当做内存使用从而使程序得到装载运行的现象。

2.3 PE 文件与虚拟内存之间的映射

静态反汇编工具看到的 PE 文件中某条指令的位置是相对于磁盘文件而言的,即文件偏移,我们可能还需要知道这条指令在内存中所处的位置,即虚拟内存地址(VA)

反之,在调试时看到的某条指令的地址是虚拟内存地址,我们也经常需要回到 PE 文件中找到这条指令对应的机器码。 为此,我们需要弄清楚 PE 文件地址和虚拟内存地址之间的映射关系。

数据在 PE 文件中的地址叫文件偏移地址(File Offset),是相对于文件开始处 0 字节的偏移。

PE 装入内存时的基地址叫做装载基址(Image Base)。默认情况下,EXE文件在内存中的基地址是0x00400000DLL文件是0x10000000。这些位置可以通过修改编译选项更改。

PE 文件中的指令被装入内存后的地址叫做虚拟内存地址(Virtual Address,VA)

相对虚拟地址(Relative Virtual Address,RVA) 是内存地址相对于映射基址的偏移量。

虚拟内存地址、映射基址、相对虚拟内存地址三者之间有如下关系。

VA = Image Base + RVA

文件偏移地址和 RVA 有很大的一致性,还有一些差异是由于文件数据的存放单位与内存数据存放单位不同而造成的。

PE 文件中的数据按照磁盘数据标准存放,以0x200 字节为基本单位进行组织。当一个数据节(section)不足 0x200 字节时,不足的地方将被 0x00 填充;当一个数据节超过 0x200字节时,下一个 0x200 块将分配给这个节使用。因此 PE 数据节的大小永远是 0x200 的整数倍。

当代码装入内存后,将按照内存数据标准存放,并以 0x1000 字节为基本单位进行组织。类似的,不足将被补全,若超出将分配下一个 0x1000 为其所用。因此,内存中的节总是0x1000 的整数倍。

文件偏移地址与虚拟内存地址之间的换算关系:

节偏移 = 起始段偏移 - 起始文件偏移

文件偏移地址= 虚拟内存地址(VA)−装载基址(Image Base)−节偏移 = RVA -节偏移

即:

文件偏移地址= RVA −段起始偏移 + 起始文件偏移

猜你喜欢

转载自blog.csdn.net/Ga4ra/article/details/94617249