MIPS缓冲区溢出 — 定位offset
首先编写存在缓冲区溢出的测试程序 vuln_system.c
#include <stdio.h> #include <sys/stat.h> #include <unistd.h> #include <string.h> #include <stdlib.h> void do_system(int code, char *cmd) { char buf[255]; system(cmd); } void main() { char buf[256] = {0}; char ch; int count = 0; unsigned int fileLen = 0; struct stat fileData; FILE *fp; if(0 == stat("passwd",&fileData)) fileLen = fileData.st_size; else return 1; if((fp = fopen("passwd","rb")) == NULL) { printf("cannot open file passwd\n"); exit(1); } ch = fgetc(fp); while(count <= fileLen) { buf[count++] = ch; ch = fgetc(fp); } buf[--count] = '\x00'; if(!strcmp(buf,"adminpwd")) { do_system(count,"ls -l"); } else { printf("you have an Invalid Password\n"); } fclose(fp); }
创建passwd文件,使用mips-linux-gcc编译此代码
python -c “print ‘A’*600” > passwd mips-linux-gcc vuln_system.c -static -o vuln_system
运行输出,引发故障

使用idapro对gdb进行远程调试
qemu-mips -g 1234 vuln_system
运行发现程序执行0x41414141时出错,即4个A

根据执行错误提示,在strcoll函数调用处设置断点,双击此函数也可以看到注释
# Alternative name is ‘__GI_strcmp’
执行到此处

根据寄存器V1地址,查看数据

是测试输入的全A值

在main函数出口,设置断点

执行到此时,RA寄存器值已经被覆盖为AAAA,引发溢出错误

复制时缓冲区在var_1A0

返回地址RA在var_4

据此计算偏移为RA-BUF = -0x4 + 0x1A0 = 0x19C == 412字节

测试
python -c “print ‘A’*0x19C+’BBBB’+’CCCC'” > passwd
qemu-mips -g 1234 vuln_system
计算的偏移正确

还可以采用动态调试的方法确定偏移位置,在PWN中常用
使用pattern脚本自动生成指定长度的字符串,比如使用gdb-peda插件,或pwntools等
用patternLocOffset.py脚本,根据返回地址来确定偏移量

得到偏移也是412

使用gdb-peda时,其生成的pattern string与之前不同,先将其写入passwd文件

然后运行时需要用与可执行程序相同的架构gdb
target连接运行,在地址0x41247341断下

然后得到的offset也是412
