首先来了解一下什么是fuse
简而言之就是一个二进制文件,但是运行起来之后实现了一个文件系统的功能。
然后我们看题目给的二进制文件:
main_real函数的参数ida没有很好的翻译出来,我们看一下源码:
可以看到第三个参数是operation,这里直接放重命名好的:
到这里我们大概摸清了程序功能,其实就是通过这样一个函数表,起了一个用户态文件系统,在文件系统中对文件的各项操作都是由这些函数来实现的。
需要在这些函数中找漏洞
首先将文件的格式逆出来:
结构体大概长这样,前0x20是文件名,然后是文件类型,文件类型为0表示是一个文件,为1表示是一个文件夹,然后是size,最后八字节是存储文件内容的指针,如果是文件夹的话则里面存储的是文件结构体。
然后我们开个天眼,直接定位漏洞到create函数:
可以看到,文件名是固定的最大0x20长度,但是这里在strcpy的时候,并没有对s2的长度进行检测,也就是说这里存在一个溢出,可以利用文件更名操作,修改文件类型,文件大小甚至文件指针。
我们设想一下,如果我们把伪造好的文件结构体当做文件内容读进去,再利用溢出将其改成文件夹,这就达到了伪造文件的目的,伪造的文件的ptr可以直接指向got表,然后利用read和write就可以做到读取和修改got表,到这里此题就基本结束了,只需要将free改成system,然后free一个写有cp /chroot/flag /chroot/rwdir/flag命令的file就结束了。
在调试的时候可以自己在本机上搭个fuse环境,然后运行的时候加个-d参数即可。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>