首页
社区
课程
招聘
对一篇反沙箱文章的分析学习小记
发表于: 2020-8-23 03:03 10688

对一篇反沙箱文章的分析学习小记

2020-8-23 03:03
10688

前段时间看到一篇McAfee关于反沙箱的文章,文中总结了一些病毒所用手段以及手段的进化史。链接如下:
f03K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2E0j5$3q4X3k6h3g2Q4x3X3g2U0L8$3#2Q4x3V1k6T1L8r3!0Y4M7#2)9J5c8X3!0@1K9r3g2J5i4K6u0V1j5X3I4G2k6%4y4Q4x3V1k6G2N6r3S2W2M7W2)9J5k6r3u0D9L8$3N6K6i4K6u0r3L8h3y4S2k6X3g2W2i4K6u0V1L8r3q4T1M7#2)9J5c8X3g2$3L8$3I4#2N6r3W2G2L8W2)9J5k6r3!0X3i4K6u0V1L8h3q4D9N6$3q4J5k6g2)9J5k6s2y4S2L8X3c8T1L8%4S2Q4x3X3c8W2N6X3q4K6K9h3!0F1i4K6u0V1N6r3q4U0N6r3W2U0M7#2)9J5k6r3q4Q4x3X3c8J5k6i4c8J5L8%4y4H3k6h3y4@1K9i4k6W2i4K6u0V1M7%4c8#2k6s2W2Q4x3V1j5`.
看完之后总觉得应该亲自去实践一下,一方面更深的了解其中的具体细节部分,另外也想锻炼下自己。所以才有了这篇小记,本次样本没有找全,主要涉及Delaying Execution(从两个方面,时间复杂度和API调用)两个样本,GetTickCount一个样本,API Flooding一个样本,CPU Temperature Check(没找到合适样本,有验证代码)。本次分析只涉及到了关键的反沙箱部分(包括定位到这部分代码和代码分析),能力有限,没有全面分析,算是浅析,大佬见谅。

对于这个样本,我的想法是通过导入函数VirtualAlloc/VirtualProtect入手试试,猜测有可能是解密病毒代码的时候造成的延时。

通过IDA对函数VirtualAlloc进行交叉引用,发现都是库代码进行了引用,所以放弃。再次尝试对函数VirtualProtect进行交叉引用,发现此处存在调用,紧接着再次对lpAddress进行交叉引用。

很幸运的是只有一处对lpAddress进行了赋值操作,不难发现此处是从地址0x4514e8向地址0x45B5F8进行了内存拷贝,字节数是0x491f。

到了这步,怎么办?我的想法是进行动态调试,通过在0x45b5f8下硬件写入断点找到对其进行更改的位置,因为我觉着程序应该会对这块内存进行重写。通过下断,找到了如下位置。

接下来就是需要好好分析这段代码了,那我自己是通过最终的赋值位置(mov [esi], eax)向上回溯两个寄存器值的来源,这样相比顺序分析快很多而且可以避免垃圾代码的干扰。

通过分析,这段代码是存在很多的垃圾代码的,其真正有用的代码只有短短的十行,如下:

紧接着就是通过引用查看这个函数在何处被引用,结果发现有两处对此进行了调用,而且两处又都是一个大循环。
第一处引用:

第二处引用:

其实不难发现,循环跳出的关键就在于[esp+0x10]中存的数是多少?通过动态调试可知其值为固定的0x911FB2(IDA中也有体现)。其实到这里,几乎可以确定这段就是超时代码了。

按照代码中的计算方式来说,一层循环0x3e次就已经完全可以了,将要解密的248字节数据按照四字节取出,分别加上(0x16024C0*2)之后在放回去即可,那这个病毒代码硬生生的将其嵌套了两层循环,实打实的增加了时间的复杂度完成延时操作。

这个样本前期的操作和上个样本类似,所以本次分析重点并不是他,而是他在内存中解出来的另外一个pe文件,我直接dump下来之后对其进行分析,样本会放到压缩包里。
这次我换了个思路,就是通过火绒剑先大概定位到超时的位置,之后再进行具体分析。

由于定位在未知模块,多半又是堆空间,结合导入函数VirtualAlloc的存在,就不多赘述了,在得到堆空间的地址之后,在超时偏移处先下个断点之后运行,在断下之后我并没有什么思路,毕竟完全不知道什么套路,所以我选择了单步步过,很幸运在单步几步之后看到了令我激动的函数WaitForMultipleObjects,本能觉得此处是关键处。

之后我的思路是,找到这个内核对象创建的地方,有两种方法,一是在这个栈地址下个硬件写入,二是直接在附近的函数调用中找一找,应该很快就可以找到,此处我选择第二种方法。

由图可知,进程创建了一个计时器对象,在经过一定时间的时候才能出发,这样就可以达到超时的目的。至此,等待的第一个对象解决了,那么等待的第二个内核对象是啥呢?通过一顿猛如虎的操作,最终我找到了其实是个事件对象,

从参数可以发现,这个事件对象在创建的时候被设置为手动激活,而且初始信号为无信号,但是通过在SetEvent函数下断点无果之后,我不得不到底有没有激活,再让我们回头看下函数WaitForMultipleObjects发现其中第三个参数为false,也就是等到其中任意一个对象即可,好吧。之后通过手动更改让其等待所有对象,结果。。没有结果,果然没有激活事件对象。

没啥说的直接火绒剑跑一下行为,结果就悲剧了:

打开并读取文件是在有明显超时时间之后执行的动作,所以红色框中的地址就是我准备入手的地方,但是突然就崩了是什么操作?先不管了,先找超时点吧。

通过之前几个样本的分析,所以我就直接顺着入手点所在的函数一路交叉带闪电向上回溯,此时我判断的标准也很简单,就是找有循环或者敏感api的调用,最后找到了几段类似如下的代码,此处只放一张作为实例。

可以看到这段代码的巧妙之处就在于,只有当GetTickCount返回指定值的时候才能够继续,这样在某种程度上说就达到了超时效果,而且这样的片段有好几个,有意思的是指定的返回值在经过简单的计算之后会被用来拼装成要获取的函数名称字串。

由于和本次的分析主题不是太相关就简单记录下了,通过从崩溃点入手,动态调试几次之后发现是在进行内存拷贝时候有个地址不存在导致的。

仔细看这个源地址是不是有点感觉像是申请出来的对空间,但是地址老感觉又不太对。。之后通过向上查找代码,发现确实是使用VirtualAllocEx申请得到,然后向这块内存拷贝了一段内嵌字节码用来解密,解密之后在把这段代码拷贝到内存0x46fa20处,从后面代码对这个解密之后的代码头部验证是否是0x5a4d就可以知道应该解出来的是个pe文件。那就看看他是如何解密的吧。

从上图可知,这个程序必须运行在2016年7月份才能解密正确,生而为人,我很抱歉!手动更改年份和月份之后运行正确。


[招生]系统0day安全-IOT设备漏洞挖掘(第6期)!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (3)
雪    币: 355
活跃值: (15)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
2
论坛上反沙箱的文章很少,学习
2020-8-23 09:07
0
雪    币: 299
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
还原一下沙箱代码啊 
2021-9-13 23:16
0
雪    币: 586
活跃值: (631)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
OopsIE Trojan应该有检测cpu温度的功能
36e66597a3ff808acf9b3ed9bc93a33a027678b1e262707682a2fd1de7731e23
055b7607848777634b2b17a5c51da7949829ff88084c3cb30bcb3e58aae5d8e9
6b240178eedba4ebc9f1c8b56bac02676ce896e609577f4fb64fa977d67c0761
9e8ec04e534db1e714159cc68891be454c2459f179ab1df27d7f89d2b6793b17
参考链接16eK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6#2L8X3W2@1y4o6u0Q4x3X3g2H3j5h3I4G2j5h3I4@1L8$3&6W2N6s2N6G2M7X3E0K6i4K6u0W2j5$3!0E0i4K6u0r3N6h3&6A6N6o6b7J5i4K6u0V1L8$3W2D9M7X3W2Y4i4K6u0V1N6r3q4J5k6$3g2@1M7#2)9J5k6r3#2A6k6r3c8D9k6g2)9J5k6r3g2S2M7%4c8W2M7X3&6Q4x3X3c8Y4L8%4k6W2M7X3&6E0k6h3&6@1i4K6u0V1j5h3c8V1M7#2)9J5k6r3g2$3j5i4y4A6L8$3&6Q4x3X3c8@1k6h3y4Z5L8X3W2I4N6h3g2K6i4K6u0V1L8$3!0H3M7$3W2W2i4K6u0r3
2022-6-8 18:20
0
游客
登录 | 注册 方可回帖
返回