xiaoxiaoY520 发表于 2024-9-11 16:52

一个远控木马加载器的逻辑分析

本人不是干这行的,抽摸鱼时间断断续续分析的,用word文档记录,写完才发现图片压缩了,糊的一批,复制过来更糊了,凑合看吧。该样本是在7月份发现的,当时测试发现还可以过火绒的扫描,运行起来也没有告警(8月底看最新的更新已经可以检测出来了,火绒的反应还是非常快的{:1_921:}),当时没时间,找工具人测了一下,如图:


微步检测:


该样本只是个加载器,本身中并没有微步分析出的恶意行为,恶意行为来源于本身解密出的dll和去网络上分多次下载的dll。由于篇幅原因加上dll暂未分析完(只是个运维马喽,技术不行也没时间,只能抽摸鱼时间分析),本文只分析该样本本身行为,dll行为日后补充。附上部分分析时打的断点:


基本信息:
HASH
SHA256:eb68f2bd6be604b01ac589880b37087f4b1ae0cea4bb081c96bbed55329279c0
MD5:3a8e47bba9fd671a2588903493f85f9e
SHA1:3c7165b29855ac83c45424b63deeb957d618b1eb
通信IP:206.238.197.107www.yydsyoyo.com端口:8888

通信流量:


没定位到落地文件,应该是直接从缓冲区加载进内存的,从数据包中提取出该dll查看导出表可以基本确定是个远控木马了,下载的dll名字为install.pg.dll:




该样本执行后会将本身重命名后写入到public/download下,首次名字为RLOJNg.exe,以后如果再次运行,它会以其他随机名字写入,文件日期可以发现是修改过的(这个日期有意思)。


最后会启动ROLJNg来接替自己并删除自身,删除自身用了点小技巧,并未调用删除文件的api,而是使用TerminateProcess无条件强制退出程序来间接删除自身文件。从进程来看其下载了一个dll文件,第一阶段只是解密并加载install.dat的dll文件。


PE文件中删除了调试信息,符号表异常,因此函数功能基本无法识别。






代码分析:

由于断断续续的分析,x64dbg很容易跑飞的BUG,其中涉及到动态调试的地方可能有地址上下衔接不上,这是由于多次运行申请堆内存随机导致的,程序步骤没有问题,如有错误还望大佬指正。
主程序逻辑:获取系统版本信息后开始执行,因为在sub_406AE7中最终会跳进dll执行后强制退出,所以整个WinMain不会全部执行完。




获取版本号信息myGetSubSysVersion部分主要代码:创建0x18字节缓冲区,获取NtQueryInformationProcess的地址并调用,从获取的0x18字节中获取到peb基址,然后经过偏移找到版本信息:






得到结果:


关键的代码中使用了很多迷惑性的重复代码逻辑来增加分析复杂度(也可能是迷惑安全软件的检查,不排除有其他用处,毕竟它换名字“ROLJNg.exe”换路径重新执行了,在之后重启阶段的动作暂未分析,待分析后补充。目前阶段可视为无用代码),实际是无用的。重复代码中使用字符转数字来计算出一个大大超出屏幕的坐标值,最终为GetPointWindowText和SetWindowRgn来服务,但是这两个api由于故意传递违规参数实际执行都是无效的(传入坐标大大超出了屏幕范围),与实际要执行的恶意代码也无关联。




可以看到执行后缓冲区没有任何变化:


密文地址在pe的固定4112DB位置,格式为01+大小+pe密文(该样本很多地方都是这种格式的数据组成结构):


F5的类C代码可以更直观的看到中间确实有很多的无用代码干扰分析,实际功能之间跨度很大:




在复制密文的逻辑中,前段也用了重复的老套路来干扰,即GetPointWindowText:


干扰代码中创建计时器验证时间这一段着实没想明白目的是什么,实际动态调试好像也没有什么实际效果:


动态调试也可以印证密文确实就是在4112DB处:




获取密文后再次复制一份并调用解密函数进行解密:






解密函数分析:获取字符串后进入解密逻辑:


MyDecrypt逻辑:

获取加密服务:




获取字符串(解密获得advapi32.dll字符串)并截取,&$分隔:




解密字符串算法:

获取密文长度后获取需要异或的参数并循环遍历进行解密,异或参数来源于4316AC数据的计算:




异或解密:




接下来就是获取该dll的地址,该程序并没使用Loadlibrary来获取,而是自己编写代码使用了比较通用的一种方式:从peb的ldr中去遍历模块,取出模块名字并跟解密的字符串进行比较,找到后获取其基址,即dll的句柄了。






接着用上述异或老套路,解密出“CryptAcquireContextA”字符串:


自己实现的代码查找模块导出表,遍历导出表找到函数地址,这个函数在后面会多次用到,包括最后加载解密的pe后跳进去执行,详细解析主要代码:






在调用CryptAcquireContextA获取加密服务时也用了点技巧,除api需要的五个参数外压入了api的VA,并使用retn跳转过去执行以获取加密服务:




然后是导入密钥,密钥来源于三个数据的合并,格式一如既往(01+长度+数据):




经过一大段无意义的代码后开始导入密钥,导入密钥函数中同样使用异或解密密文获得字符串advapi32.dll、kernel32.dll、LoadLibraryA、CryptImportKey、GetProcAddress,然后经过ldr遍历获取地址,最后入栈retn执行,至此获取了加密服务并导入了密钥:




解密dll:将密文拼接,复制两份,最后结构即重复两次的密文:




开始解密pe数据(dll):


分析该解密的内部逻辑:先固定地址获取密文后截取字符串,然后进行解密该字符串,解出字符串”advapi32.dll”,这种简短的字符串解密过程上文已说明,都是同一种解法。




接着加载该advapi32.dll,加载方式如下:
这个函数有两种字符串解密,一种为kernel32.dll,一种是当前走的分支即LoadLibraryA,因为当前已经有了kernel32.dll的绝对地址,所以跳过了开始的解密kernel32.dll字符串并寻址kernel32.dll。




再然后就是通过GetFuncVAFromPE解析pe导出表直接获取到LoadLibraryA的地址,这种方式上述也有讲。


调用LoadLibraryA的方式使用的非正常方式:压栈上面获取到的LoadLibraryA的VA后ret进系统领空执行,至此advapi32.dll就在没有显式调用LoadlibraryA的情况下加载了。




下面就是从加载的advapi32.dll中找到函数CryptDecrypt并调用进行解密(获取字符串、解密出字符串CryptDecrypt、获取该函数的VA,然后压栈rtn调用CryptDecrypt进行解密)。





解密完成后数据结构为01+长度(明文+密文)+明文+密文


然后就涉及到通过不同的方式多次将解密的pe在内存中多次换位置:




分析该PE文件,从PE装载基址来看基本是dll无疑了。接下来的函数也确实是非显式的加载该dll。


分析加载dll逻辑:
加载函数


根据PE文件加载基址进行偏移量寻址,找到characteristics属性值,与2做与运算判断是否是可执行文件。


通过peb中ldr查找kernel32.dll地址,逻辑如下:从PEB中找到LDR的地址,然后遍历循环链表,找到dll名字,通过逐字节计算出最终值后与特定值对比,若相等则获取dll基址并返回。


计算的算法已用python复现相同逻辑,由此也可以爆破出这个算法确实是在找kernel32.dll的基址,0x6A4ABC5B是该dll名计算的值。


通过获取的kernel32.dll基址,从导出表中找出函数功能地址VirtualAllocEx和VirtualFreeEx,这两个函数在将dll数据手动映射到内存时会用到(非显式的调用):


内容太多,这边挑主要的讲:遍历节表,计算大小确保数据大小一致性:




以获取到的VirtualAllocEx函数地址去调用api申请前面获取到的VirtualSize大小内存,即开辟dll内存实际大小的空间。然后将dll头部映射进该内存


根据偏移量去查找每个节的地址和大小,然后将节数据写进内存,循环进行,即可将dll每个节的数据手动映射进内存。


以上步骤之后即手动加载了该dll文件,此时还需修复重定位数据。根据偏移定位到重定位表并进行修复:








加载并解析导入表,这边图表太大,就用f5的伪代码凑合看吧,附上主要解析块的注释:






获取dll入口点,从头部获取Characteristics值并判断了一下是否是dll文件,然后调用了一次DllMain,至此,该dll算是成功加载上了。


中间经过一堆没什么意义的操作后开始获取导出函数"ds15_6e1v5ew9_74y"的地址,可以发现它巧妙地用了坐标变量去存储关键的数据:




再次经过一堆无意义代码后跳转进"ds15_6e1v5ew9_74y"执行:




这个dll提取出来可以看到导出函数确实只有一个,从导出表字段中可以看到该dll的实际名字为install.dat。






至此,该pe本身的工作就算完成了,剩余工作交给加载的dll中ds15_6e1v5ew9_74y函数。

xiaoxiaoY520 发表于 2024-9-11 17:35

本帖最后由 xiaoxiaoY520 于 2024-9-11 21:36 编辑

最后插的图片附件直接忽视了,这个编辑器整不会了,编辑跟看到的对不上,编辑排版也是乱的,改了几次改不动了,凑合看吧{:1_901:}。有人知道这是咋回事嘛,文件多了好像就跳,当成ddos禁了?

Hmily 发表于 2024-9-29 17:03

xiaoxiaoY520 发表于 2024-9-11 17:35
最后插的图片附件直接忽视了,这个编辑器整不会了,编辑跟看到的对不上,编辑排版也是乱的,改了几次改不动 ...
491是请求太频繁了,可能确实和图片太多有关系,我给你编辑换了行,应该比之前好一些。

不过图片感觉太多导致文章太长,建议精简一下内容,图片保留核心关键内容更好一些,目前图片清晰度也不好。

shitoumail 发表于 2024-9-11 17:01

多长时间才能研究明白这么长的内容啊,{:1_921:}

xiaoxiaoY520 发表于 2024-9-11 17:08

shitoumail 发表于 2024-9-11 17:01
多长时间才能研究明白这么长的内容啊,

运维马喽没事干断断续续摸了两个多月了,不知道为啥排完版发出来就乱的:(eew

zk3926 发表于 2024-9-11 17:43

厉害了大佬,两个月的成果!

justwz 发表于 2024-9-11 20:31

跟着大佬学逆向

新时代 发表于 2024-9-11 21:02

点赞研究研究

silver1ight 发表于 2024-9-12 01:21

点赞学习

注册个id 发表于 2024-9-12 08:02

内容多, 排版确实有点乱

DAYS77 发表于 2024-9-12 09:46

页: [1] 2 3 4
查看完整版本: 一个远控木马加载器的逻辑分析