百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

因漏洞修补触发的漏洞—CVE-2016-6309漏洞详细分析

bigegpt 2024-08-10 12:06 15 浏览

作者:梁瘦叟

预估稿费:500RMB(不服你也来投稿啊!)

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿

前言


openssl发布了一个安全级别为”严重”的UAF漏洞,该漏洞利用简单,只需要发一个tcp包就能触发漏洞,但后果严重,可能导致TLS相关的应用拒绝服务,甚至任意代码执行等后果。唯一的限制是该漏洞影响范围较小,仅影响1.1.0a版本的openssl,而该版本的openssl发布时间比较晚,实际使用的并不多。笔者对此次漏洞进行了一次详细分析,同时通过漏洞分析分享笔者关于安全的一些思考。

漏洞重现


此次漏洞仅影响版本为1.1.0.a的openssl,下面让我们一起来一步步重现此次漏洞。漏洞测试的系统为Ubuntu。如果不熟悉linux的朋友建议安装一个虚拟机进行测试。

第一步首先我们从github上下载源码并编译:

12345wget "https://github.com/openssl/openssl/archive/OpenSSL_1_1_0a.tar.gz"tar -xf OpenSSL_1_1_0a.tar.gzcd openssl-OpenSSL_1_1_0a./config --debugmake -j4

如果编译成功,可以在apps目录下看到openssl执行程序。

在这里我们为了不影响系统原有的openssl,不执行 sudo make install命令,因此需要把生成的动态库文件libssl.so和libcrypto.so放到系统库目录下。

12sudo cp ./libssl.so.1.1 /usr/local/libsudo cp ./libcrypto.so.1.1 /usr/local/lib

生成一张测试证书

1./openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 –nodes

运行该命令后openssl会询问一些关于证书的相关信息,无视掉,直接一路enter就好了。

使用openssl的s_server子命令搭建SSL服务器,监听20443端口

1./openssl s_server -key key.pem -cert cert.pem -accept 20443 –www

使用nc向openssl的本地20443端口发送异常的ssl握手包

1nc localhost 20443 < send_content

openssl收到这一畸形的握手包后bang的一声down掉了!怎么样,利用是不是很简单呢?

send_content地址:

https://pan.baidu.com/s/1eRXpmgU

基础知识


接下来我们要对漏洞产生的原因和如何构造一个漏洞测试数据包进行学习,但是让我们首先来学习一些关于SSL的基础知识。

在漏洞重现中我们搭建了一个ssl服务器,下面我们打开wireshark进行抓包,捕获此次的SSL通信过程。在wireshark中设置过滤条件:tcp.port=20443,避免显示太多无用的通信包。

使用firefox与openssl的ssl服务器进行通信。在firefox的地址栏输入:

1https://localhost:20443

此时firefox会提示你该网址不安全,不用理会这一提示,这是因为证书是我们为了测试生成的,不在firefox的可信根证书列表中。依次点击Advanced->Add Exception->Confirm Security Exception,确认安全例外网址https://localhost:20443。

这时回到wireshark的界面,可以看到wireshark已经抓到了本次ssl通信的数据包。

SSL通信的过程是这样的,首先客户端和服务器端经过三次握手建立TCP连接,然后客户端发送的第一个数据包通常被称为“client hello“,意思就是说client想要和server进行通信,首先要向服务器端say一下hello,这个hello包中包括了客户端需要交换的随机数,支持的加密算法等内容,但和本次漏洞相关的是SSL包的长度,就是图中标红的两个length,512和508,标明了SSL数据段的长度,正是因为openssl对长度的处理不当导致了此次漏洞。

漏洞分析


目前,openssl已经发布了漏洞补丁,我们先来看看补丁(这里):

123456789101112131415161718192021222324252627282930+static int grow_init_buf(SSL *s, size_t size) {++ size_t msg_offset = (char *)s->init_msg - s->init_buf->data;++ if (!BUF_MEM_grow_clean(s->init_buf, (int)size))+ return 0;++ if (size < msg_offset)+ return 0;++ s->init_msg = s->init_buf->data + msg_offset;++ return 1;+}+ /* * This function implements the sub-state machine when the message flow is in * MSG_FLOW_READING. The valid sub-states and transitions are:@@ -545,9 +560,8 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) /* dtls_get_message already did this */ if (!SSL_IS_DTLS(s) && s->s3->tmp.message_size > 0- && !BUF_MEM_grow_clean(s->init_buf,- (int)s->s3->tmp.message_size- + SSL3_HM_HEADER_LENGTH)) {+ && !grow_init_buf(s, s->s3->tmp.message_size+ + SSL3_HM_HEADER_LENGTH)) { ssl3_send_(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); SSLerr(SSL_F_READ_STATE_MACHINE, ERR_R_BUF_LIB); return SUB_STATE_ERROR;

上面以-开始的行意味着从源码中删除,以+号开始的意味着向源码中增加。

分析一下该补丁,补丁为BUF_MEM_grow_clean函数的调用增加了一层封装grow_init_buf。

接下来我们用GDB来实际调试一下:

1gdb –args ./openssl s_server -key key.pem -cert cert.pem -accept 20443 –www

在补丁对应的行上下断点:

1

b statem.c:546

朋友们可以手动跟一下函数运行的流程。对比一下正常的TLS握手包和畸形的TLS握手包对于openssl的运行流程有什么区别。

引发漏洞的根源在BUF_MEM_grow_clean函数中,该函数位于源码crypto/buffer/buffer.c文件中,我们来重点分析一下这个函数的流程。

在BUF_MEM_grow_clean函数中,有两个入参,第一个是openssl分配的结构,用于记录为此次clienthello包分配的内存的相关信息,第二个入参是数据包的长度,而这一长度是从我们传入的数据包中获得的,这也就意味着该参数是攻击者可控的。以下是BUF_MEM_grow_clean的代码。

12345678910111213141516171819202122232425262728293031323334353637size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len){ char *ret; size_t n; if (str->length >= len) { if (str->data != NULL) memset(&str->data[len], 0, str->length - len); str->length = len; return (len); } if (str->max >= len) { memset(&str->data[str->length], 0, len - str->length); str->length = len; return (len); } /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ if (len > LIMIT_BEFORE_EXPANSION) { BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE); return 0; } n = (len + 3) / 3 * 4; if ((str->flags & BUF_MEM_FLAG_SECURE)) ret = sec_alloc_realloc(str, n); else ret = OPENSSL_clear_realloc(str->data, str->max, n); if (ret == NULL) { BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE); len = 0; } else { str->data = ret; str->max = n; memset(&str->data[str->length], 0, len - str->length); str->length = len; } return (len);}

通过使用GDB跟踪openssl对畸形TLS数据包的处理,该TLS握手包的的长度段的值必须同时不满足代码1,代码2,代码3的判断并进入代码4处。即漏洞被触发需要同时满足str->length < len,str->max < len,len < LIMIT_BEFORE_EXPANSION,三个条件。

其中str->length也是由攻击者传入的,

str->max和LIMIT_BEFORE_EXPANSION都是固定的。

str->max的值为21684(0x54b4)

LIMIT_BEFORE_EXPANSION的值定义在/crypto/buffer/buffer.c:19

#define LIMIT_BEFORE_EXPANSION 0x5ffffffc。

满足这三个条件后函数进入代码4处,使用realloc函数重新分配一块内存,而导致原先的str->data指针被free掉,成为野指针,而程序其他地方继续使用这一指针,就导致了Use After Free。

至此为止,漏洞的原理搞清楚了,那么如何构造畸形的TLS握手包呢?

首先使用wireshark导出正常的TLS握手包,将包头中的两个长度段分别改为0x4000, 0x5560。并在包尾填充相应长度的字符。很简单,是不是?

漏洞溯源


俗话说,”冤有头,债有主”,那么这次漏洞是如何出生的呢?openssl使用的代码管理工具是git,我们能够在github看到过往的历史提交记录,让我们来查查此次漏洞到底是如何产生的。根据上面的分析,我们知道漏洞是在statem.c文件中。经过一番搜索,最后找到这段代码的修改记录:

https://github.com/openssl/openssl/commit/c1ef7c971d0bbf117c3c80f65b5875e2e7b024b1#diff-03303953dad8b2c06464ec69a7414859

查看页面中的修改说明,openssl给TLS包分配内存的时机太早,如果有恶意攻击者发送大量恶意TLS包,可能导致openssl分配大量内存而导致拒绝服务漏洞。注意看说明结尾,此次漏洞是由360团队的shilei向openssl报告的,openssl开发团队收到这一漏洞报告后对相关文件进行了修改,并最终导致了此次拒绝服务攻击。总结起来就是360的一位安全研究员shi lei向openssl报告了CVE-2016-6307拒绝服务攻击漏洞,openssl对此进行了修改,并导致了CVE-2016-6309漏洞。

通过这一漏洞的分析,以下是笔者一些不成熟的关于软件安全的想法,请大家指正:

1.尽量不要让你的代码太复杂。我认为软件开发人员在修复一个bug的时候引入一个新bug的原因在于软件的复杂度已经超过了开发人员的驾驭能力。对于开发人员而言,太过复杂的代码容易出bug,这是常识。但是因为业务的各种变更,项目进度需要,历史原因等种种实际情况,很容易出现极其复杂的代码,并产生安全漏洞。因此,开发人员如果有多一些时间的话,希望能思考一下,你手头上正在开发或维护的代码,能否在不影响业务的基础上降低复杂度。

2.在给漏洞打补丁的同时,也可能产生新的漏洞。安全研究人员在挖掘漏洞的时候,可以试着从软件的补丁上考虑。

相关推荐

5分钟调色大片的方法(5分钟调色大片的方法有哪些)

哈喽大家好。在大家印象中一定觉得ps非常难学非常难。大家不要着急,小编的教学都是针对ps零基础的同学的,而且非常实用哦。只要大家跟着图文练习一两遍,保证大家立马学会~!好了,废话少说,下面开始我们今天...

闪白特效原来是这么用的(闪白特效怎么使用)

作者|高艳侠订阅|010-86092062闪白特效是影视作品中应用比较多的效果之一,那么具体该在哪些场景使用闪白特效?具体该如何操作?下面就以AdobePremiere(以下简称PR)为例,...

ppt常用小图标去哪里找?3个矢量素材网站推荐!

ppt是一个注重可视化表达的演示载体,除了高清图片,ppt中另一类常用的素材是各种小图标,也叫矢量图标,巧妙运用小图标能提升整体美观度和表现力,那么ppt常用小图标去哪里找呢?为方便各位快速找到合适的...

有什么好用的截图录屏工具?试试这9款

经常有朋友反馈苦于缺乏截屏和录屏的趁手工具,本期我们分享几个相当好用的截屏和录屏工具,希望能帮到大家。ScreenToGifScreenToGif是一款免费且开源的录屏工具。此款工具最大的特点是可以...

配色苦手福音!专业快速色环配色PS插件

今天橘子老师给的大家介绍的是一款快速配色的插件,非常强大配色苦手福音来啦!(获取方式见文末)【插件介绍】配色在后期设计中占有主导地位,好的配色能让作品更加抢眼Coolorus这款专业的配色插件,能够...

如何用PS抠主体?(ps怎么抠主体)

1.主体法抠图-抠花苞和花梗导入一张荷花苞的照片,点击上图中顶部“选择”菜单栏,下拉单击“主体”。可以看到,只有花苞被选中,但是花梗并没有被选中。接下来单击上图中左侧工具栏的“快速选择工具”,上图中顶...

2799元的4K电视,有保障吗?(买4k电视机哪个品牌好)

在上一期《电脑报》的3·15专题报道中,我们揭露了一款不靠谱的42英寸4K智能电视——TCLD42A561U。这款售价2699元的4K智能电视不仅4K画质方面存在严重问题,而且各种功能和应用体验也不理...

苹果电脑的Touch Bar推出一段时间了 这款工具可以帮你开发适用于它的APP

距离苹果推出带有TouchBar的MacBookPro已经有一段时间了,除了那些像Adobe、Google和Microsoft大公司在开发适用于TouchBar的应用之外,其实还有很多独立的开...

如魔法般吸取颜色的桌灯(如魔法般吸取颜色的桌灯叫什么)

色彩为生活带来的感官刺激,逐渐被视为理所当然。一盏桌灯运用它的神奇力量,将隐藏于物件中的颜色逐一释放,成为装点环境的空间魔法师。ColorUp是一款可以改变颜色的吸色台灯,沿用传统灯泡的造型,融入了拾...

一篇文章带你用jquery mobile设计颜色拾取器

【一、项目背景】现实生活中,我们经常会遇到配色的问题,这个时候去百度一下RGB表。而RGB表只提供相对于的颜色的RGB值而没有可以验证的模块。我们可以通过jquerymobile去设计颜色的拾取器...

ps拾色器快捷键是什么?(ps2019拾色器快捷键)

ps拾色器快捷键是什么?文章末尾有获取方式,按照以下步骤就能自动获得!学会制作PS特效需要一定程度的耐心和毅力。初学者可以从基本的工具和技术开始学习,逐渐提高他们的技能水平。同时,观看更多优秀的特效作...

免费开源的 Windows 截图录屏工具,支持 OCR 识别和滚动截图等

功能很强大、安装很小巧的免费截图、录屏工具,提供很多使用的工具来帮我么能解决问题,推荐给大家。关于ShareXShareX是一款免费的windows工具,起初是一个小巧的截图工具,经过多年的迭...

入门到精通系列PS教程:第13篇 · 拾色器、颜色问题说明及补充

入门到精通系列PS教程:第13篇·拾色器、颜色问题说明及补充作者|侯潇问题说明我的第12篇教程里,有个小问题没有说清楚。要说是错误,又不算是错误,只是没有说准确。写完那篇教程后,因为已经到了深...

PS冷知识:用吸管工具吸取屏幕上的任意颜色

今天,我们给大家介绍PS中的一个冷知识:用吸管工具可以吸取屏幕上的任意颜色。其实,操作起来是非常简单的。大多数情况下,我们认为,PS的吸管工具只能吸取PS软件作图区域范围内的颜色,最多加上画布四周的...

Windows 11 将提供内置颜色选择器工具

Windows11内置了颜色选择器,可以扫描并识别屏幕上的颜色并生成颜色代码。此外,微软还利用人工智能技术,让屏幕上的文本扫描和选择变得更加便捷。这两项功能均已在SnippingToolv1...