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