远程控制,C&C服务器,混淆
0x00 前言
黑月是一个把易语言程序小型化,脱离支持库运行的工具。
文件的基本信息如下:
文件名称 | bca11af3fb5437be2c8ce4fae6230836+0aa6f9f75c8e329ae23b3118bcfbf71018fe3a1a_bca11af3fb5437be2c8ce4fae6230836.vir |
MD5 | bca11af3fb5437be2c8ce4fae6230836 |
SHA-128 | 0aa6f9f75c8e329ae23b3118bcfbf71018fe3a1a |
SHA-256 | d44e73f421132ef7a39c219988821cb4e44fe8dbde5e8d0acbf8cd6a9a156d3d |
0x01 初步观察和信息的收集
1.1人为执行分析
该样本伪装成日历的样子诱导用户点击,图形如下:
直接在虚拟机运行发现,无明显的操作行为,通过ProcessMonito发现文件在C:\Users\admin\AppData\Roaming\Micorsoft\Winows\Start Menu\Programs\Startup(程序开机启动路)创建了一个文件后退出。
1.2沙箱检测
VT查询:
初步信息总结:
反检测,有网络连接,有键盘钩子,包含洋葱地址:
http://m3r7ifpzkdix4rf5.onion/kpanel/connect.php,和窃取密码信息的行为。
洋葱网络:洋葱网络是一种在计算机网络上进行匿名通信的技术。通信数据先进行多层加密然后在由若干个被称为洋葱路由器组成的通信线路上被传送。每个洋葱路由器去掉一个加密层,以此得到下一条路由信息,然后将数据继续发往下一个洋葱路由器,不断重复,直到数据到达目的地。这就防止了那些知道数据发送端以及接收端的中间人窃得数据内容
0x02 正式分析
2.1查询壳信息
通过exeinfo查看样本信息发现是一个带upx壳的32位样本。
通过oep法,脱壳后用插件修复导入表。
脱壳前数据:609KB
脱壳后数据大小:1.33MB
样本的整体行为流程图如下:
2.2第一层脱壳后的样本
先静态分析,先观察字符串和导入函数窗口看看是否有特别有用的信息
字符串没有看到特别有用的信息
数据的前面是一些混淆的数据,动静结合去分析,找到关键的解密数据
2.3第二层shellcode1
把数据dump分析,大小如图:
第一层shellcode1执行流程:
1)先获取函数或dll的地址:
kernel32.dll、GlobalAlloc、GetLastError、Sleep、VirtualAlloc、CreateToolhelp32Snapshot、Module32First、CloseHandle
2)通过获取到的函数进行系统遍历
3) 对申请内存后对shellcode进行解密
2.4第三层shellcode2
第一层shellcode1传入第二层shellcode2的数据
第二层shellcode2对数据,进行解密后,跳转到第三层
2.5第四层shellcode3
继续进行解密后,跳转到全新的exe中
2.6第五层last.exe
通过winbdg,把数据dump下来,主函数功能如下图所示:
2.6.1隐秘解析ntdll.dll
为了防止被一些软件检测到,程序从自己的代码中直接调用底层函数,不使用代理ntdll.dll,通过从ntdll.dll中获取到系统调用编号,并通过名称哈希值来识别这些函数。
函数名称哈希表如下:
Ntdll.dll文件操作执行流程如下:
1.获取ntdll.dll导出表到内存中
2.创建堆空间,获取ntdll.dll模块基地址
3.ExpandEnvironmentStringsW转换环境变量为路径:
L"C:\Windows\system32\ntdll.dll"
4.打开ntdll模块,获取大小,读取到申请的堆空间
5.通过哈希值识别,并导入函数
6.校验是否正确读取文件
7.拷贝PE头部信息,节区体等信息到VirtualAllocEx申请的内存中,并修复重定位表。
8.判断ntdll.dll是否存在导出表不存在释放空间
获取ntdll路径:
收集当前程序及环境信息
1.加载ntdll.dll模块,调用RtlGetVersion获取OS版本信息
2.判断当前程序是否以管理员权限启动
3.DeviceIoControl获取当前磁盘信息
4.将环境变量%APPDATA% 和%WINDIR%\System32 转换为路径字符串
a)L"C:\Windows\System32"
b)L"C:\Users\XXX\AppData\Roamin"
2.6.2从C&C服务器中获取配置文件
last.exe可以从C&C服务中下周带有data_injectd的配置文件,配置文件与last.exe路径相同。机器人向C&C服务器发送信标,其中包括:
1.配置文件的哈希
2.CoCreateGuid()生成GUID,代表唯一标识符
2.6.3提权、遍历进程和尝试进程注入
提权函数IDA查看无调用,猜测通过相对偏移调用。
检查权限:
遍历进程:
2.6.4防守检测
last.exe1通过前面获取到NtQuerySystemInformation获取系统信息,它却为我们提供了丰富的系统信息,同时还包括对通过PEB 遍历模块链表,检测是否存志指定的模块信息。以下是这个函数的原型:
然后遍历系统进程,扫描到vm的相关进程后退出,设置标志defensive_checks=1.
判断防守标志后退出程序
2.6.5初始化和创建远控程序VNC
在Github上发现初始化VNC远程软件的源码与我所分析的样本大体相同
VNC远控软件的初始化,直接连接网络,创建服务
GitHub上的源码: 样本源码:
VNC通过RFB协议建立链接
github源码地址:
2.6.7窃取键盘消息
last.exe可以在自身进程中运行一个键盘记录器的线程,键盘记录器安装键盘钩子
回调函数收集进程名称、窗口标题的文件以及挂钩窗口中键盘输入的内容,最后通过主线程C&C服务器传输回去
2.6.8复制自身到开机启动项和持久化
把自身复制到开机启动项中,并重新命名为bac58a5f.exe
静态查看:
动态调试:
持久化:调用函数instal_bot_in_registry_and_AppData
执行流程如下:
1.%APPDATA%\Microsoft\{GUID 字符串}\bac58a5f.exe
2.\REGISTRY\USER\SID 字符串\SOFTWARE\Microsoft\Windows\CurrentVersion
3.Software\Microsoft\Windows\CurrentVersion\Run
4. Wow6432Node\Microsoft\Windows\CurrentVersion\Run
2.6.9窃取浏览器和outlook用户数据
last.exe通过VNC远程发包,在本地解析包数据,通过一个大的switch——case执行不同吗的命令,执行命令如下图:
使用以下流程抓取filefox的数据:
1. last.exe通过访问%s\\Mozilla\\Firefox\\profiles.ini中的路径来获取profile文件的路径,该路径包含包含了用户信息
2. 然后它从注册表中获取了filefox安装路径加载了nss3.dll
3. 通过nss3.dll,解析用户数据
获取firefox配置文件路径:
获取注册表中的库路径:
加载nss3.dll库,解密数据:
多路径查找outlook的配置文件数据:
注册表路径 |
HKEY_CURRENT_USER\Software\Microsoft\Windows Messaging Subsystem\Profiles\9375CFF0413111d3B88A00104B2A6676 |
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676 |
HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676 |
HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676 |
收集以下注册表的值:
SMTP Server 、IMAP Server、POP3 Server、email、IMAP Passwords、SMTP Passwords、POP3 Passwords等收集到的数据然后由CryptUnprotectData()解密。
调用另外的远控软件或hellworld.exe
3.IOC
MD5
MD5 | 文件大小 |
6F8B0451B7DEA07B423650E0B8C7094C | 444938 bytes |
B4CD27F2B37665F51EB9FE685EC1D373 | 3584 bytes |
URL
获取方式 | URL |
字符串解析 | https://api.ipify.org/ |
字符串解析 | http://ylnfkeznzg7o4xjf.onion/kpanel/connect.php |
内存中解析 | 194.109.206.212 |
内存中解析 | 154.35.175.225 |
内存中解析 | 199.58.81.140 |
内存中解析 | 193.23.244.244 |
内存中解析 | 128.31.0.34 |
内存中解析 | 131.188.40.189 |
内存中解析 | 171.25.193.9 |
内存中解析 | 204.79.197.219 |
内存中解析 | 192.23.244.244 |
0x03 结论
具提供的信息表明这是一个远控木马,跟某商业木马Kronos具有相同的起源,功能并不新颖,但精巧的方式(ntdll的调用)还是值得学习的,该代码被很好地混淆了,并且还使用了各种技巧,这些技巧需要了解操作系统的一些低级工作原理。
0x04 附录
**dump****一些问题的说明:**
在第四层shllcode3进入第五层last.exe1,这时候从内存中dump数据的PE会出现一些问题,需要换一个时间去dump,直接跑起来,进程退出之前,在任务管理器中去完整的dump,最后通过windbg去修复导入表、入口点。经过多工具反复dump具体出现的问题如下:数据数据缺失会造成IDA分析的数据不准确,以下图为例:
正确的dump流程可以通过视频连接查看视频:
https://www.aliyundrive.com/s/1EmXJRadWBJ
windbg工具:
https://www.aliyundrive.com/s/f4nkB9MQwri
关于last.exe调式入口点和PE入口点不同的问题:
调试入口开始运行last.exe,您将在下面找到一些提示。
函数的第一个块负责填充注入模块的导入表。如果我们想从那个点开始运行样本,而不是在注入时跟随它,有一些重要的事情需要注意。首先,加载器应该在注入的可执行文件中填充一些变量,即变量module_base。其他函数会引用这个,因此,如果它不包含有效值,则示例将崩溃。此外,填充导入的函数需要*.rdata*部分(包含要填充的块),设置为可写。在注入样本的情况下,它将被设置为可写,因为那时,完整的 PE 被映射到具有 RWX(读-写-执行)访问权限的内存区域中。然而,在正常情况下——当样本从磁盘运行时——它不是。这就是为什么,为了通过这个阶段,我们需要手动更改对该部分的访问权限。
另一种选择是从主函数的下一个块开始运行last.exe示例。这也导致成功执行,因为如果样本是从磁盘运行而不是注入,则导入由 windows 加载程序填充,手动执行只是多余的。
调试入口:
PE入口点:
- 本文作者: 初学者
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/1412
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!