[细节剖析]X Windows中一个22年的漏洞
X Windows系统,今天作为世界各地的Linux桌面,已经存在超过20年了,仍然存在Bug。几天前Sysadmins为libXfont库提供了补丁,来对应新发现的已经在代码中存在了22年的特权升级漏洞,补丁抢在了让人厌烦的exploit前发布了。这一漏洞可以使得登入到一个存在漏洞的机器的人将X服务搞崩溃,或者执行输入代码后成为超级用户。
在混沌通信大会(译注:始于1984年,由欧洲最大的黑客联盟组织——德国混沌电脑俱乐部主办。该会议主要研讨计算机和网络安全问题,旨在推进计算机和网络安全。开始多是热爱计算机的黑客参与,其后不断吸引科学家、安全专家和计算机爱好者参加,因此也有人称之为欧州黑客大会。)的一个展示上,发现了数百个漏洞(在X.org上讨论的电子邮件在此:http://lists.x.org/archives/xorg-devel/2013-December/039773.html),最新发现的漏洞是文本的栈溢出漏洞,可以追溯到1991年,这个Bug至今仍存在于所有的X11版本中。
这一漏洞很简单,并且影响共享的电脑,但是本文只想剖析这一系列的安全问题是如何发生的。
来自X.org的公告内容:“一个BDF字体文件包含了一个超过期望长度的字符串,会导致站溢出。在创建了栈保护的X服务上进行测试,当读取用户提供的巧妙设计的字体时,会导致服务立即崩溃。” (译注:http://lists.x.org/archives/xorg-announce/2014-January/002389.html)
存在问题的地方是如下代码中的bdfReadCharacters()函数中(译注:源代码路径http://cgit.freedesktop.org/xorg/lib/libXfont/tree/src/bitmap/bdfread.c)
如果你没有见过这个bug,我会详细解释。屏幕上的字体可以保存成GBD格式(Glyph Bitmap Distribution),详情参见此文档(http://partners.adobe.com/public/developer/en/font/5005.BDF_Spec.pdf),保存后的内容格式是以STARTCHAR 2.1+字体内容的格式。(译注:请参照上图中1305行的代码)
如果被加载的字体包含一个短的版本号,作为字符串加载的话一切正常,例如本文中的版本号“2.1”。这一信息在代码中通过文件dbfread.c中的函数调用函数sscanf将信息拷贝到charName字符数组当中。(译注:参照上述图中的1302-1308行代码)。问题是sscanf函数没有限定读取版本号码的字符串长度,该函数会一致拷贝文件中的数据,直到遇到了一个空格符,才终止。(译注:http://www.cplusplus.com/reference/cstdio/sscanf/
http://www.cplusplus.com/reference/cctype/isspace/)
字符数组charName被定义为长度只有100个字节,因此当一个BDF字体包含一个“STARTCHAR”开始的字符串并且其版本号的长度超过字符数组长度将会导致超过数组范围,将数据放在栈中的其他数据区上。这意味着攻击者可以覆盖内存从而控制处理器的命令指针离开bdfReadCharacters函数,从而有效的劫持程序。
因为X服务通常是以超级用户权限运行的,如果攻击成功,普通用户权限的用户可以通过执行代码来得到机器的控制权。关于在现今系统中存在保护机制情况下,如何触发栈溢出的更深层次的文章可以参考如下两篇文章
http://www.exploit-db.com/papers/24085/
http://crypto.stanford.edu/~blynn/rop/
修补漏洞很简单,如下图所示,明确指定数据长度为99个字节,第100个字节用来保存NULL。
来自X.org的声明:
在由X.org 发布的所有的X服务中,libXfont被用来读取用户指定的字体文件,包含Xorg服务,它通常是以root权限来运行的,
或者是以setuid-root的权限来运行以方便访问硬件,这一漏洞可能导致在某些系统中,一个普通用户拿到root权限。
在12月份的混沌通信大会上,Ilja van Sprundel 说他要在两个月内,挖到120个漏洞。Van Sprundel说:“现在我还没有挖到那么多”,Van Sprunde在2013年5月份导致了X.org的大量安全更新,包含数十个需要修正的漏洞,因为客户端程序库相信服务器发送的数据时有效的,没有进行完整性测试。(译注:http://lists.x.org/archives/xorg-devel/2013-May/036276.html)最新的漏洞是通过cppcheck静态分析工具发现的,命名为CVE-2013-6462,安全更新应该在所有的包管理中有效。(译注:有关cppcheck,请参照http://cppcheck.sourceforge.net/)
- tomcat源码编译和环境搭建(r5笔记第83天)
- NumPy 将停止支持 Python 2,这里有一份给数据科学家的 Python 3 使用指导
- Apache solr(一).
- dataguard中MRP无法启动的问题分析和解决(r5笔记第82天)
- Apache solr(二).
- Git 使用技巧
- 4.训练模型之准备训练数据
- 关于dg broker的简单配置(r5笔记第99天)
- 三天速成 TensorFlow课件分享
- 干货 | 机器学习算法线上部署方法
- 用于快速开发 3D 数据处理软件的开源数据处理库 —— Open3D | Github 项目推荐
- 【java网络】IO编程
- 一周 Github Trending 热门项目,最全中华古诗词数据库 | Github 项目推荐
- 【线程池】线程池与工作队列
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法