首页
社区
课程
招聘
[翻译]FlokiBot银行木马详细分析
发表于: 2017-3-25 21:18 6680

[翻译]FlokiBot银行木马详细分析

2017-3-25 21:18
6680


目录

介绍 

FlokiBot Dropper 

API调用去混淆 

FlokiBot Payload 

配置 

IDAPython完全静态去混淆 

挂钩API 

最后的笔记和哈希值 


介绍

FlokiBot 是最近一款针对于欧洲和巴西联邦共和国的银行木马,作为一款恶意软件工具集,它在一些黑客论坛上被卖到$1000。它通过垃圾邮件和渗透代码工具包来传播。虽说它是继承于ZeuS(宙斯),FlokiBot也做了很多有趣的改进。有诸如内存截取(RAM scraping),定制的dropper这样的新特性,还有似乎从泄露了源码的Carberp 那里借鉴了几行代码。

FlokiBot与其dropper都有很多常用或不常用的混淆技术,我们将解开它们的神秘面纱,并着重讨论如何使用IDAIDAPython脚本来静态脱壳。因为你们已经在最近很多恶意软件上接触过这些技术了,所以我觉得这是一次很好的锻炼。

在看完@hasherezade写的这篇关于FlokiBotdropper文章:https://blog.malwarebytes.com/threat-analysis/2016/11/floki-bot-and-the-stealthy-dropper/. 之后,我决定看一下FlokiBot。尽管大多数关于FlokiBot的文章都着重讲它的dropper,我还是想讲得更详细一些,然后再讲讲它的payload;我们将会看到它有很多有有趣的特性,而且不是你平常所看到的ZeuS不一样,虽然它的很多代码是来自ZeuSCarberp leaks。还是比逆向勒索软件好。

Hash值:

$ rahash2 -a md5,sha1,sha256 -qq floki_dropper.vir 37768af89b093b96ab7671456de894bc 5ae4f380324ce93243504092592c7b275420a338 4bdd8bbdab3021d1d8cc23c388db83f1673bdab44288fccae932660eb11aec2a $ rahash2 -a md5,sha1,sha256 -qq floki_payload32.vir da4ea4e44ea3bb65e254b02b2cbc67e8 e8542a465810ff1396a316d1c46e96e042bf4189 9f1d2d251f693787dfc0ba8e64907e204f3cf2c7320f66007106caac0424a1f3


对这个dropper的自动分析报告:

VirusTotal AnalysisHybrid-Analysis

FlokiBot Dropper

dropper通过比较经过哈希处理的库名与内置哈希值来加载模块。哈希进程用到了一个基础的CRC32,之后这个CRC32还要跟两个字节的密钥异或,那两个密钥随样本的不同而不同。

有两种方法来检索动态链接库(dll)库名:一是用 Process Environment Block  来检查InMemoryOrderModuleList 的结构并读取BaseDllName 的值来获取进程已经加载的dll。第二种方法是,通过在Windows系统文件夹中罗列库名。


下面的模块都被dropper导入了:

CRC Library Method ------------------------------------------------------ 84C06AAD ntdll.dll load_imports_peb 6AE6ABEF kernel32.dll load_imports_peb 2C2B3C88 948B9CAB C7F4511A wininet.dll load_imports_folder F734DCF8 ws2_32.dll load_imports_folder F16EE30D advapi32.dll load_imports_folder C8A18E35 shell32.dll load_imports_folder E20BF2CB shlwapi.dll load_imports_folder 1A50B19C secur32.dll load_imports_folder 630A1C77 crypt32.dll load_imports_folder 0248AE46 user32.dll load_imports_peb BD00960A 4FF44795 gdi32.dll load_imports_peb E069944C ole32.dll load_imports_folder CAAD3C25

之后,FlokiBot将采取同样的操作来定位和加载这些模块用到的API.首先,当CRC后的名字是匹配的,那么它将检索LdrGetProcedureAddress ntdll中的地址,并用它来获取其他API的句柄。这样做的话,函数的地址就仅对debugger可见。如此,分析代码将会非常困难,因我我们不知道调用了哪个API。去混淆的一种方法将在下一章提到。

FlokiBot与其dropper的另一有趣之处在于它们调用一些原生API函数的方式。这些函数位于ntdll中,并且以 Nt* 或者Zw*为前缀。它们在实现的时候与其他API有些许不同,因为它们要用到syscall特别是int 0x2e。下面的截图说明了它们是如何在ntdll中实现的。

正如我们所看到,系统调用的值放在eax(在我64Windows 7上,NtAllocateVirtualMemory 是在0x15 ),而且参数被传到edxx8664位的所有系统调用号(syscall number)都可以在这张网页找到:http://j00ru.vexillium.org/ntapi/.

在检查ntdll中的API时,FlokiBot会先检查函数的第一个操作码是否为 0xB8 MOV EAX, 若是,并且CRC后的API名也复合,它将提取MOV EAX 后面的四个字节,也就是系统调用号,并将它保存在dwSyscallArray 数组中。



在我的虚拟机上,当所有的系统调用号都被dropper提取后,dwSyscallArray 长这样。

Index API Syscall number ------------------------------------------------------- 0x0 NtCreateSection 0x47 0x1 NtMapViewOfSection 0x25 0x2 NtAllocateVirtualMemory 0x15 0x3 NtWriteVirtualMemory 0x37 0x4 NtProtectVirtualMemory 0x4D 0x5 NtResumeThread 0x4F 0x6 NtOpenProcess 0x23 0x7 NtDuplicateObject 0x39 0x8 NtUnmapViewOfSection 0x27

FlokiBot需要调用某个原生函数的时候,它将调用自身的一个函数,那个函数直接从dwSyscallArray 中检索系统调用号,传参,触发中断0x2E。这些都跟它在ntdll中的实现方式一样。这就是为什么你不会看到任何这些API调用的轨迹,而且专门用来钩住这些API的监测工具也监测不到有调用它们。

API调用去混淆

既然FlokiBotpayload用到了相同的函数和数据结构,你可以用“IDAPython完全静态去混淆”模块,稍稍修改IDAPython脚本就可以将dropperAPI调用去混淆。

FlokiBot的一个有趣之处就在于它的dropperpayload都有解除挂钩操作。思路是卸载检测工具,沙箱和杀毒软件中的钩子。尽管这并不是恶意软件第一次使用这样的功能,比如说,Carberp就有一个能 不让TrusteerRapport发现  的功能,还有最近的Carbanak ,但这样的功能能真的非常罕见,应该值得注意。在这一部分,我将描述FlokiBot是如何解除挂钩的。

首先,FlokiBot通过罗列System32文件夹中的dll来获得ntdll.dll的句柄,然后用我们上面所提到的哈希处理过程,最后调用 MapViewOfFile 来映射它在内存中的位置。结果就是,FlokiBot有两个库在内存中映射的版本:一个是在导入期间导入的,这个可能会被监测工具的钩子改变,另一个是它直接从磁盘中映射的,这个是干净的。


NTDLL
在磁盘中的映射——干净版本


dropper导入的NTDLL——可能被钩住


现在,设置了正确的权限,FlokiBot把映射干净DLL代码块的地址、导入的dll的地址入栈,然后调用解除挂钩操作。


因为它要重写它的内存里的一些数据以删除钩子,恶意软件需要改变导入的NTDLL代码导出段的内存保护机制。而它是通过用int 0x2E和之前提取的系统调用号(在我的windows版本是0x4D)调用NtProtectVirtualMemory 来做到的。我们可以看到如果某个钩子被发现,某一部分的代码就会变得可写。

解除挂钩函数可以描述为三步:对于NTDLL导出的每一个函数……

比较两个映射库的第一个操作码

如果它们不一致,说明导入的ntdll里的函数已经被钩住了。

改变导入的dll的内存保护机制,让它变成可写。

用从被映射到磁盘的dll复制来的操作码修补这个操作码。

解除挂钩操作的主要程序如下:



这样以来,很多监测工具、杀毒软件和沙箱都无法追踪恶意软件的调用。这个非常有用,如果你想要避免来自像 malwr.com. 这些网上沙箱的自动分析。

它的dropper3个明确命名的资源: keybot32  bot64 BotRtlCompressBuffer()  LZNT1 压缩,然后用有16字节密钥的RC4加密它。在我的样本里,密钥是:

你可以从Talos 团队的Github https://github.com/vrtadmin/flokibot. 中找到可以备份这个payload和配置文件的Python脚本。要注意的是,它们并不能自己正确运行,因为它们要注入一个进程,还需要一些被dropper在内存中改写的数据。我们会在下一部分详谈注入进程。

提取资源的常用方法:

dropper并不是用常用的用NtMapViewOfSection NtWriteVirtualMemory来将payload注入到explorer.exe (或者svchost.exe如果失败的话) 。它是用写并运行一个可以在进程内存中解密解压payloadshellcode来完成的。这很不常见,很有趣。dropping的过程可以用下面的图片来总结:

dropperexplorer.exe / svchost.exe 里写一个trampoline shellcode 和它自己的一个函数。

当运行时,trampoline就会调用那个函数。

函数自动运行,并且动态解决导入、读取dropper的资源,并将它们提取到自己的进程内存中。(比如,在explorer.exe / svchost.exe 的地址空间里)

最后,dropper在目标进程中运行bot payload的入口点(entrypoint)。

第一个写在explorer.exe shellcode(称为trampoline )会休眠100ms,然后调用一个函数,那个函数dropper在进程内存中映射在0x80000000 ,在该dropper中默认称为 sub_405E18 。这第二个阶段是要提取bot payload,解密并解压它们。所有这些都发生在explorer.exe / svchost.exe  内存中。

$ rasm2 -a x86 -b 32 -D '558BEC51C745FCFF10B4766864000000FF55FCC745FC000008006800000900FF55FC83C4048BE55DC3'

0x00000000   1                       55  push ebp

0x00000001   2                     8bec  mov ebp, esp

0x00000003   1                       51  push ecx

0x00000004   7           c745fcff10b476  mov dword [ebp - 4], 0x76b410ff ; address of sleep()

0x0000000b   5               6864000000  push 0x64

0x00000010   3                   ff55fc  call dword [ebp - 4] ; sleep()

0x00000013   7           c745fc00000800  mov dword [ebp - 4], 0x80000

0x0000001a   5               6800000900  push 0x90000

0x0000001f   3                   ff55fc  call dword [ebp - 4] ; sub_405E18, 2nd stage 0x00000022   3                   83c404  add esp, 4

0x00000025   2                     8be5  mov esp, ebp

0x00000027   1                       5d  pop ebp

0x00000028   1                       c3  ret


sub_405E18 将通过与dropperpayload相同的进程来导入它需要的资源,用有些许不用的crc32和新的异或密钥。


前两个哈希值,0x6AE6AF84  0x84C06EC6 应该是 'kernel32.dll''ntdll.dll'。我用Python来实现哈希过程,证实导入的那两个DLL确实是kernel32 ntdll,然后我修改我的Python程序去解析它的导出表,想要知道函数导入的API的名字。我运行程序得到下面的API


用这些函数,进程中的代码将可以读取dropper的资源(botRC4密钥)并且映射payload在内存中的位置。最后,远处终止的线程内容将会被修改,这样它的EIP将指向第一个shellcode,该线程继续。


这个payload 是基于熟知并已经分析过的ZeuS木马,所以我不会每件事都详细描述。至于dropper,我会更着重讲去混淆部分以及FlokiBot改进部分的实现。

配置

我运行 Talos 团队发布的  ConfigDump.py 程序,然后得到下面的C&C :


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 1
支持
分享
最新回复 (4)
雪    币: 34
活跃值: (864)
能力值: ( LV12,RANK:380 )
在线值:
发帖
回帖
粉丝
2
我尽力了,可是还是没排好版式。
2017-3-25 21:20
0
雪    币: 26205
活跃值: (63302)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
3
lumou 我尽力了,可是还是没排好版式。
辛苦,排版过程中,感觉哪点不太好?我们再改进
2017-3-25 22:02
0
雪    币: 34
活跃值: (864)
能力值: ( LV12,RANK:380 )
在线值:
发帖
回帖
粉丝
4
Editor 辛苦,排版过程中,感觉哪点不太好?我们再改进
从我个人来说,我本身对于排版不太在行,所以在写的时候是用缩进的方式对齐表格的,所以最后必然是东西都缩在一起了。然后关于我们论坛的:1.我在复制粘贴的过程中发现,因为我今天弄了几次,第一次的时候是用全屏,它没有出现滚动条,而且每次粘贴后都会跳回首行,第二次的时候,如果直接粘贴代码,格式不对,用“粘贴纯文字”粘贴的话,格式没问题,但又跳到末行。2.不知道能否像原文里的那样,代码如果比较长的话,用滚动条的形式展现。
2017-3-25 23:22
0
雪    币: 7850
活跃值: (2313)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
lz辛苦了,谢谢分享
2017-3-30 09:06
0
游客
登录 | 注册 方可回帖
返回
//