嘻!这几天一直在玩iscc,wp也准备了不少,还是先打算写一系列的假装pwn题,小白入门,从我做起。
拿到elf先运行一下
检测一下,得到一些信息
1.Canary(栈保护) 这个选项表示栈保护功能有没有开启。栈溢出保护是一种缓冲区溢出攻击缓解手段,当函数存在缓冲区溢出攻击漏洞时,攻击者可以覆盖栈上的返回地址来让shellcode能够得到执行。当启用栈保护后,函数开始执行的时候会先往栈里插入cookie信息,当函数真正返回的时候会验证cookie信息是否合法,如果不合法就停止程序运行。攻击者在覆盖返回地址的时候往往也会将cookie信息给覆盖掉,导致栈保护检查失败而阻止shellcode的执行。在Linux中我们将cookie信息称为canary。
2.NX/DEP(堆栈不可执行) NX即No-eXecute(不可执行)的意思,NX(DEP)的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。
3.PIE/ASLR(地址随机化) 可以防范基于Ret2libc方式的针对DEP的攻击。ASLR和DEP配合使用,能有效阻止攻击者在堆栈上运行恶意代码。liunx下关闭PIE的命令如下: sudo -s echo 0 > /proc/sys/kernel/randomize_va_space
4.Fortify 这个保护机制查了很久都没有个很好的汉语形容,根据我的理解它其实和栈保护都是gcc的新的为了增强保护的一种机制,防止缓冲区溢出攻击。由于并不是太常见,也没有太多的了解。
5.RelRO 设置符号重定向表格为只读或在程序启动时就解析并绑定所有动态符号,从而减少对GOT(Global Offset Table)攻击。
发现我们的elf没有栈保护和PIE,只存在不能执行栈区。接下来IDA打开文件,main函数F5
我标题都取为栈溢出了,那肯定就存在栈溢出了。。简单分析一下,v4存放在距离栈底64h的地方,并且gets函数存在溢出漏洞,即gets函数读入一行,以换行符结束,那么我们就可以填充满栈,用我们的东西覆盖掉返回地址,就能控制程序执行流了。
接着看程序,在左边的导图里面找到system,因为system可以得到系统的shell,查看交叉引用,发现在secure里面存在调用
那我们就用system的调用地址0x08048641覆盖原本的返回地址吧。(注意一下在计算机内存中,对应的每个值都是按照字节存储的。一般情况下都是采用小端存储)先计算我们需要覆盖掉的字节数
找到main函数调用我们gets函数的地方,发现字符串输入的地址是关于esp的偏移,那就先去找esp的值
gdb调试得到esp的值为 0xffffd170 ,ebp为 0xffffd1f8 ,输入的s[esp+0x1c]为0xFFFFD18C
得出字符串相对于ebp的偏移为0x6c,所以相对于与返回地址的偏移为0X6C+4,py脚本敲一下payload
from pwn import *
sh = process('./ret2text')
target = 0x804863a
sh.sendline('A' * (0x6c+4) + p32(target))
sh.interactive()
即可拿到shell