[翻译] Linux (x86) Exploit 开发系列教程之三(Off-By-One 漏洞 (基于栈))
发表于:
2017-4-10 21:19
13845
[翻译] Linux (x86) Exploit 开发系列教程之三(Off-By-One 漏洞 (基于栈))
Off-By-One 漏洞 (基于栈)
虚拟机安装:Ubuntu 12.04(x86)
什么是off by one?
将源字符串复制到目标缓冲区可能会导致off by one
1、源字符串长度等于目标缓冲区长度。
当源字符串长度等于目标缓冲区长度时,单个NULL字节将被复制到目标缓冲区上方。这里由于目标缓冲区位于堆栈中,所以单个NULL字节可以覆盖存储在堆栈中的调用者的EBP的最低有效位(LSB),这可能导致任意的代码执行。
一如既往的充分的定义,让我们来看看off by one的漏洞代码!
漏洞代码:
编译命令
上述漏洞代码的第[2]行是可能发生off by one溢出的地方。目标缓冲区长度为256,因此长度为256字节的源字符串可能导致任意代码执行。
如何执行任意代码执行?
使用称为“EBP覆盖”的技术实现任意代码执行。如果调用者的EBP位于目标缓冲区之上,则在strcpy之后,单个NULL字节将覆盖调用者EBP的LSB。要了解更多关于off by one,让我们反汇编漏洞代码并绘制它的堆栈布局。
反汇编:
堆栈布局
当我们已经知道256字节的用户输入,用空字节可以覆盖foo的EBP的LSB。所以当foo的存储在目标缓冲区“buf”之上的EBP被一个NULL字节所覆盖时,ebp从0xbffff2d8变为0xbffff200。从堆栈布局我们可以看到堆栈位置0xbffff200是目标缓冲区“buf”的一部分,由于用户输入被复制到该目标缓冲区,攻击者可以控制这个堆栈位置(0xbffff200),因此他控制指令指针(eip )使用他可以实现任意代码执行。让我们通过发送一系列256的“A”来测试它。
测试步骤1:EBP是否覆盖,从而可能覆盖返回地址?
以上输出显示由于EBP覆盖,我们已经控制指令指针(EIP)。
测试步骤2:距离目标缓冲区的偏移是多少?
现在,我们可以从目标缓冲区“buf”的起始位置开始找到偏移量,我们需要替换我们的返回地址。记住在off by one 漏洞中,我们不会覆盖堆栈中存储的实际返回地址(像我们在基于堆栈的缓冲区溢出中),而是攻击者控制的目标缓冲区“buf”内的4字节内存区域将被视为返回地址位置(在off by one溢出之后)。因此,我们需要找到这个返回地址位置偏移量(从'buf'),它是目标缓冲区“buf”本身的一部分。不是很清楚,但是没有问题继续阅读!
现在让我们尝试从文本段地址0x08048490开始了解CPU的执行情况。
0x08048476 - ret - 返回到位于ESP(0xbffff204)的指令。现在,ESP指向攻击者控制的缓冲区,因此攻击者可以返回到任何要实现任意代码执行的位置。
现在让我们回到我们原始的测试,找到从目标缓冲区'buf'到返回地址的偏移量。如我们的堆栈布局图所示,'buf'位于0xbffff158,在CPU执行后,我们知道目标缓冲区“buf”中的返回地址位于0xbffff204。因此,从“buf”到返回地址的偏移量为0xbffff204 - 0xbffff158 = 0xac。因此,用户输入的形式“A”* 172 +“B”* 4 +“A”* 80,用“BBBB”覆盖EIP。
以上输出显示攻击者可以控制返回地址。返回地址位于“buf”的偏移量(0xac)处。有了这些信息,我们可以编写一个漏洞利用程序来实现任意的代码执行。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)