PECMD的解包
新脚本
F12检查到一个管道,别的虽然也挺令人在意,但还没有什么实际能看出来的。
老规矩,先断LoadResource。
堆栈跟踪到sub_472E88
调试的时候跑飞了,没想到这样本还怪好的,还提醒我反反调试没做好:


其中msdge拥有一个有效的数字签名,查询发现是一款杀软,看这形式猜测是用了这个杀软的某个漏洞提权,并且数字签名免杀。
本来是杀软,却被病毒用来提权,实在有点感慨。当然,这还只是猜测,还得继续验证

翻找temp目录总能有新的发现,比如这个7z带密码的压缩包:

发现和前面的几个文件相对应,看来这就是要提取的文件了。
检查日志,查看是否有遗漏的目标:

自身不滞留在后台,是好消息。

谁家写入分块分512的?不过有个好处:必定存在一个超大的循环,单步肯定跑不完的那种

可能是作者后门(纯猜测),检查到这个文件/文件夹后不执行病毒之类的。
在上述排查中,和逆向分析得到的结果一样,只发现那三个文件(或者说,一个7z文件)
那么现在的首要任务:
-
获取文件数据
-
解密文件数据
-
获取7z压缩包密码
根据日志里面一堆的readfile和writefile,只要断这两个准没错,必断到加密算法中间。
00473C70:首次尝试直接读入7z文件
00474A45:读入失败后,创建新的空白7z文件

00473C70命中第三次的时候7z文件完成全部写入。
中断插入,得到断点为00474DEF时完成第一部分。
检查到sub_43362F是一个非常复杂的分支系统




PECMD脚本语言。
PECMD 命令帮助 - PECMD技术社区: www.pecmd.net
[[原创]2023-05-20更新--进程管理器-PECMD脚本作品展示-PECMD技术社区

参考了一下,果然是一个成熟的体系。程序里面大量使用的脚本非常奇怪,现在看到,也正常了。

再次检查,发现脚本资源下有一个可能是PE文件,但头部似乎多出了一些内容。
尝试提取检查。

只是简单的删除头部的字节,无法被识别为PE文件,IMHEX尝试使用PE结构解析时直接崩溃。

再次翻看,发现里面的内容也和其他正常软件不同,没有大片的空白。
0043EDCD:调用解密函数
004481A9:解密函数断点触发处
00448346:调用了一个看似完整的解密循环,看起来像是解密流程函数。
这里始终没找到v7怎么传递的,去找了一下thiscall的资料


通过ecx传递,看看ecx。


有指针,指针正常赋值到函数内
看看原调用:


v7在经过定义后就没有进行过任何赋值,直接传入thiscall里面

在thiscall内部,也就简单清理了一下数据区域就拿来用了,那这些函数是什么时候初始化的呢?
挠头起来了
尝试断一下v7的定义函数开头


断上了,但是栈空间太短,要么是dbg识别错误,要么就有点问题在里面了。
再检查一下ida那边,发现ida自动省略了一个栈空间申请函数,哦?这就有点意味在里面了。




过了那个所谓的栈空间申请函数以后,栈里面居然跳不到esp了,push还在正常执行?这也太奇怪了点吧。

sub_414F82:疑似加载资源附带解密资源
sub_4410C9:疑似判断资源类型是否需要解密
esp和ebp-d470无法访问的问题的答案:dbg版本太老了

换一个dbg解决问题
ecx不是指针,无法跳转的问题:系统内存申请问题


结构体赋值是在SUB_43E92E

sub_4355F6疑似主流程函数

尝试跟踪:this的最初值


上答案了

好简洁的代码。
Resource_TypeCheck_4410C9:资源检查,是否加密,这部分相同,返回的v5做什么的我暂时没搞明白,只是和他一样返回了,感觉可能是标志位。


我的报错点就在C8这里,但是学长的代码直接跳过了C8

另一个地方也一样,难道说。。。。


好吧,还是继续看学长的代码好了
Decode_MainProc:对应的是sub_43ED73,流程代码。不过外面还有一层sub_414F82,main函数代替之了。
sub_448188:主要解密函数
原程序并没有文件写出(或不在流程内),在学长的解密程序额外添加了文件写出以进行后续分析
大概思路是在中途退出之前进行一次写出,或者是在解密过程中逐渐写出。

C8的意义不明。
来点总结。



取得key和资源检查,DWORD类型,仅低3.5字节有效(DWORD共4字节),读入后一个小异或固定数字0x5AA59669u(这里居然用到了4字节)



这里的curb是指针指向的字节的意思。
4~6存储的是关键词CMPx(4 5 6 那其实只能匹配三个字节)
7存储的是flag 9720 658 120==4,是key的异或值。 flag最低位是flag是否有效,flag低第2位是key1是否有效。(实际上就是判断key1是否为0,这个位置没啥用)
8~12(0x10)存储的是key1
key的部分解析完成,接下来是文件。

别说这部分跑一遍才发现真是挺巧妙的。
v9一开始是空白的,先取一个byte的数据确定要跑多少次
sub_448188的作用是取下一个byte的数据,这里涉及到解密和指针自动右移一位。
第一次取到的是8次(一个byte8位最高了),那么本次,以及后续7次, 一共8次。
因为小端序的原因,v9 = result | 0xFF00;其实会填充v9的第二个字节为FF,第一个字节为result。
如果清空了FF,那么就是文件没读完,会再读一遍长度,也就是8个8个字节一组。
如果清空FF之前,就先碰到了result的0,那么说明该break了。
另外注意,8个8个字节一组,但是每个字节头需要一个FF用来标识长度,所以是9个字节一组
然后buf的起点并非从v1(pcn->DecodeB)开始,而是从v1 + v2(4078) + 12开始,以及每个文件片(在这部分中,还不能确定这部分一定是纯粹的文件内容。)最大可以达到0xFFF的长度,可谓也是非常小了。
每次写入0x1000的数据,基本算是一段,没确定下一段是否会去使用上一段的数据进行重复,不过这也不重要了。
然后一般sub_448188只会返回一个BYTE的数据,读到最后的时候会返回一个INT32的-1,遇到-1就可以终止了。

因此结构体如上。
编了个程序把其他的样本都扒下来了。

103号是通用的7z解压缩本体。


多出来的102号是一个不知道干啥的资源配置文件。

奇怪,那我之前找到的加密压缩包呢?

资源里面没有其他可用的东西了。
找找别的:

哦吼?你的意思是又放文件末尾了?
IMHex又出bug了,服了,还是换回稳定的010editor好了,工具果然还是得稳定一点。


试着截取此大小,然后修改文件头。
比对哈希

哈希比对成功,这个压缩包是被【原样】保存在exe里面的,不是资源。文件末尾有压缩包头。
先附上结论图

第一步:跳转到内容为004E的地方,比对内容是否正确。(固定从文件尾的偏移:十进制160)
第二步:跳转到内容为23313531的地方(固定偏移177),读取是否是##包括的数字。
第三步:跳转偏移 -160-177 获取到压缩文件尾部。
第四步:【未知压缩文件大小来源】跳转到压缩文件头部。 但是由截获的压缩文件可知大小为0x906A2F(缺少这步将会导致无法实现自动化。)
第五步:【未知比对目标】比对一个目标是否是cab格式,如果是,则获取到的压缩包头部替换为cab文件头,否则替换为7z文件头。

第四步和第五步的【未知】是因为在导出的脚本根本没有填充这部分内容,因此有可能是在exe后赋值的。
第六步:运行解压命令【解压密码为rfhujhfud4656575】(截图里面前面的-p不是密码)


另注:随便开了个别的样本,密码不一样。

但是结构是一样的,也没给压缩包长度(变量名不一样是因为我上面自己分析的时候修改了变量名)



浙公网安备 33010602011771号