前言
菊哥某日给我发了一个样本,告诉我这个冲锋马写的非常牛逼,都被提交三年了在VT上竟然依然是全绿,让帮忙分析一下是咋搞的。
看了一下VT的提交时间是 2019年,重新提交分析一下,竟然依然是全绿;
我现在有点怀疑这个样本是不是真的是黑的了,然后又跟菊花哥确认了一下,就是它。不得不说杀软很无奈,你知道杀软这三年都是怎么过的么?下面开始一点一点解开它的神秘面纱。
样本特征分析
首先看一下样本图标和属性信息,
VS_VERSION_INFO.StringFileInfo.040904b0.CompanyName:Tencent
VS_VERSION_INFO.StringFileInfo.040904b0.FileDescription:QQ浏览器
VS_VERSION_INFO.StringFileInfo.040904b0.FileVersion:10.3.2816.400
VS_VERSION_INFO.StringFileInfo.040904b0.InternalName:bug_report_exe
VS_VERSION_INFO.StringFileInfo.040904b0.LegalCopyright:Copyright 2018 Tencent. All rights reserved.
VS_VERSION_INFO.StringFileInfo.040904b0.OriginalFilename:BugReport.exe
VS_VERSION_INFO.StringFileInfo.040904b0.ProductName:QQ浏览器
VS_VERSION_INFO.StringFileInfo.040904b0.ProductVersion:10.3.2816.400
VS_VERSION_INFO.StringFileInfo.040904b0.CompanyShortName:Tencent
VS_VERSION_INFO.StringFileInfo.040904b0.ProductShortName:QQ浏览器
VS_VERSION_INFO.StringFileInfo.040904b0.LastChange:713bc9f76cb50125fdd45c5a1681158adfff5709
VS_VERSION_INFO.StringFileInfo.040904b0.Official Build:1
VS_VERSION_INFO.StringFileInfo.040904b0.SpecialBuild:1023
VS_VERSION_INFO.StringFileInfo.040904b0.CipVer:10016
VS_VERSION_INFO.StringFileInfo.040904b0.UrlVer:1
VS_VERSION_INFO.VarFileInfo.Translation:04b00409
一看图标和伪造的版本资源信息,这个是个钓鱼马无疑了,这里看到它伪造的是 QQ浏览器的 BugReport.exe
的 10.3.2816.400
版本;
看一下字符串信息,还真的就是QQ浏览器的字符串。
这让我怀疑它是不是直接拿QQ浏览器的 BugReport.exe
直接二进制patch的,于是赶紧从网上找了一个对应版本的原程序进行了一下对比,原程序的hash在文末提供;
先用010editor来对比一下;
可以看到除了 .rsrc section的大小不一样之外,其他的都是一样的,.rsrc大小不一样也可以理解,毕竟图标被替换了。
我们知道恶意代码肯定是存在.text中,着重比对一下 .text section的差异,我最开始是用ida看了一下 winmain函数,发现竟然一摸一样。
面对几千个函数我陷入了沉思,我怎么知道哪个函数被修改成恶意的了?
这里首先想到使用bindiff看一下,发现存在不少函数是不一致的,而且由于bindiff的算法问题,他是基于最高相似度进行函数匹配的,并不是基于相同地址进行匹配的;
很多不匹配的,还有匹配错误的,也就是说这个bindiff也并不能帮我定位出来哪里代码被修改了。
不过我的需求也简单,只要找出来哪些地址的代码被修改了,定位出来区间,然后做一个小的容错,就可以了,下面是最终的结果:
[
('0x421dcf', '0x421e89'), ->长度: 184
('0x425679', '0x4264f6'), ->长度: 3707
('0x4589f4', '0x459ac6') ->长度: 4306
]
可以看到,这三个区间的代码被修改过,接下里在这三个区间的起始地址都打上断点,开启一波调试分析;
调试分析
很快就在第一个断点段下来了;
我们跟踪一下调用栈;
是从winmain函数中调用过去的;
很明显这个恶意代码编写者是patch了原程序WinMain调用的一个函数的代码,然后从这里作为恶意代码的执行入口,后续再内存中布局其他的恶意代码,来依次调用达到隐藏的目的
简单的看了一下这个函数的代码,发现被加入了很多垃圾代码;
这种垃圾代码后续会不停的出现,不过是比较小儿科的垃圾代码,所有的分支都不会进入,这里直接忽略就好了,关键是下面的那个call,跟进去之后会发现我们进入了第二段被修改的代码区间 0x425679;
又是一大堆的垃圾代码,跳过一大堆没有用的,可以看到这个函数一直再不停的调用函数 0x0042604E
根据经验可以知道,此函数的功能是 getprocessaddr_by_hash ;随后将此函数获取的所偶有函数地址都标记上符号方便静态观察;
继续调试,发现会把所有获取的地址存放再一个数组中;
接下里还用说吗?赶紧把这些函数打上断点呀。
看到这里大头基本上已经分析的差不多,下面展示一些细节;
反沙箱
继续分析会看到一个明显的反沙箱操作;之前再历史文章中也总结过过这种方法;
创建一个线程 sleep 83s,然后使用waitForSingleObject等待这个线程返回,等待时间是80s,如果没有超时说明sleep函数被加速了,那就是沙箱。
反调试
反调试还是利用waitForSingleObject , 等待线程的返回;不过这次是等待0s,如果没返回 v38就加一;
只有的等v38 > 0x26000 的时候才会执行恶意代码;
如果是单步调试的话,v38可能不会大于 0x26000; 同时这里也是一个对系统性能的判断,如果性能比较差也不会>0x26000.
c2地址
继续更跟踪会发现IP地址解码函数;
继续跟踪发现使用的User-Agent;
最后找到请求的url地址:
https://39.xx.xx.xx:443/kumoko/wakaba.bmp
总结
此二进制用的技术方法;
- 直接patch原始二进制,保留原文件的字符串、统计特征、资源等,防止被杀软识别
- 时间流速反沙箱
- 反调试
- 垃圾代码、虚假控制流混淆视听
- 独立编写的shellcode,防止被识别
- 混淆比较小儿科,分析起来比较简单
参考
- 被修改文件:e20d0311a9e436c08ecb72c349903b22