前言
菊哥某日给我发了一个样本,告诉我这个冲锋马写的非常牛逼,都被提交三年了在VT上竟然依然是全绿,让帮忙分析一下是咋搞的。
样本特征分析
首先看一下样本图标和属性信息
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
-
c++元编程混淆: https://t.zsxq.com/18uscKY7U
-
时间流速反沙箱方法:https://t.zsxq.com/18OTtZlIb
安全的矛与盾
我们的知识星球”安全的矛与盾”是一个既讲攻击也讲防御,开放的、前沿的安全技术分享社区。在这里你不仅可以学习到最新的攻击方法与逃避检测的技术,也可以学到最全面的安全防御体系,了解入侵检测、攻击防护系统的原理与实践。站在攻与防不同的视角看问题,提高自己对安全的理解和深度,做到: 知攻、知守、知进退;有矛、有盾、有安全。
更多的干货内容,更深入的技术交流,尽在知识星球“安全的矛与盾”,欢迎大家扫码加入!有问题请咨询微信 Manliness_man
原文始发于微信公众号(安全的矛与盾):三年了,还是VT全绿,它到底凭什么?