原文:https://seclists.org/oss-sec/2018/q3/274

摘要

Qualys研究实验室的安全团队发现一个位于Linux内核函数create_elf_tables()中的整型溢出漏洞。在64位系统下,本地攻击者可能利用该漏洞通过SUID-root程序获取root权限。

只有内核commit b6a2fea39318 (mm:可变参数长度,2007),但是没有commit da029c11e6b1(exec:限制arg stack最多使用 75% 的 _STK_LIM,2017) 可被利用

绝大多数Linux发行版commit da029c11e6b1 在他们长期支持的内核中,但是 Red Hat Enterprise Linux 和 CentOS 并没有,因此这两个发行版中,容易受到攻击。

分析

150 #define STACK_ROUND(sp, items) \
151         (((unsigned long) (sp - items)) &~ 15UL)
...
165 create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
...
169         int argc = bprm->argc;
170         int envc = bprm->envc;
171         elf_addr_t __user *sp;//elf_addr_t == unsigned int
...
178         int items;
...
190         p = arch_align_stack(p);
...
287         items = (argc + 1) + (envc + 1) + 1;
288         bprm->p = STACK_ROUND(sp, items);//bprm->p = (((unsigned long) (sp - items)) &~ 15UL)
...
295         sp = (elf_addr_t __user *)bprm->p;

argc 代表传递给execve()的命令行参数个数,envc 代表传递给execve()的环境变量个数。因为argc、envc的大小都被限制在0 ~ 0x7FFFFFFF(MAX_ARG_STRINGS (fs/exec.c))之内,所以我们可以使287行的items变量整型溢出为一个负数.

因此,我们能够增加用户空间的栈指针而不是减少它(当items为负数的时候,分析第288行可知),将用户空间的栈重定向到我们的参数和环境字符串的中间,然后在SUID-root程序在用户空间执行的时候,重写这些字符串

利用

我们执行一个 SUID-root程序,使变量items的值为0x80000000,因此需要大约0x80000000 * sizeof(char ) = 16GB的参数指针,16GB的参数字符串,16GB的环境变量字符串,但是我们的利用只需要 2 16GB = 32GB的内存,而不是 3 * 16 = 48GB,因为我们使用了一些小技巧,减少内存的使用(例如,我们用等效的文件映射替换了近16GB的相等参数指针,这些映射实际上几乎没有内存)

下面的图展示了ld.so加载我们SUID-root程序时的用户空间栈布局:

               | argument strings  |          environment strings          |
--|---|--------|---------+---------|---------+---------+---------+---------|--
  | A | sprand | protect | padding | protect | scratch | onebyte | padding |
--|---|--------|---------+---------|---------+---------+------^--+---------|--
  |     0-8192              ~16GB                1MB         rsp    ~16GB
  v                                               <-------+---|----------|
  |                                                 stack | B | pointers |
  \-------------->-------------->-------------->--------------/   16GB
             0x80000000 * sizeof(elf_addr_t) = 16GB
  • A: 由190 - 287 行分配的栈空间(平台和基础平台功能字符串),大约512字节
  • sprand:是在第190分配的,大约在 0 - 8192字节之间
  • protect:参数字符串中最重要的参数字符串,必须保证不会被破坏(如:argv[0],SUID-root程序的名称)
  • padding:大约占16GB的参数字符串
  • protect:环境字符串中重要的环境变量字符串,必须保证不会被破坏(如:LD_PRELOAD环境字符串,其会被ld.so的handle_ld_preload函数使用)
  • scratch:1M的安全栈空间用于执行SUID-root程序。整型溢出items变量,会导致重定向用户空间的栈指针rsp指向我们的参数字符串和环境变量字符串之间(16GB)--更准确的说,指向我们在环境变量字符串中的onebyte区
  • onebyte:256KB大小,会被 ld.so中的handle_ld_preload函数以fname[]覆盖掉4KB大小的空间
  • padding:占用接近16GB的栈空间
  • pointers:将items变量溢出,重定向rsp之后,16GB的环境变量指针和参数指针将会被create_elf_tables()写到环境变量字符串padding区的高端
  • B:在ld.so调用handle_ld_preload之前分配的大约9KB的空间,其在onebyte中间分配的

因此,ld.so调用handle_ld_preload()时,会用fname buffer(可通过LD_PRELOAD环境变量控制) 覆盖掉部分我们的onebyte区,使process_envvars()的UNSECURE_ENVVARS过滤无效(LD_AUDIT,LD_LIBRARY_PATH,LD_PRELOAD等)

利用create_elf_tables()中的整型溢出,造成UNSECURE_ENVVARS过滤无效的POC演示如下:

# gcc -O0 -o poc-suidbin poc-suidbin.c
# chown root poc-suidbin
# chmod 4555 poc-suidbin

$ gcc -o poc-exploit poc-exploit.c
$ time ./poc-exploit
...
ERROR: ld.so: object 'LD_LIBRARY_PATH=.0LD_LIBRARY_PATH=.0LD_LIBRARY_PATH=.' from LD_PRELOAD cannot be preloaded:
ignored.
ERROR: ld.so: object 'LD_LIBRARY_PATH=.0LD_LIBRARY_PATH=.' from LD_PRELOAD cannot be preloaded: ignored.
ERROR: ld.so: object 'LD_LIBRARY_PATH=.' from LD_PRELOAD cannot be preloaded: ignored.
argc 2147090419
stack 0x7ffbe115008f < 0x7ffbe1150188 < 0x7fffe0e50128 < 0x7ff7e11503ea < 0x7ffbe102cdea
getenv 0x7ffbe114d83b .
0x7ffbe114d82b LD_LIBRARY_PATH=.
0x7ffbe114df60 LD_LIBRARY_PATH=.
0x7ffbe114df72 LD_LIBRARY_PATH=.
...
0x7ffbe114e69e LD_LIBRARY_PATH=.
0x7ffbe114e6b0 LD_LIBRARY_PATH=.
0x7ffbe114e6c2 LD_LIBRARY_PATH=.

real    5m38.666s
user    0m0.049s
sys     1m57.828s

演示程序下载地址

poc-suidbin_c.bin:

https://seclists.org/oss-sec/2018/q3/att-274/poc-suidbin_c.bin

poc-exploit_c.bin:

https://seclists.org/oss-sec/2018/q3/att-274/poc-exploit_c.bin

内存分析

一共需要32GB的内存。

溢出items变量,仅仅只需要argc或envc中的任意一个就可以造成溢出,即只要argc就可以,为什么还需要16GB的环境变量呢?其实,溢出后,会造成rsp指针后移16GB,然后写入16GB的参数指针。16GB环境变量就是预留出来的存放指针的地方。

影响版本

内核版本: 2.6.x, 3.10.x, 4.14.x

  • Red Hat Enterprise MRG 2
  • Red Hat Enterprise MRG 2
  • Red Hat Enterprise MRG 2
  • Red Hat Enterprise Linux 5
  • Debian jessie 3.16.56-1+deb8u1
  • Debian jessie (security) 3.16.57-2

吐槽

该漏洞至少需要32GB的内存且系统结构为x64.但是我物理机一共才24G,根本无法调试。。。。。。看来这漏洞专搞高端服务器。

CVE-2018-14634 - Linux create_elf_tables()中的整型溢出 - 翻译的更多相关文章

  1. dateline 在数据库中就是 整型字段。date函数是可以转换成可读日期的。

    返回数据中的dateline全部用date()函数转换后再返回,是要嵌套循环还是遍历,代码怎么写? //查询我的活动 function user_activity_info_by_uid($uid){ ...

  2. Linux漏洞分析入门笔记-CVE_2018_6323_整型溢出

    操作系统   Ubuntu 16.04 /32 位 调试器     IDA pro 7.0 漏洞软件   binutils-2.29.1 0x00: 漏洞描述 1.什么是整数溢出: 在计算机中,整数分 ...

  3. CVE-2019-11477:Linux 内核中TCP协议栈整数溢出漏洞详细分析 代码卫士 今天

    CVE-2019-11477:Linux 内核中TCP协议栈整数溢出漏洞详细分析 代码卫士 今天

  4. C语言的整型溢出问题

    整型溢出有点老生常谈了,bla, bla, bla… 但似乎没有引起多少人的重视.整型溢出会有可能导致缓冲区溢出,缓冲区溢出会导致各种黑客攻击,比如最近OpenSSL的heartbleed事件,就是一 ...

  5. 记录: 一次解决整型溢出攻击(使用scala,隐式转换)

    最近项目遇到一次整型溢出攻击 有一个功能,玩家购买num个物品. 每个物品花费14货币. 客户端限制玩家只能购买 1-9999个该物品. 但是某玩家通过技术手段,获得了客户端的运行权限. 于是发送协议 ...

  6. 在JavaScript中判断整型的N种方法

    原文:http://www.cnblogs.com/YcYYcY/p/3759184.html 整数类型(Integer)在JavaScript经常会导致一些奇怪的问题.在ECMAScript的规范中 ...

  7. MySQL和PHP中以整型存储IP地址

    正文:将IP地址以整型存储 一般我们在数据库中会用到ip地址用来查记录的等等,而ip地址是分为四段的,一般是用varchar或char类型存储.但是其实有更好的存储方法就是以整型存储IP地址. 因为c ...

  8. C#语言基础 Main 函数中变量 整型

    在我们每次上网或者用电脑的时候,请输入你的xxx 或者你的名字(年龄/身高/学校/籍贯)是 在这里我们就要学到一些变量,就是不确定的东西 string a:   //赋予变量 a ="内容& ...

  9. c语言中指向整型指针的指针的理解

    /************************************************************************* > File Name: ptr_ptr_i ...

随机推荐

  1. 数据机构-折半查找法(二分查找法)-Python实现

    Python实现二分查找法(基于顺序表) class List: elem=[] #存储顺序表元素 last=-1 #设置初始为-1 SeqList = List() #创建一个顺序表 print(& ...

  2. 性能监控(5)–JAVA下的jstat命令

    jstat的基本语法为 Usage: jstat -help|-options jstat -<option> [-t] [-h<lines>] <vmid> [& ...

  3. Python 最佳实践指南 2018 学习笔记

    基础信息 版本 Python 2.7 Python 3.x Python2.7 版本在 2020 年后不再提供支持,建议新手使用 3.x 版本进行学习 实现 CPython:Python的标准实现: ...

  4. polyfill-eventsource added missing EventSource to window ie浏览器 解决方案

    今天遇到一个 ie浏览器显示空白,报错内容是: polyfill-eventsource added missing EventSource to window的问题, import 'babel-p ...

  5. 2018-02-27 "Literate Programming"一书摘记之一

    书到后才发现是Knuth的论文集, 第一篇就在网上: Computer programming as an art (1974). 其中"Taste and Style"(品味和风 ...

  6. 卸载Myeclipse10.5 报错“an error has occured.See the log file ...Uninstaller\...”

    找到Myeclipse的安装包,双击它,会出现Uninstaller的按钮,单击卸载即可. 另,网上说,windows下cmd命令道myeclipse.exe 目录,然后执行myeclipse.exe ...

  7. Testlink Testlink在Windows下的安装

    Testlink在Windows下的安装   by:授客 QQ:1033553122   测试环境 testlink-1.9.14 下载地址:http://pan.baidu.com/s/1pLrcu ...

  8. JMeter http(s)测试脚本录制器的使用

    JMeter http(s)测试脚本录制器的使用 by:授客 QQ:1033553122 http(s) Test Script Recorder允许Jmeter在你使用普通浏览器浏览web应用时,拦 ...

  9. JavaScript按纯数字排序

      直接上代码: var arr=[ {name:"张散步",age:"23",sports:"篮球",number:"23112 ...

  10. MIME 内容类型

    MIME内容类型 https://www.iana.org/assignments/media-types/media-types.xhtml 媒体在各浏览器的支持情况: https://develo ...