【发布时间】:2020-03-12 19:17:29
【问题描述】:
我正在尝试执行ProtoStar stack5 challenge。我知道解决方案(在写完之后),但我正在尝试提出不同的方法。
这是我们试图在其上执行 shellcode 的程序的源代码:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char buffer[64];
gets(buffer);
}
所以只是为了查看寄存器中发生了什么,我执行以下操作:
(gdb) n
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
11 in stack5/stack5.c
(gdb) x/30x $esp
0xbffff750: 0xbffff760 0xb7ec6165 0xbffff768 0xb7eada75
0xbffff760: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff770: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff780: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff790: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff7a0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff7b0: 0x41414141 0xbffff800 0xbffff85c 0xb7fe1848
0xbffff7c0: 0xbffff810 0xffffffff
(gdb) p $ebp
$1 = (void *) 0xbffff7a8
(gdb)
很好,我用 41414141 溢出了返回地址。正如预期的那样。现在,我要做的是将返回地址更改为接下来的 4 个字节,这样
00xbffff7a8: |saved frame pointer| - | return address| - |shellcode part 1| - |...| - |shellcode part n|
但是,当我尝试写 76 个“41”,然后是地址 0xbffff7a8 + 4(即 0xbffff7b0)时,它一直在写错误的东西。这是我输入的内容:
41414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141b0f7ffbf
请注意,我们使用的是小端系统。
但是,当我输入这个(作为 ASCII)时,这就是我在 $esp 和 $ebp 上看到的:
(gdb) n
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA°÷ÿ¿
11 in stack5/stack5.c
(gdb) x/30x $esp
0xbffff760: 0xbffff770 0xb7ec6165 0xbffff778 0xb7eada75
0xbffff770: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff780: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff790: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff7a0: 0x41414141 0x41414141 0x41414141 0xb7c3b0c2
0xbffff7b0: 0xbfc2bfc3 0xbffff800 0xbffff86c 0xb7fe1848
0xbffff7c0: 0xbffff820 0xffffffff ...
(gdb) p $ebp
$1 = (void *) 0xbffff7a8
如您所见,写入的是 0xb7c3b0c2 而不是预期的 0xbffff7b0
有人知道这是为什么吗?
注意:我意识到我真正想要的地址是 0xbffff7ac,而不是 0xbffff7b0。我会解决这个问题,但它不会改变我遇到的问题。
【问题讨论】:
-
@ChristianGibbons 使用
gets()的目的是导致溢出。常见的示例代码暴露了在没有边界检查的情况下接受输入的缺陷(以及该 SO 帖子中提到的所有其他内容)。gets()的“坏”用法是故意的。 -
@VeridianDynamics 我知道这一点。我正在尝试使用溢出,但我在堆栈上找到的字节与我输入的字节不同(请参阅问题的最后一部分)。
-
呃,哈哈,我回复了其他建议你不要使用
gets()的人。他们显然删除了他们的评论。你能告诉我你是如何输入字节的吗? -
@VeridianDynamics 没问题 :) 要获得 $ebp + 0x4,我需要 76 个字符。所以我输入了 'A' 76 次,然后我输入了相当于 b0 f7 ff bf 的 asccii。当我查看 GDB 上的堆栈时,一切都是我所期望的值,除了 b0 f7 ff bf 部分。如您所见,改为写入 0xb7c3b0c2。如果您需要更多信息,问题的结尾会更清楚。感谢您的回复!
-
您输入了哪些准确的 ASCII 码?
标签: c security debugging gdb buffer-overflow