麻省理工学院。 讲座课程#6.858。 “计算机系统的安全性。” Nikolai Zeldovich,James Mickens。 2014年
计算机系统安全是一门有关开发和实施安全计算机系统的课程。 讲座涵盖了威胁模型,危害安全性的攻击以及基于最新科学研究的安全技术。 主题包括操作系统(OS)安全性,功能,信息流管理,语言安全性,网络协议,硬件安全性和Web应用程序安全性。
第1课:“简介:威胁模型”
第1 部分 /
第2 部分 /
第3部分第2课:“控制黑客攻击”,
第1 部分 /
第2 部分 /
第3部分第3讲:“缓冲区溢出:漏洞利用和保护”
第1 部分 /
第2 部分 /
第3部分 您可以根据自己的目的使用猜测“ canary”的技术,以便从选择的角度找出“弱”的存在。 也就是说,如果您猜对了,服务器将重新启动,这将向您发出信号,表明设置值非常容易猜测。 因此,有可能打败随机的“ canaries”,前提是服务器重启后它们的值不会改变。 您也可以使用小工具来实施一系列相关的攻击。
接下来,我们将探讨一种更有效的方法,您可以使用所有这些方法来克服数据执行保护,随机地址空间和“ canaries”的问题。
让我们将注意力转向64位架构,而不是32位架构。 前者更适合随机化,因此它们为您提供了更多“机会”来防御黑客。 这些系统在攻击形成方面看起来更加有趣。
从
BROP的角度也考虑了这种类型的64位体系结构,即“盲目的”反向编程。 为简单起见,我们假设64位和32位计算机之间的唯一区别在于,在64位计算机上,参数传递给寄存器,对于32位计算机,参数传递给堆栈。

当函数开始执行时,将“查找”某些寄存器以查找参数在何处。
现在,让我们进入今天的演讲的重点-什么是盲目的面向返回的编程或
BROP 。 我们要做的第一件事是找到一个停止小工具。 请记住,当我们说“小工具”时,实际上是指寄信人地址。 小工具由返回地址标识,即我们要执行的指令序列的起始地址。 那么什么是停止小工具?
本质上,它是代码中某个位置的返回地址,但是,如果您跳到那里,则只需暂停程序即可,但不要导致程序崩溃。 这就是为什么将其称为Stop小工具的原因。
您可以跳入代码中的某个位置,然后启动睡眠系统调用或暂停或类似操作。 如果您跳到这个地方,程序可能会以某种方式“陷入”无限循环。 停止发生的原因并不重要,但是您可以想象会导致停止的情况。
停止小工具有什么用?
一旦攻击者使用猜测位的交互式技术设法击败“金丝雀”,他就可以开始重写此返回地址,
ret地址,并开始“摸索”停止小工具。 请注意,您可以在堆栈上放置的大多数随机地址很可能只会导致服务器崩溃。 同样,此消息是针对您的攻击者的,这表明您发现的内容不是停止的小工具。 因为当服务器崩溃时,您的套接字会关闭,并且作为攻击者,您知道自己没有上过停止小工具。 但是,如果您猜到了什么,之后的插座仍然打开了一段时间,您会想:“是的,我找到了这个停止工具!” 因此,第一步的基本思路是找到该停止小工具。

第二步是您要查找使用
pop命令删除堆栈条目的小工具。 因此,您应该使用精心设计的指令序列来确定何时抓取这些堆栈小工具之一。 此序列将由
探测地址的探测地址 ,
停止地址的停止地址以及
崩溃地址的系统故障
地址组成 。
因此,
探测地址就是我们要放入堆栈的地址。 这是清除堆栈的潜在小工具的地址,即
停止地址 -这是我们在第一步中考虑的地址,这是停止小工具的地址。 然后,
崩溃地址将只是不可执行代码的地址。 您可以在此处简单地输入零地址(0 x 0),如果将
ret函数应用于此地址并尝试在该地址执行代码,则将导致程序崩溃。

因此,我们可以使用这些类型的地址来找出这些小工具在清理
堆栈弹出堆栈的位置 。
我将举一个简单的例子。 假设我们有两个不同的
探针示例,陷阱
陷阱和
停止 陷阱 。 假设在
探针的帮助下
,我们将“探测”某个地址,假设它以4开头,以8结尾:0x4 ... 8,其后是形式为0x4 ... C的下一个地址。 假设地,我们可以假设这两个地址之一是
堆栈弹出小工具的地址。
陷阱陷阱将获得零地址0x0和0x0,并且使
stop小工具
stop具有任意地址,例如0xS ... 0xS ...,这无关紧要。 该停止小工具指向睡眠(10)代码,导致程序暂停。
让我们从
探测操作开始,该操作清除一些寄存器并按以下顺序返回:
pop rax; 撤退 。 会发生什么? 当系统跳至该地址时,堆栈指针将移至小工具的中间。 小工具在这里要做什么? 正确,执行
pop rax操作。

然后跟随
ret ,它将功能移到小工具的最上面一行,即
stop ,并且该功能将停止而不会使整个程序崩溃。 因此,使用此小工具,攻击者可以说
探测地址属于这些功能之一,它会清除堆栈,因为服务器客户端连接已打开。
现在,让我们假设第二个
探针地址指向某个寄存器的
xor rax,rax,ret之类的东西。

那么,如果我们尝试跳至该小工具,会发生什么? 请注意,它不会清除堆栈上的任何内容,而只是更改寄存器的内容。 因此,我们将返回到位于上面的0x0地址。 这将导致系统崩溃。 客户端与服务器的连接将断开,黑客将了解这不是清除堆栈
栈弹出的小工具。
这样,您可以使用一系列更奇怪的陷阱和停止小工具,例如,可以清除堆栈中的两个项目。 为此,您只需要在此处放置另一个
陷阱指令即可,如果该小工具没有擦除两个元素,您将发现自己处于这些陷阱之一中,并且代码将停止执行。 讲座的材料描述了一个称为
BROP小工具的东西
,如果您不喜欢返回编程的话
,它将很有用。 但是今天我也将告诉您如何使用这些简单的
流行小工具发动类似的攻击。 一旦了解了这一点,使用
BROP小工具将变得容易
得多 。
但是你们所有人都知道我们如何对这些小工具使用
探测功能吗? 假设您找到了代码片段的位置,可以使用
pop函数清除堆栈,从中删除一个元素,但是您实际上并不知道此
pop函数将在哪个寄存器中工作。 您只知道她已经准备好执行死刑。 但是您需要知道这些
弹出式小工具将在哪个寄存器中工作,因为在64位体系结构中,寄存器控制着您要调用的函数的参数位于何处。
因此,我们的目标是能够创建一个小工具,该小工具将允许我们删除放入某些堆栈寄存器中的值,并最终启动系统调用
system call ,从而使我们可以做一些不好的事情。
因此,现在我们需要确定
pop小工具使用了哪些寄存器。

为此,我们可以利用暂停系统调用。 如果系统调用被暂停,则程序的执行将被暂停,并且不接受任何参数。 这意味着系统将忽略寄存器中的所有内容。
实际上,要找到我们正在执行的暂停指令,您可以链接所有这些
弹出式小工具,以便将它们全部放入堆栈中,并在每个小工具之间
插入一个系统调用号以进行暂停。 然后,我们将查看是否可以通过这种方式“暂停”程序。 让我给你一个具体的例子。
在这里,我们将一个小工具放在返回地址栏中,以清除
RDI寄存器并将
ret函数应用于它们。 在它上面,我们将放置一个
系统调用号码以暂停。
假设上面还有一个小工具,可以在另一个寄存器(例如
RSI)中实现
pop函数,然后再进行
ret 。 然后,我们再次将
syscall号暂停。 然后对发现的所有小工具执行此操作,然后以推定地址
syscall结束堆栈的顶部。

再次调用您如何使用这些系统调用。 您必须将
系统调用号放入
RAX寄存器中,然后调用
libc syscall函数,该函数将进行请求的系统调用。
那么,当我们执行此代码时会发生什么呢? 我们将来到这里,到达
ret地址行,我们将跳至该小工具的地址,应该注意的是,攻击者知道位于右侧的该小工具会从堆栈中删除某些内容,但尚不知道它位于哪个寄存器中。
那么,如果我们跳到
ret address ,会发生什么? 他将使用
pop函数暂停
syscall ,在一些攻击者不知道的寄存器中暂停它,然后我们将继续在堆栈中向上扩展此操作链。
这样做时,我们希望这些小工具之一将对相应
RAX寄存器中的
syscall编号执行
pop功能。 因此,当我们到达堆栈顶部的此处时,在“发送”所有具有
系统调用编号要暂停的寄存器的途中,我们希望我们仍然有一个寄存器,这应该是正确的。 因为如果我们的一个小工具执行此操作,然后再执行
ret ,过一会儿,我们将返回此处,位于堆栈的顶部,那么我们将暂停一下。 暂停再次向攻击者发出信号。 因为如果此
syscall的假定地址不正确,则程序将失败。
那么,什么使我们能够进行这一阶段的攻击呢? 我们仍然不知道哪个
弹出式小工具位于哪个寄存器中,但是我们知道其中一个将释放我们要控制的
RAX 。 我们可能知道
syscall地址,因为我们设法暂停了系统。
完成此操作后,我们可以一一检查这些小工具,然后找出哪个小工具使系统处于暂停状态。 换句话说,我们剪切了
ret地址行和堆栈顶部之间的所有内容,直接进入
syscall 。 我们将检查是否发生了暂停或系统故障。 如果发生故障,我们将找出导致该故障的小工具,例如,它在右侧的底行中,即
pop rdi 。 摆脱他,再尝试下一个。 在
ret address上方的行中放入
syscall 的真实地址。 我们可以暂停程序吗? 是的,这意味着我们了解到此
流行小工具应释放
RAX 。 清楚吗?
观众:那么,猜测系统调用地址的方法仅仅是盲目转移小工具?
教授:是的,是的,当您使用
PLT文件扩展名和类似的东西时,有一些方法可以优化教材中的此过程。 通过我描述的简单攻击,您实际上只是将地址粘贴到此处,并确保它是否引起了暂停。 作为测试的结果,我们找出了
syscall的位置。 我们将找出执行
pop RAX的指令的
位置 。 我们还需要在其他寄存器中执行
pop的小工具。 您可以对它们进行类似的测试。 因此,与其暂停
系统调用号码 ,
不如将
push用于其他一些命令,例如,使用
RAX和
RDI参数。
因此,您可以利用以下事实:对于要控制的任何特定寄存器集,都有某种
系统调用可以使攻击者发现您是否成功破坏了它。 因此,在此阶段结束时,您将拥有
syscall地址和小工具堆地址,这使您可以
弹出任意寄存器。
现在,我们继续执行第四步,即
写入 -记录。 第四步是记录系统调用。 要调用
write ,我们需要具有以下小工具:
pop rdi,ret;
pop rsi,ret;
pop rdx,ret;
流行rax,ret;
系统调用
系统调用如何使用这些寄存器? 第一个是套接字,或更一般而言,是要传输以用于写入的文件描述符。 第二个是缓冲区,第三个是该缓冲区的长度,第四个是系统调用号,第五个是
syscall本身。
因此,如果我们找到所有这些小工具,则可以控制嵌入在参数中的值,这些参数又被放置在这些寄存器中,因为我们只是将它们“推”到了堆栈中。
什么是插座? 在这里,我们不得不猜测一点。 您可以利用Linux限制文件同时打开连接数达到2024的事实,而且它应该是所有可用连接中最少的。
我想知道我们要插入到缓冲区指针中吗? 没错,我们打算在这里使用程序的文本片段,我们将其放在程序代码中的指针中。 这使我们能够使用正确的客户端套接字调用从内存中读取二进制文件。 然后,攻击者可以使用
GDB或其他工具来获取此二进制文件,离线分析脱机文件,以找出所有这些文件的位置。 攻击者知道,现在,每当服务器“崩溃”时,相同的随机对象集就会存储在其中。 因此,既然攻击者可以找到堆栈内容的地址和偏移量,就可以直接攻击这些小工具。 它可以直接攻击其他漏洞,弄清楚如何打开外壳等。 换句话说,在您向黑客提供二进制文件的地方,您被击败了。
这就是
BROP攻击的
工作方式 。 正如我说的,在讲座材料中,有许多方法可以优化这些过程,但是首先您需要了解主要材料,否则优化就失去了意义。 因此,您可以单独或在课后与我谈谈优化。
就目前而言,可以说这些是如何发起
BROP攻击的基础。 您必须找到
stop小工具,找到执行
pop stack条目功能的小工具,找出它们位于哪些寄存器中,
syscall所在的位置,然后根据获得的信息启动
write 。

因此,快速浏览主题,您如何防御
BROP ? 因此,您最明显的事情就是重新随机化。 由于“堕落的”服务器不会重生,不会创建其自身的随机版本,因此可以使攻击者有机会测试有关程序工作方式的各种假设。
保护自己的一种简单方法是确保在恢复进程时执行
exec而不是
fork 。 因为执行该过程时,会创建一个全新的随机放置的空间,至少在Linux上会这样。 在Linux上,当您使用
PIE ,与位置无关的可执行文件(位置无关的可执行文件)进行编译时,使用
exec时,您只会获得新的随机地址空间。
第二种方法是简单地使用Windows,因为该操作系统基本上不具有
fork功能。 这意味着在Windows上恢复服务器时,该服务器将始终具有新的随机地址空间。
这里有人问服务器故障后,如果他不断开连接会怎样? 因此,如果在服务器崩溃期间我们以某种方式“捕获”此错误并保持连接打开一段时间,我们可能会混淆攻击者,使攻击者不会收到有关失败的信号,并认为自己已找到正确的地址。
在这种情况下,您的
BROP攻击将变成
DOS攻击。 因为您刚刚获得了所有潜在的僵尸进程。 它们没有用,但是您不能放任其走,否则,您将不得不删除此信息。
您可能想到的另一件事是进行我们之前谈到的边界检查。 讲座的资料说,这种方法是无效的,因为它要贵2倍,但您仍然可以使用它。
这就是
BROP的工作方式。 至于家庭作业,在那里提出了一个更微妙的问题:如果您使用当前时间的哈希值怎么办? 即,您重新启动程序的时间长度。 这足以防止此类攻击吗? 请注意,如果您很容易预测到哈希中输入的数据,则哈希不会神奇地为您提供熵位。 如果您的哈希值包含数十亿比特,那没关系。 但是,如果那里只有几个意思,那么攻击者只会猜测它们。 当然,使用随机时间哈希比不使用任何东西来防止黑客攻击要好,但这不会为您提供应依靠的安全性。
该课程的完整版本可
在此处获得 。
感谢您与我们在一起。 你喜欢我们的文章吗? 想看更多有趣的资料吗? 通过下订单或将其推荐给您的朋友来支持我们,为我们为您开发
的入门级服务器的独特模拟,为Habr用户提供
30%的折扣: 关于VPS(KVM)E5-2650 v4(6核)的全部真相10GB DDR4 240GB SSD 1Gbps从$ 20还是如何划分服务器? (RAID1和RAID10提供选件,最多24个内核和最大40GB DDR4)。
戴尔R730xd便宜2倍? 仅
在荷兰和美国,我们有
2台Intel Dodeca-Core Xeon E5-2650v4 128GB DDR4 6x480GB SSD 1Gbps 100电视(249美元起) ! 阅读有关
如何构建基础架构大厦的信息。 使用价格为9000欧元的Dell R730xd E5-2650 v4服务器的上等课程?