之前都是调试flash的漏洞,相关的样本接触较少,碰巧看到一篇不错的分析,尝试了一下,留个记录。
调试flasher样本一般建议使用调试版的flash player,在调试版本下可以输出swf文件运行时的相关日志,便于进行相关的分析,安装之后会在家目录(C:User<your name>mm.cfg)生成该文件(早期的flash调试版本不会生成该文件,需要手动生成)。
文件中包含以下配置选项,手动生成的话红色框中的选项为必选项,用于告诉flash生成错误日志及trace日志(对应的日志文件保存在C:Users<your name>AppDataRoamingMacromediaFlash PlayerLogs目录下)。
该样本在运行之后含有多层解密(以下以此分析)。
Sample1
通过JPEXS反编译之后,该样本只有两个主要的类
- Base64 传统的base64算法
- MainTimeline 样本的功能类
MainTimeline的入口函数frame1中首先对组合出第一个请求地址,当请求结束,调用TteNDbdn函数。
通过trace可以获取该请求的地址
请求之后会报错,因为该cc已经失效,好处是该样本通信的过程记录在fiddler的包中,我们将这次请求的页面保存到本地,在fiddler中设置对这两个地址的自动回复,回复的文件使用本地保存好的两个页面。
http://zaleimneviskivgorlo.website/crossdomain.xml
http://zaleimneviskivgorlo.website/XVsiAHhqXHV1TT8nPEB_Tgc.xml
此时再运行该样本,trace记录如下,输出的地址如下:
现在回到样本的分析,对应请求完成后启用函数TteNDbdn,该函数会解析其中返回的xml文件,获取两个参数,并完成解密,之后解密的内容通过addChlid函数加载起来,这个地方很容易就明白该解密的内容应该就是接下来的运行样本。
该xml及对应的两个变量如下:
这个地方可能会想到通过trace的方式直接打印出该解密内容,通过上面给出的代码是不行的,因为此处的_loc4_并不是一个普通的变量或常量,其类型为一个对象。
为了获取第二层的样本,可以通过python脚本手动解密该xml文件中包含的sample2,这个地方注意读取的时候不要使用python中的ET.ElmentTree的方式去读取,至少我在通过该方式读取的数值解密之后,JPEXS无法反编译。
可以使用以下代码:
解密之后为标准的swf文件格式。
Sample2
反编译之后的主方法如下所示:其中比较重要的有yYJREHXgUy,和TPbsJhbquQh
首先是函数yYJREHXgUy,运行之后实际上是将字符串”G5GH……..”直接附加到exec之后,并以LoaderContext的类型返回,这时很容易想到该返回的结果有可能是作为一个参数。
然后是函数TPbsJhbquQh,该函数会调用dMbRyCRIPq进行实际的解密,这个地方的param1,_loc3_值得关注。
通过trace直接获取这两个参数的数值。
对应的值如下,可以看到这两个参数分别为一个长的加密序列content,和一个秘钥key:4d07059cb79e3545dcf7f0cf5bc33baa。
可以发现加密序列content实际就是sample2中的二进制数据文件。
使用之前的脚本即可解密出sample3。
Sample3
通过JPEXS对该样本进行反编译,如下图所示,可以看到相比于前两个样本该样本中有多个类。
加载运行该swf文件,程序报错,错误出现在class_7中。
直接查看class_7,其代码会检测exec之后的参数是否为空,而之前直接加载sample3并不是通过样本直接运行的,所以没有传送参数,因此报错。
此时直接修改函数,把相关的校验部分去掉之后,替换成右侧的代码,可以看到最后会调用到class_1.init()函数
函数class_1.init中首先会检测当前版本是否小于19.207,只有小于该版本才往后执行,函数之后值得关注的有asfsgrggvxyb,_loc_4,及extLoaded函数
从以上的代码可以得知,_loc4_应该是一个json文件,如下图所示通过trace函数直接获取该参数。
不出所料,此处为一个json文件,在json中的vari42即为对应漏洞利用代码(此处为了便于显示将vari42的值简略了)
之后解析好的json内容会被赋值给变量§_-q§,然后获取其中的vari42域,即json中的加密字符串,作为class_11.method72的参数,实际上,该函数只是简单的base64解码操作,同样通过trace获取该解密的结果。
运行样本,可以看到输出的结果如下,一个标准的swf文件,这个就是漏洞利用的swf文件了。
由于之前已经获取了对应的json文件,这里直接通过pyton脚本做一下处理就能获取对应的漏洞利用代码。
如下图所示,CVE-2015-7645漏洞的利用代码,该漏洞为一个writeExternal对象的类型混淆漏洞。
回到之前的init函数,漏洞利用函数解密加载之后,会调用exloaded函数,如下图所示:
此时该类下的EXP_try通过JPEXS反编译的效果并不好,可以尝试换AS3 Sorcerer(as3有多个反编译工具,可以交替使用,JPEXS的好处在于打trace很方便)。
进入class_4.EXP_try函数,在该函数中会调用到Load函数。
在load中完成shellcode的解码,最后通过_safe_Str_10类的函数exec执行shellcode,此处的shellcode除了解密出来的部分外还包括asfsgrggvxvb中返回的数值(该值来之于sample2中作为sample3的启动参数)。
进入exec函数可以看到flash中经典的获取virtualprotect函数地址,分配可以执行内存,并执行shellcode的操作。
在以下两图中通过修改jit字节码,将对应的shellcode替换成一系列的CC中断指令。
运行之后可以看到,flash player在windgb中确实中断下来了。
编写loader
此时可以通过修改sample3的部分代码,实现仅仅通过一个html页面加载该样本的功能,这个地方主要需要注意的是shellcode的问题,通过上面的分析可以发现,最终sample3漏洞触发之后使用到的shellcode来自两部分。
- 来自sample2启动sample3时传入的参数exec
- load中硬编码的shellcode2
传入的exec参数会在asfsgrggvavb中进行处理,通过分析我们知道该函数仅仅是将传入的数值附加到”exec”之后,该功能可以在html页面中直接实现,因此通过修改字节码直接将该函数的功能去掉,以方便在html中增加我们的shellcode接口。
我们的shellcode通过html传入,因此直接把sample3中load中硬编码的shellcode2删除。
通过一个html加载运行。
之后点击之后直接运行。
总流程
整个kit的运行过程如下所示:
参考
http://vulnerablespace.blogspot.co.uk/2016/04/malware-analysing-and-repurposing.html