基于CMD勒索脚本混淆分析



在这篇博文中,我们将分析 YourCyanide,它是基于 CMD 的勒索软件系列的最新变体,始于 GonnaCope。YourCyanide 是一种复杂的勒索软件,它集成了 PasteBin、Discord 和 Microsoft 文档链接,作为其payload下载的一部分。YourCyanide 包含多层混淆,并利用自定义环境变量和启用延迟扩展功能来隐藏其活动。作为其规避策略的一部分,YourCyanide 还将通过不同的文件,通过 Discord 和 Pastebin 下载后续文件,然后最终下载主要有效负载。
使用vscode打开混淆脚本后,可以看到该代码为批处理脚本,同时为多处混淆内容。
enter description here
这些环境变量,因为这些值周围有两个%的百分比符号,比如%jVElq:~20,1%。
enter description here
接下来是设定值,这些基本上是数字值将从其索引并根据值返回字符或字符串的字母,从jVElq设置变量来看。
enter description here
打开cmd窗口,复制粘贴jVElq的变量,然后使用echo再去打印“%jVElq:~20,1%”,打印的结果为e。
enter description here
在vscode中按住ctrl+F使用查找并点击下图红框的按钮进行正则匹配“%jVElq:~[0-9]+,[0-9]+%”,可以看到进行模糊匹配关于jVElq环境变量。
enter description here
那么接下来写个脚本进行手工解密,用来理解混淆的思路,在vscode上新建一个文本文档,定义jVElq的字符串的值,定义obfuscation_cmd为YourCyanide.txt的第七行的值,为混淆的代码。

1
2
3
4
import re
jVElq="yxlpdqajizrusokhbmnwefgctv"
obfuscation_cmd ="@%jVElq:~20,1%%jVElq:~23,1%%jVElq:~15,1%%jVElq:~13,1% %jVElq:~13,1%%jVElq:~21,1%%jVElq:~21,1%"
#定义obfuscation_cmd

定义obfuscation_code的值 使用正则匹配 “ %jVElq:~[0-9]+,[0-9]+% ” 如obfuscation_cmd的%jVElq:~20,1%等,同时将这些值放入新的列表中obfuscation_list。

1
2
3
4
5
6
obfuscation_list1=[]
obfuscation_code1 = re.finditer(r"%jVElq:~[0-9]+",obfuscation_cmd)
for match in obfuscation_code1:
obfuscation_list1.append(match.group())
#定义obfuscation_code1变量 使用正则匹配 “ %jVElq:~[0-9]+ ” 如obfuscation_cmd的%jVElq:~20%等。
print (obfuscation_list1)

打印obfuscation_list1如下图红框。
enter description here
接着定义obfuscation_Sequence的值 ,使用正则匹配 jVElq 的序列匹配obfuscation_cmd 的数字,注释上面的obfuscation_list的代码,最后打印Sequence_list的列表。

1
2
3
4
5
6
obfuscation_Sequence= re.finditer(r"\d+",str(obfuscation_list1)) 
Sequence_list=[]
for match2 in obfuscation_Sequence:
Sequence_list.append(jVElq[int(match2.group())])
print (Sequence_list)
#定义obfuscation_Sequence的值 ,使用正则匹配 jVElq 的序列匹配obfuscation_cmd 的数字。

打印出obfuscation_list的列表的值拼接起来就是echo off。
enter description here
再次定义obfuscation_code2变量 使用正则匹配 “ %jVElq:~[0-9]+,[0-9]+% ” 如obfuscation_cmd的%jVElq:~20,1%等。

1
2
3
4
5
eobfuscation_list2=[]
obfuscation_code2 = re.finditer(r"%jVElq:~[0-9]+,[0-9]+%",obfuscation_cmd)
for match in obfuscation_code2:
obfuscation_list2.append(match.group())
#定义obfuscation_code2变量 使用正则匹配 “ %jVElq:~[0-9]+,[0-9]+% ” 如obfuscation_cmd的%jVElq:~20,1%等。

接下来去定义一个字典,将输出的对应的索引值与jVElq的值进行做成一个字典,注释掉上一个“print (Sequence_list)”,最后打印字典。

1
2
3
4
5
6
7
dic={}
#dic 给一个空的字典
for i in range(len(obfuscation_list2)):
dic_old = {obfuscation_list2[i]:Sequence_list[i]}
#定义dic_old 添加{obfuscation_list2:Sequence_list }成为字典
dic.update(dic_old)
print (dic)

打印出相对应的字典,同时可以看到去掉了一些重复的字符内容,如下图红框中的内容。
enter description here
最后进行将dic字典对应的字母与混淆的代码替换,然后重组打印,同样也是注释上面的“print (dic)”。

1
2
3
4
for key in dic:
obfuscation_cmd = obfuscation_cmd.replace(key,dic[key])
print(obfuscation_cmd)
#将dic 字典对应的字母与混淆的代码替换,重组打印。

可以看到这组对应的混淆代码经过手工解码后为字符串是“@echo off”。
enter description here

完整代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import re
jVElq="yxlpdqajizrusokhbmnwefgctv"
obfuscation_cmd ="@%jVElq:~20,1%%jVElq:~23,1%%jVElq:~15,1%%jVElq:~13,1% %jVElq:~13,1%%jVElq:~21,1%%jVElq:~21,1%"
#定义obfuscation_cmd变量

obfuscation_list1=[]
obfuscation_code1 = re.finditer(r"%jVElq:~[0-9]+",obfuscation_cmd)
for match in obfuscation_code1:
obfuscation_list1.append(match.group())
#定义obfuscation_code1变量 使用正则匹配 “ %jVElq:~[0-9]+ ” 如obfuscation_cmd的%jVElq:~20%等。
#print (obfuscation_list1)
obfuscation_Sequence= re.finditer(r"\d+",str(obfuscation_list1))

Sequence_list=[]
for match2 in obfuscation_Sequence:
Sequence_list.append(jVElq[int(match2.group())])
#print (Sequence_list)
#定义obfuscation_Sequence变量 ,使用正则匹配 jVElq 的序列匹配obfuscation_cmd 的数字。

obfuscation_list2=[]
obfuscation_code2 = re.finditer(r"%jVElq:~[0-9]+,[0-9]+%",obfuscation_cmd)
for match in obfuscation_code2:
obfuscation_list2.append(match.group())
#定义obfuscation_code2变量 使用正则匹配 “ %jVElq:~[0-9]+,[0-9]+% ” 如obfuscation_cmd的%jVElq:~20,1%等。

dic={}
#dic 给一个空的字典
for i in range(len(obfuscation_list2)):
dic_old = {obfuscation_list2[i]:Sequence_list[i]}
#定义dic_old 添加{obfuscation_list2:Sequence_list }成为字典
dic.update(dic_old)
#print (dic)

for key in dic:
obfuscation_cmd = obfuscation_cmd.replace(key,dic[key])
print(obfuscation_cmd)
#将dic 字典对应的字母与混淆的代码替换,重组打印。

那么重新复制YourCyanide.txt的下图红框的内容,
enter description here
粘贴并替换到python代码中obfuscation_cmd 的值。

1
2
3
4
5
6
7
obfuscation_cmd ="""@%jVElq:~20,1%%jVElq:~23,1%%jVElq:~15,1%%jVElq:~13,1% %jVElq:~13,1%%jVElq:~21,1%%jVElq:~21,1%
%jVElq:~23,1%%jVElq:~2,1%%jVElq:~12,1%
%jVElq:~12,1%%jVElq:~20,1%%jVElq:~24,1%%jVElq:~2,1%%jVElq:~13,1%%jVElq:~23,1%%jVElq:~6,1%%jVElq:~2,1% %jVElq:~20,1%%jVElq:~18,1%%jVElq:~6,1%%jVElq:~16,1%%jVElq:~2,1%%jVElq:~20,1%%jVElq:~20,1%%jVElq:~1,1%%jVElq:~24,1%%jVElq:~20,1%%jVElq:~18,1%%jVElq:~12,1%%jVElq:~8,1%%jVElq:~13,1%%jVElq:~18,1%%jVElq:~12,1% && %jVElq:~12,1%%jVElq:~20,1%%jVElq:~24,1%%jVElq:~2,1%%jVElq:~13,1%%jVElq:~23,1%%jVElq:~6,1%%jVElq:~2,1% %jVElq:~20,1%%jVElq:~18,1%%jVElq:~6,1%%jVElq:~16,1%%jVElq:~2,1%%jVElq:~20,1%%jVElq:~4,1%%jVElq:~20,1%%jVElq:~2,1%%jVElq:~6,1%%jVElq:~0,1%%jVElq:~20,1%%jVElq:~4,1%%jVElq:~20,1%%jVElq:~1,1%%jVElq:~3,1%%jVElq:~6,1%%jVElq:~18,1%%jVElq:~12,1%%jVElq:~8,1%%jVElq:~13,1%%jVElq:~18,1%
%jVElq:~12,1%%jVElq:~20,1%%jVElq:~24,1% %JSCUL:~23,1%%jVElq:~6,1%%JSCUL:~6,1%%jVElq:~1,1%%JSCUL:~0,1%=%ozMXz:~4,1%%ozMXz:~0,1%%ozMXz:~7,1%%ozMXz:~6,1%%ozMXz:~5,1%%ozMXz:~9,1%%ozMXz:~2,1%%ozMXz:~1,1%%ozMXz:~3,1%%ozMXz:~8,1%
%jVElq:~12,1%%jVElq:~20,1%%jVElq:~24,1% %JSCUL:~20,1%%JSCUL:~6,1%%JSCUL:~17,1%%JSCUL:~25,1%%JSCUL:~19,1%=%JSCUL:~0,1%%JSCUL:~17,1%%JSCUL:~2,1%%JSCUL:~11,1%%JSCUL:~8,1%%JSCUL:~3,1%%JSCUL:~12,1%%JSCUL:~4,1%%JSCUL:~16,1%%JSCUL:~10,1%%JSCUL:~23,1%%JSCUL:~21,1%%JSCUL:~25,1%%JSCUL:~19,1%%JSCUL:~24,1%%JSCUL:~15,1%%JSCUL:~18,1%%JSCUL:~7,1%%JSCUL:~9,1%%JSCUL:~1,1%%JSCUL:~6,1%%JSCUL:~20,1%%JSCUL:~5,1%%JSCUL:~14,1%%JSCUL:~13,1%%JSCUL:~22,1%
%jVElq:~12,1%%jVElq:~20,1%%jVElq:~24,1% %jVElq:~1,1%%jVElq:~11,1%%jVElq:~11,1%%jVElq:~18,1%%JSCUL:~3,1%=%jVElq:~24,1%%jVElq:~22,1%%jVElq:~9,1%%jVElq:~11,1%%jVElq:~15,1%%jVElq:~5,1%%jVElq:~23,1%%jVElq:~21,1%%jVElq:~3,1%%jVElq:~4,1%%jVElq:~25,1%%jVElq:~2,1%%jVElq:~13,1%%jVElq:~19,1%%jVElq:~0,1%%jVElq:~10,1%%jVElq:~20,1%%jVElq:~14,1%%jVElq:~16,1%%jVElq:~7,1%%jVElq:~1,1%%jVElq:~17,1%%jVElq:~18,1%%jVElq:~8,1%%jVElq:~6,1%%jVElq:~12,1%
"""

最后打印改混淆前的代码,可以看到打印出的代码依稀可见一部分可读的字符串,同时还有一些混淆代码在里面,也就是刚刚解的是这组混淆的第一层代码。
enter description here
接下来使用工具一层层的解除混淆,打开【DecodeEnvType_4.exe】,点击右上角的clear按钮。
enter description here
复制全部【YourCyanide.txt】代码的内容,粘贴到【DecodeEnvType_4.exe】,同时填写设定值jVElq及字符串如下图所示。
enter description here
点击Decode按钮,输出第一组的第一层的解码内容。
enter description here
接着解码第一组的第二层,重新填写设定值JSCUL及字符串如下图所示。
enter description here
如遇到快捷键无法全选,则在input或者output,右键全选。
enter description here

接着解码第一组的第三层,重新填写设定值ozMXz及字符串如下图所示。
enter description here
接着用第一组的密钥,解码第二组的混淆,依次类推,解完后如下。
enter description here
首先可以看到执行后,YourCyanide 将其文件属性设置为隐藏和系统文件,然后启动五个最大化的命令提示符窗口。
enter description here
然后它将尝试使用 net localgroup 命令将用户“session”添加到管理员组。
enter description here
它还通过在 HKLM\Software\Microsoft\Windows\CurrentVersion\Run 中创建注册表项,然后将自身复制到 Startup 目录来创建持久性的自动启动机制。它还通过修改其注册表项来禁用任务管理器。
enter description here
然后它检查 %SystemDrive%\AutoExec.bat 是否存在,如果存在,它会删除原始文件,然后复制自身并将文件设置为只读、隐藏并作为系统文件。
它还避免了具有以下用户名的机器,根据我们的研究,其中一些是恶意软件研究人员和沙盒系统使用的用户名,这意味着恶意软件作者正在注意哪些机器应该被规避,如下图所示
enter description here
检查受感染机器的用户名后,它会在“UserProfile\Documents\black.bat” 中删除并执行一个批处理文件。此批处理文件负责不断打开空白屏幕保护程序文件,这会在恶意软件运行时使机器无法访问。
enter description here
YourCyanide 还通过连接变量以形成字符串“net stop”、“norton”、“symantec”和“McAfee”来终止多个服务和安全应用程序。
enter description here
以及还下载KillAVS脚本。
enter description here
打开找到killAVS.bat,打开后发现依旧是混淆,不过这个脚本混淆和前面部分不一样,只需挨个替换即可。
enter description here
如找到%ii%,与上面”set ii=ne”对应,然后在vscode按住ctrl+F,替换全部即可。
enter description here

全部替换如下图所示,终止多个服务和安全应用程序:
enter description here
然后它使用 user32.dll 文件的 SwapMouseButton Export 函数交换鼠标按钮。
终止应用程序后,它将以下目录中的文件重命名为*.cyn,并使用 CMD shell 中名为 %random% 的内置变量将其内容覆盖为随机数。
尽管没有执行实际的加密,但由于文件被重命名,用户仍然会感到非常不便——尤其是对于那些在这些特定文件夹中有大量文件的人。此外,由于恶意软件目前仍在开发中,恶意软件作者很可能仍在完成例程的加密部分。
enter description here
然后它会创建以下赎金记录并将它们放入 %MyDesktop%。
enter description here
它具有两个实例,其中将自身复制到批处理文件,然后将恶意代码附加到win.ini和 system.ini。
enter description here
在执行其例程后,它会删除 %MyDocuments% 目录中的 black.bat 文件,该文件负责使机器无法访问。删除文件将阻止空白屏幕保护程序文件持续打开。
enter description here
YourCyanide 还能够通过电子邮件和不同的驱动器进行传播。它创建了两个 VBScript 文件 mail.vbs 和 loveletter.vbs,它们使用以下主题发送电子邮件(其本身作为附件)。
enter description here
绕过远程桌面连接和防火墙,YourCyanide 使用下图中所示的 netsh 命令启用远程桌面连接 (RDP)。
enter description here
然后它将 YourCyanide.cmd 转储到新创建的目录中。该文件的内容如下图所示。Dropper执行批处理脚本以从 Pastebin 获取内容并将其保存为 YourCyanide.cmd,这是用批处理脚本编写的实际勒索软件。
enter description here
打开ycynlog.bat,可以看到依旧是混淆,同样使用工具解码,这次只有一组。
enter description here
解到将output的内容,全选复制,并在vscode新建文本粘贴解码内容保存为decode_ycnlog.txt。
enter description here
ycynlog.cmd文件负责从受感染的机器中收集和泄露被盗信息。与主文件一样,它也具有多层混淆功能。执行后,文件会隐藏自身并通过在HKLM\Software\Microsoft\Windows\CurrentVersion\Run 中生成注册表项并将自身复制到 Startup 目录来创建其自动启动机制。
该恶意软件使用 Telegram聊天机器人API泄露被盗信息并将其设置为变量“Webhook”。
enter description here
它从Discord (GetToken.exe)下载另一个可执行文件。运行此可执行文件会创建文件 MyTokens.txt,其中包含来自不同应用程序(如 Chrome、Discord 和 Microsoft Edge)的被盗访问令牌数据。
enter description here
将GetToken.bin拖入peid工具中,可以发现是32位的C#程序。
enter description here
关闭PEID程序,将GetToken.bin拖入dnspy反编译工具,点击下图红框中的main函数。
enter description here
GetToken 是一个 C#的NET 程序,用于窃取用户的 Discord 令牌。窃取程序包含 Discord 的硬编码目录路径和各种 Web 浏览器的本地存储,如下图所示。
enter description here
令牌通过使用正则表达式模式匹配来识别,如下所示。如果找到匹配项,窃取者通过调用函数 TokenUtil.checkToken 来检查令牌的有效性。
enter description here
令牌有效性是通过连接到Discord服务器并监控服务器响应来执行的。令牌检查例程如下所示。有效令牌返回给调用者函数。
enter description here
窃取者在受害者系统上创建一个文件 Tokens.txt 并转储找到的所有有效令牌。如果不存在令牌,写入 Tokens.txt 的值为“Retard Has No tokens”。勒索软件最终将 Token.txt发送到Telegram机器人。
enter description here
Tokens.txt 和 userdata.txt 都将使用 curl 命令通过 Telegram 聊天机器人 API 发送。还发现 YourCyanide 泄露了与 Minecraft相关的凭据。
enter description here
分析中,我们可以推断出恶意软件作者正在积极监控恶意软件研究人员创建的报告,方法是记录在沙箱日志和报告中发现的用户名,并将它们包括在用户名和具有多种功能的勒索软件变体(例如本博文中分析的变体)正越来越受欢迎。虽然 YourCyanide 及其其他变体目前的影响力不如其他系列,但它代表了对勒索软件工具包的一次有趣更新,将蠕虫、勒索软件和信息窃取程序捆绑到单个中间层勒索软件框架中。
这些勒索软件变种也很可能处于开发阶段,因此在它们进一步发展并造成更大破坏之前,优先检测和阻止它们。

参考链接:https://pcsxcetrasupport3.wordpress.com/2022/05/16/pealing-back-the-layers-of-a-batch-script-ransomware/