我试图获取可在Ubuntu 16.04 LTS 64bit上运行的缓冲区溢出漏洞。为此,我使用了以下易受攻击的程序:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{

    char buffer[256];
    strcpy(buffer, argv[1]);
    printf("%s\n", buffer);
    return 0;
}


我停用了ALSR(将/proc/sys/kernel/randomize_va_space暂时设置为0),并使用

gcc vuln.c -o vuln -z execstack -fno-stack-protector
编译我的代码

我设法用

gdb$ run $(python -c 'print "A"*264 + "B"*6')


,并在gdb中获得以下结果: />我想用“ rip”的缓冲区开头覆盖B,以便以后可以将shellcode放在缓冲区的开头(某些noop开头):

所以,知道,我在缓冲区中写了多少rip,我看看A减去偏移量(我只是在玩偏移量,直到得到以A开头的行:

RSI: 0x602010 ('A' <repeats 200 times>...)
RDI: 0x1 
RBP: 0x4141414141414141 ('AAAAAAAA')
RSP: 0x7fffffffd9d0 --> 0x0 
RIP: 0x424242424242 ('BBBBBB')
Stopped reason: SIGSEGV
0x0000424242424242 in ?? ()


因此,从这个角度出发,我的缓冲区从堆栈上的rsp开始。

接下来,我将A重定向到0x7fffffffd8c0,如下所示: />
当我打算将shellcode放在我假设的缓冲区的开头时,我的shellcode的长度将为10个字节,看看是否可行:
br />,现在发生了一些我不理解的事情:尽管事实是,我在缓冲区中写入了完全相同数量的字符,但是rip的值发生了变化,显然它不再指向缓冲区的开头: />
gdb$ x/20x $rsp-288
0x7fffffffd8b0: 0x00007fffffffdaa8  0x0000000200000000
0x7fffffffd8c0: 0x4141414141414141  0x4141414141414141
0x7fffffffd8d0: 0x4141414141414141  0x4141414141414141


而不是0x7fffffffd8c0现在rip包含0x7fffffffd8c0

所以它实际上仍然指向我的rip的开头,而不是0x7fffffffd8ca'我在python命令中注入的s:

gdb$ run $(python -c 'print "A"*264 + "\x7f\xff\xff\xff\xd8\xc0"[::-1]')


显然我只是开始使用这些东西。 br />
我想念什么?

评论

您是否尝试过使用其他数量的“ S”字符?它的作用相同还是真的与您具有0xa字符的事实有关?

#1 楼

不用担心,shellcode在正确执行,只是调试器“跳过”了执行。

请记住,rip是指令指针,并且执行在rip处出现的任何代码。但是,如果代码无效,则会出问题(例如,将引发SIGSEGV)。在这种情况下,S(字节\x53)对应于push rbx命令(有效,并且将8个字节压入堆栈),而Arex.B-从本质上讲,这会导致SIGSEGV。 (请注意,将push rbx减小了esp,这是0x7fffffffd9d0 - 0x7fffffffd980 = 0x50大小的10倍)

您可以做的是:中断rbx函数中的ret指令。达到断点后,再执行1条指令,则main应该具有所需的值。