#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_space
暂时设置为0
),并使用gcc vuln.c -o vuln -z execstack -fno-stack-protector
编译我的代码我设法用
gdb$ run $(python -c 'print "A"*264 + "B"*6')
,并在gdb中获得以下结果: />我想用“
rip
”的缓冲区开头覆盖B
,以便以后可以将shellcode放在缓冲区的开头(某些noop开头):所以,知道,我在缓冲区中写了多少
rip
,我看看A
减去偏移量(我只是在玩偏移量,直到得到以A
开头的行:RSI: 0x602010 ('A' <repeats 200 times>...)
RDI: 0x1
RBP: 0x4141414141414141 ('AAAAAAAA')
RSP: 0x7fffffffd9d0 --> 0x0
RIP: 0x424242424242 ('BBBBBB')
Stopped reason: SIGSEGV
0x0000424242424242 in ?? ()
因此,从这个角度出发,我的缓冲区从堆栈上的
rsp
开始。 接下来,我将
A
重定向到0x7fffffffd8c0
,如下所示: /> 当我打算将shellcode放在我假设的缓冲区的开头时,我的shellcode的长度将为10个字节,看看是否可行:
br />,现在发生了一些我不理解的事情:尽管事实是,我在缓冲区中写入了完全相同数量的字符,但是
rip
的值发生了变化,显然它不再指向缓冲区的开头: /> gdb$ x/20x $rsp-288
0x7fffffffd8b0: 0x00007fffffffdaa8 0x0000000200000000
0x7fffffffd8c0: 0x4141414141414141 0x4141414141414141
0x7fffffffd8d0: 0x4141414141414141 0x4141414141414141
而不是
0x7fffffffd8c0
现在rip
包含0x7fffffffd8c0
。所以它实际上仍然指向我的
rip
的开头,而不是0x7fffffffd8ca
'我在python命令中注入的s:gdb$ run $(python -c 'print "A"*264 + "\x7f\xff\xff\xff\xd8\xc0"[::-1]')
显然我只是开始使用这些东西。 br />
我想念什么?
#1 楼
不用担心,shellcode在正确执行,只是调试器“跳过”了执行。请记住,
rip
是指令指针,并且执行在rip
处出现的任何代码。但是,如果代码无效,则会出问题(例如,将引发SIGSEGV)。在这种情况下,S
(字节\x53
)对应于push rbx
命令(有效,并且将8个字节压入堆栈),而A
是rex.B
-从本质上讲,这会导致SIGSEGV。 (请注意,将push rbx
减小了esp
,这是0x7fffffffd9d0 - 0x7fffffffd980 = 0x50
大小的10倍)您可以做的是:中断
rbx
函数中的ret
指令。达到断点后,再执行1条指令,则main
应该具有所需的值。
评论
您是否尝试过使用其他数量的“ S”字符?它的作用相同还是真的与您具有0xa字符的事实有关?