接上文:
- 《深层次考察解释型语言身后隐藏的攻击面,Part 1(上)》
- 《深层次考察解释型语言身后隐藏的攻击面,Part 1(下)》
在本系列产品有关解释型语言最底层攻击面的第一篇论文中,大家认识到,即使在Javascript、Python和Perl等解释型语言的关键完成中,运行内存安全性也不是无懈的。
在这篇文章中,大家将愈发深入细致地讨论,在根据外界函数公式插口(Foreign Function Interface,FFI)将根据C/C 的库“黏合”到表述语言表达的历程中,网络安全问题是怎样发生的。正如大家以前所探讨的,FFI当做用这两种不一样语言撰写的编码中间的插口。例如,使一个根据C语言的库可用以Javascript程序流程。
FFI承担将计算机语言A的目标译成计算机语言B可以采用的物品,相反也是。为了更好地完成这类翻泽,开发者务必撰写特殊于语言表达API的编码,以完成二种语言中间的往返变换。这通常也被称作撰写语言表达关联。
从网络攻击的方面看来,外界语言表达关联意味着了一个有可能的攻击面。当解决一个从运行内存安全性文字翻译成运行内存不安全语言表达(如C/C )的FFI时,开发人员就会有很有可能引进运行内存网络安全问题。
即使高层住宅的语言表达被觉得是运行内存安全性的,与此同时总体目标外界编码也通过了严苛的安全性核查,可是,在二种语言中间搭起公路桥梁的编码中,仍很有可能潜伏着可使用的系统漏洞。
在这篇文章中,大家将细心科学研究2个那样的系统漏洞,大家将一步步地掌握网络攻击怎样分析你的编码的可运用性的。文中的目地是提升阅读者对exploit开发设计全过程的了解,而不仅是对于一个主要的实例,反而是从定义的方面来了解。根据掌握exploit开发者如何思考您的编码,帮您创建保护性的程序编写习惯性,进而编写出更可靠的编码。
在人们的案例研究中,大家将考察2个看上去十分类似的bug,殊不知只有一个是bug,而另一个则是一个网络安全问题。两者都存有于关联Node.js包的C/C 编码中。
node-sass
Node-sass是一个库,它将Node.js关联到LibSass(一款时髦的css样式表预CPUSass的C版本号)。尽管node-sass近期被弃用了,但它每星期仍有500万个以上的注册量,因此,它是一个特别有價值的财务审计目标。
当阅读文章node-sass关联时,大家注意到下列编码方式:
在[1]处,大家注意到一个可控于客户键入的32位整数金额值被用以内存分配。假如该客户带来的整数金额为-1,则整数算数关系式indent_len 1的值将变为0。在[2]处,初始负数用以建立由indent_len标识符构成的制表符或空格符字符串数组,在其中indent_len数值负,如今将成为一个非常大的恰逢,由于std::string构造方法期待接受无标记的长短主要参数,其类别为size_t。
在JS API等级,大家注意到indentWidth的查找方法以下所显示:
这里的目地是保证indentWidth >= 2或 <= 10,但其实这儿仅查验了上界,而且parseInt容许大家给予负数,例如:
这将开启一个整数金额外溢,进而造成分派的内存不够,并进一步造成后面的运行内存被毁坏。
为了更好地彻底解决这个问题,node-sass应当保证在将客户带来的indentWidth值传送给最底层关联以前,先查验该值的下界和上界。
全方位地查验键入,并确立地将他们的取值范围限定在对程序结构更有意义的范畴内,这将有效地协助您培养一种常用的保护性程序编写习惯性。
因此大家来总结一下。这儿的bug方式是啥?整数金额外溢,造成堆分派不够,之后的运行内存添充很有可能会毁坏邻近的堆内存。听起来的确非常值得分派CVE,不是吗?
殊不知,尽管这一整数金额外溢的确会造成堆内存分派不够,但这一bug并不意味着便是一个系统漏洞,由于这一css样式表键入很可能并不是网络攻击操纵的,而且在一切堆毁坏产生以前,都是会抛出去std::string出现异常。即使发生了堆毁坏,也就是一个十分不足的操纵遮盖(凭借一个特别大的indent_len的制表符或空格字符),因此,具体被充分利用的概率很低。
结果:仅仅一个bug。
那麼,什么情况网络攻击才会对如此的bug有兴趣呢?网络攻击可以对开启bug的键入环境要素。在这样的情况下,不大可能有些人为node-sass关联给予可控于网络攻击的键入。与此同时,运行内存毁坏原语自身的控制力也会十分比较有限。尽管的确存有那样的状况:即使是十分不足的堆毁坏也足够灵活运用某一缺点,但通常网络攻击会更善于寻找具备一些决策权的情况,例如可以操纵用以毁坏内存条的物品,或是可以操纵遮盖的运行内存总数。最好二者兼而有之。
在这样的情况下,即使std::string构造方法沒有撤出,网络攻击也需要用空格符或制表符开展大量的遮盖,以操纵过程。尽管这并不彻底不太可能,但考虑对周边运行内存合理布局的充足危害和操纵,概率依然稍低。
在这样的情况下,大家通常可以根据回应接下来的三个问题,来实现一个简便的可运用性“味觉检测”:
- 网络攻击是怎样开启这种bug的?
- 网络攻击操控了什么数据信息,操纵到啥子水平?
- 什么优化算法遭受网络攻击操纵的危害?
此外,可运用性关键在于网络攻击的总体目标、工作经验和資源。这种大家将会一无所知。除非是您花了许多時间具体撰写exploit,不然难以明确某一问题是不是可利用。尤其是当您的编码被第三方软件应用时,即您撰写的是库编码,或是是一个更大系统软件中的一个部件。在一个独立的条件中,某一不正确看上去仅仅bug,在更大的范畴内很有可能便是安全漏洞。
尽管基本常识针对明确可利用性有较大的协助,但在的时间和資源可以的情形下,一切可以由客户操纵(或危害)的键入开启的bug全是潜在性的安全漏洞,因而,将其视作安全漏洞是十分明智的作法。
png-img
针对咱们的第二个案例研究,大家将调查GHSL-2020-142。这一bug存有于给予libpng关联的node.js png-img包中。
当载入PNG图象做好处置时,png-img关联将应用PNGIMG::InitStorage函数来分派客户带来的PNG数据信息需要的原始运行内存。
在[1]处,大家留意到为一个尺寸为info_.height * info_.rowbytes的png_byte二维数组分派了相对的运行内存。在其中,结构体组员height和rowbytes的种类全是png_uint_32,这代表这儿的整数金额算数关系式肯定是无标记32位整数金额计算。
info_.height可以同时做为32位整数金额从PNG文件给予,info_.rowbytes还可以从PNG数据信息衍生。
这类乘法运算很有可能会开启整数金额外溢,造成data_运行内存地区分派不够。
例如,如果我们将info_.height设定为0x01000001,而info_.rowbytes的数值0x100,那麼产生的关系式将是(0x01000001 * 0x100) & 0xffffffff ,其数值为0x100。那样的话,data_将做为一个0x100尺寸的png_byte二维数组来释放内存,这显然不足用。
接着,在[2]处,将应用行数据信息表针添充rowPtrs_array,这种表针偏向所划分的运行内存区的界限以外,由于for循环标准是对初始的info_.height值开展使用的。
一旦具体的行数据信息被从PNG文件中载入,一切与data_地区邻近的运行内存都很有可能被网络攻击操纵的行数据信息遮盖,最大可达info_.height * info_.rowbytes字节数,这给一切不确定性的网络攻击给予了很多可控性的过程运行内存。
必须留意的是,依据网络攻击的意向,可以根据不从PNG自身给予充足数目的行数据信息来提早终止遮盖,这时libpng不正确方法便会运行。一切后面错误处理途径的程序结构都是会在被损坏的堆内存上运作。
这极有可能造成一个相对高度可控(不论是內容或是尺寸)的堆外溢系统漏洞,大家的判断力是,这一bug可能是一个可利用的安全漏洞。
下边,使我们来回应可利用性的问题,以明确这一bug是不是对网络攻击具备充分的诱惑力。
网络攻击是怎样开启该bug的?
这一bug是由网络攻击给予的PNG文件开启的。网络攻击可以良好控制在png-img关联中的作用于PNG的一切数据信息,并废止格式文件完整性检查所增加的一切限定。
由于网络攻击务必取决于载入的故意PNG文件,我们可以假定一切利用逻辑性都很有可能务必包括在这个单一的PNG文件中。这代表着,网络攻击与总体目标Node.js过程不断互动的机“很有可能”更少,例如,执行数据泄露,以协助后面的系统漏洞利用全过程绕开一切系统软件等级的改善对策,如详细地址空间规划动态随机(ASLR)。
大家说“很有可能”,是由于我们无法预测分析png-img的具体运用状况。也就是说,也有可能存有那样的运用状况:存有可反复的互动机遇,来开启该bug或进一步协助利用该bug。
网络攻击可以操纵什么数据信息,操纵到啥子水平?
网络攻击可以给予需要的height和rowbytes自变量,便于对整数金额计算和后面的整数金额封装形式(integer wrap)开展精细化操纵。被封口的值用以明确data_二维数组的最后释放内存的尺寸。他们还可以根据PNG图象自身给予彻底可控的行数据信息,这种数据信息根据rowPtrs二维数组中的越境表针值添充到越境运行内存中。她们可以根据提早停止给予的行数据信息,细致操纵这一网络攻击给予的行数据信息有多少被添充到运存中。
简单点来说,网络攻击可以根据细致操纵內容和长短来遮盖一切与data_邻近的堆内存。
什么优化算法会遭受网络攻击操纵的危害?
因为大家解决的是堆外溢,网络攻击的危害扩大到一切涉及到被损坏的堆内存的优化算法。这很有可能涉及到Node.js编译器编码、系统库代码,自然也有关联编码和一切有关库编码自身。
总结
在这篇文章中,大家将深层次地讨论,在根据外界函数公式插口(Foreign Function Interface,FFI)将根据C/C 的库“黏合”到表述语言表达的历程中,安全漏洞是怎样发生的。因为篇数太长,大家将分成数篇开展详细介绍,更多精彩內容,敬请关注!
文中翻譯自:https://securitylab.github.com/research/now-you-c-me-part-two