PowerShell反混淆学习

PowerShell功能十分强大,其有很多优点:例如易于导入模块,能够访问核心API和远程命令,也正是由于这些优点使其成为攻击者执行无文件攻击的首选工具之一。

常见混淆方式

例如:变换大小写、字符串分割、将变量插入命令语句中(最常见的是-f格式转换)、变量中增加反引号“`”、字符串之间添加空格、字符转换ASCII码、利用replace函数替换、base64加密等等……

如图所示:

人工去混淆

先通过几个例子来了解PowerShell样本例子来了解去混淆的方式

iex

例如:

.( $SHEllID[1]+$shEllid[13]+'x') (( '118&105N64J100J25V19J4&5&26~25f3&25N64G64C100~4f5_30C15Z25~64~67f9G56Z47C43N62V47f46V106Z37~36V112~106&67&114V101_120V120~101N120C122&123_126V64V67&9N56Z47_43~62_47C46C106C40J51G112&106&67~11N46G43V39V106C8C47Z56J62_56J43N39Z64J67C12_35f38f47G36G43C39Z47f112N67&67&64C67N9f56N47~46G35~62G57N112~67N67J64C67Z24&47N59G63C35C56V47J39J47J36Z62f57_112G67N64J67J30G37N46_37V57~112_67&67~67Z67f64C100J15f18f11V7Z26&6V15&64V67~64C100~15~18N11G7C26_6_15&64&67Z64&100V26_11f24G11C7~15f30N15f24C106&26~11G24~11V7G123G64_106_67f64N100V26&11Z24C11&7V15Z30_15N24&106&26~11V24J11J7_120&64&67_64f105Z116J64~17N9f39~46V38C47&62C8Z35~36G46C35Z36&45f98C14f47f44~43C63~38N62~26C43_56~43G39G47G62G47N56V25&47C62V4_43&39_47J106f119G106Z109G36~43J39~47~109C99J23Z64_17_5_63V62_58G63Z62~30_51Z58J47&98_109V25G51C57Z62V47G39V100N7N43&36Z43f45G47J39Z47G36N62V100N11&63&62V37G39f43C62Z35&37~36V100f26N25f9C63C57J62C37f39N5V40f32&47N41&62J109~99G23_64&58N43f56C43G39f106J98G64G67V17G26_43&56&43N39Z47~62C47C56N98f26Z43V56&43C39Z47f62J47&56Z25J47~62C4f43&39&47~106C119_106Z109&36&43f39N47~109f102V64G67~67Z7_43N36N46_43~62J37J56V51Z102_64G67V67G28~43C38f63N47V12_56V37&39V26f35_58Z47V38N35~36J47_102Z64N67J67&28Z43&38V63Z47_12V56~37J39G26G35J58~47G38N35N36G47&8G51C26J56~37~58N47&56_62J51&4J43&39N47J99J23N64&67&17C28_43C38V35J46C43N62V47&25_47_62f98J104G30C37_39&104J102V104J14G35G41J33V104Z102f104~0N43Z36f47~104_99_23C64Z67Z17J28~43N38f35G46G43G62f47_24_43N36J45G47Z98J120f123V102~124C127N99_23~64Z67_17N28f43_38f35J46C43&62C47~25&41G56_35N58&62Z98G49G30&47J57J62N103N26&43~62f34C106&110C21C106Z103Z26_43Z62N34J30_51N58Z47G106Z109N9C37~36&62&43_35_36J47&56f109_55V99&23_106~64Z67J17C28V43_38_35J46G43f62_47J4Z37J62V4V63G38Z38C5C56&15N39G58_62C51V98Z99_23f64V67_17~28Z43f38C35C46f43G62_47~9V37_63G36J62J98_123Z102~127_99C23V64f67V17J28V43C38G35G46V43N62G47J6Z47V36V45~62N34C98V123V102f123Z122&99G23N64G67&17J28_43Z38Z35~46&43V62V47V26N43~62C62G47N56N36&98Z99&23C64V67C17f57f62f56G35J36_45V23C110C9N37_39C58V63C62~47C56G36C43Z39f47f106V119_106V109V14N15C12~11&31&6J30_28C11C6C31V15_109V64_99_64&64C40N47J45f35_36Z106_49_64_67V110&15f56N56~37_56f11C41&62C35J37C36V26C56_47V44f47J56N47N36V41V47J106f119Z106~17_25f51J57J62G47J39V100~7G43J36Z43C45C47J39&47~36C62~100_11V63N62G37C39~43C62Z35&37f36J100N11~41C62Z35f37&36G26J56&47G44~47f56C47~36f41V47G23Z112~112N25C62Z37N58V64f67V25Z47f62J103C25N62J56G35_41J62G7Z37J46J47f106J103Z28f47J56_57_35C37V36C106G6C43&62_47f57N62G64J67_62V56G51J106N49V64&67G67V64Z67_55f106J41V43C62C41~34J106&49C64~67~67J29~56G35C62_47&103&15V56G56G37V56f106C110G21_100&15N50G41~47f58V62_35V37C36C100V7Z47V57f57Z43C45_47&64G67G55G64G55f64f64Z58G56J37G41&47N57f57G106f49~64~67f62_56Z51Z106J49J64_67G67C64N67V55~106_41N43J62~41V34Z106_49G64&67_67N29Z56&35&62&47C103V15_56f56Z37C56C106f110C21&100f15_50Z41~47C58N62C35&37C36_100V7&47G57N57_43&45G47N67f64N67V55J64Z106G106_106C106_64C55f64~64~47G36J46C106N49Z64Z67_62J56C51C106&49G64_67Z67Z64V67~55C106Z41C43f62C41J34f106Z49Z64Z67f67J29C56J35Z62~47&103N15N56_56&37N56&106&110V21_100f15Z50V41N47Z58_62V35~37~36J100Z7J47J57J57N43f45C47~64G67G55V64Z55J64'-Split'&'-spLIt'~' -SpliT '_'-spLIt 'v'-SpLIt'z' -sPLiT 'C' -spLit'n'-spLit 'J' -SPLIT'f'-spLIt 'g'| FoREacH {[chAR] ($_ -bXor"0x4a") }) -joIN'' 

中间都是被混淆了的代码,前后各有一小段代码。

后面的代码大致是进行了分割与异或操作,

前面的是$SHEllID[1]+$shEllid[13]+'x',这里的$是PowerShell的操作符,可以将字符串作为命令执行,那么$SHEllID是什么呢,可以在PowerShell中查看:

也就是说,通过从$SHEllID这一系统变量中,提取到了i和e这两个字符,以这种混淆的方式拼接出了iex字符。

iex全称为Invoke-Expression,PowerShell文档中对其的解释为:

即iex用于将后面的字符串作为命令来执行;如果去掉iex,运行后就会得到原来的字符串。

如果用户没有对样本进行分析,而直接运行经过iex混淆后的恶意的指令,那么就会给用户带来麻烦,正因如此,我们需要对样本进行解混淆来得到明文代码。

于是我们可以将iex去掉,即这里的.( $SHEllID[1]+$shEllid[13]+'x')

并通过./test.ps1 > test_1.ps1命令来运行去除iex后的脚本,从而得到明文:

<#
.SYNOPSIS

.NOTES
Created on: 8/22/2014
Created by: Adam Bertram
Filename:
Credits:
Requirements:
Todos:
.EXAMPLE

.EXAMPLE

.PARAMETER PARAM1

.PARAMETER PARAM2

#>
[CmdletBinding(DefaultParameterSetName = 'name')]
[OutputType('System.Management.Automation.PSCustomObject')]
param (
[Parameter(ParameterSetName = 'name',
Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateSet("Tom","Dick","Jane")]
[ValidateRange(21,65)]
[ValidateScript({Test-Path $_ -PathType 'Container'})]
[ValidateNotNullOrEmpty()]
[ValidateCount(1,5)]
[ValidateLength(1,10)]
[ValidatePattern()]
[string]$Computername = 'DEFAULTVALUE'
)

begin {
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
Set-StrictMode -Version Latest
try {

} catch {
Write-Error $_.Exception.Message
}
}

process {
try {

} catch {
Write-Error $_.Exception.Message
}

}

end {
try {

} catch {
Write-Error $_.Exception.Message
}
}

运行后打开test_1.ps1就能清晰地看到代码做了什么

iex存在许多种表达方式,一些常见的:

IEX
InVOKe-EXprESSiON

(GV '*MdR*').nAme[3,11,2]-Join''
(vAriaBLe '*mdr*').naME[3,11,2]-JoIn''
(geT-vAriaBLe '*MdR*').NAmE[3,11,2]-JOIN''

$VERBOsEPREference.TOstrING()[1,3]+'x'-JOiN''
([STRIng]$veRbOsePrEfErENCe)[1,3]+'X'-joIn''

$env:COMspEC[4,15,25]-jOin''
$eNv:COmsPEc[4,24,25]-joiN''
$eNv:COMSPeC[4,26,25]-jOIN''

$SHEllID[1]+$shEllid[13]+'x'

$psHoME[4]+$PShOmE[30]+'x'
$psHoME[4]+$PsHOmE[34]+'X'
$psHomE[21]+$pshOME[30]+'X'
$PSHoMe[21]+$PsHOme[34]+'X'

注意,默认情况下,Windows PowerShell本身不区分大小写。因此这里iex的表示方法,大小写是随意的。

当然,我们也能发现,iex通常与一些运算符、操作符结合在一起使用,例如test.ps1中最开始的.运算符。

常见的与iex结合的运算符、操作符如下:

1、属性引用运算符(点运算符): .
作用:通过点运算符访问对象的属性和方法
例如:
.( $SHEllID[1]+$shEllid[13]+'x')

2、调用运算符: $
作用:可以将字符串直接解释成命令并执行
例如:
& ((geT-vAriaBLe '*MdR*').NAmE[3,11,2]-JOIN'')

3、管道运算符: |
有时候iex并不会出现在开头,会与"|"符号结合出现在末尾
作用:将上一条命令的输出,作为下一条命令的输入
例如:
|.( $eNv:COmsPEc[4,24,25]-joiN'')
| InvOkE-eXPREssiOn

即:将前面经过混淆后的命令交由iex来执行,在我们删除这样的iex时,也要将管道运算符一同删除

PowerShell and some flags

用一个多重混淆的例子来了解PowerShell and some flags常见的混淆结合方式

powershell.exe -NoE -Nop -NonI -ExecutionPolicy Bypass -C "sal a New-Object;iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String('RVZba95GEP0rkgnITqKwq73rSWnWCV+pksgyfTFGbIrBLr4E27QPTf97z5lVXEKQvDuXM2fOzKfvD39fPT5dX93eNk3Tf364P9zL8+vjAw6aI/x7ddysp8/9zfnVXdP9Vc4O5dvt6fjwce2armtOjt40F0/Pj4fPny6Pm8640bteK7Xg/2wGPFKvdchaxUlrv2nlNq15HlutdDEDrvSstVpxXfA+am1bmMDMLtXc4albM4xaBXotetCImnClacaEBWZwXwxzDAiIoCrCQ03wQG6bgWOUp4qLGSbP7K2xuEcE7XHvmRg2bnNxsqHYkFNckGlCxiWF0bnVudZ6xHcr/EoKSMwQxD0gjEZ44NVqZjjrl0QCAEClxQYU6YDJrZJLnFy2AfD06HTv7OLMkhypgpcdU0BtIJThalh4m9mGJVohKAVyBAxk3AG+QvmmN6BQtSSVjCA56QRnKuadkZbeZpg9iV0CeJQzX6zLkc1QS1RjQBABL347YjuCPevm6PJOZzZDqcSzEiSNRVpSiZ8igQGvHI8GpamBddEVT/bSIcTiNSRTAjunydAsWHLFMkdSyi7qIl0SP0iEVA30hPnmKZC4CFliAMLQ2pBKYnJR2JqSHEJQlZtS20ZFqp8SJBLr2qj6PSmlMVWtSlKKECH6QJKllLHeontkijqS8sks+rSlRMVMZtiskBCYy82VFY1erFUYqoeJAWbpeV/Loc6hFLZw1oOB6ZiQc2MlCXBsqe33wp0lBjtVqhyLnVksOkG5CirEDNuuKQQyxQjgkZOIVoAYq7JhuGHe6+OkTtbTJIvuEpMVqzcZokzYw8RExN96P0a/+ghKAgxVz4FL7b4BiouzU8XZ1XrMVHamWL/ZNNq4Op0xYk7NTk8OWOg0JsaszjI6AJ8AunhStwWKlCT5DBVESBzkRLVVkol+qyT31i3RzXVrxFE2AAYzRzvWgZv3eZprLvobGICRbFWpjIx7Y1Z23HJzqFU8k+jLolBLeVGQ7IrLQbBT6NwLSzDz3iuWsbKRk3E4rlsQVqgJDiyDWwqnIp5d9HxyYGSjaiZ12DO5LlQonbimlCZ2ieQzq3jUrak4LcCTuBJl+BifGfkq+veL/OlnhhgwfH5L1AtmhFsURXrGlVmfdu33sur8UnHrpS6lnNZo+v8nukTuFLVisAOLIiHS1CmYvU5GTUDbwjpwQilhkufRL+y2UpsFyqedo7bG4SiaSbiHDHIw2761+n0h9zWW5z4Xpfqfc7NK3ZA05Ig2+LjVhSKFw0hkvPPvQE7r0YWBYwP1YxuDqBZE5cDRQwEDxZjqD4IsSfTRIubmmXg1fo2yGX5KIluunAlbNFKZMu/7+Sjni49sl+gl4deJmwRyLD72FRlXHJpY9MBuz8iteqwHxQM8uqZ/+v7b4bnpFnm9PZx3uR7enDdd6fqnr7e8xg97v+IVh+PLYSuHcO8m+nyVQL283t48d3NXg3db96P5+OXstPxx3T98+/P0w/M/xxcfrsvj5cXh/vyyebWdNP82J82bo5fvitO7Bh8W7x9v3v/y8mHRdCdHP94dH3+6Ou9/3785mu71XT573Z28uy/z6YV5q/Xb4bL/9cvhvoP5fw=='),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()"

这其中的powershell.exe -NoE -Nop -NonI -ExecutionPolicy Bypass -C 就是指:

调用PowerShell,给它一些flags(标志)以确保它的执行,并提供要解码和执行的真实有效载荷

其中一些flags的含义是:

-NoE
运行命令后不退出,即创建一个进程并保持作为 powershell.exe 运行
-Nop
-NoProfile,不加载 PowerShell 配置文件
-NonI
-NonInteractive,不创建交互式提示,即它运行命令而 PowerShell 窗口不会在用户屏幕上弹出一个持久终端
-ExecutionPolicy Bypass
跳过执行策略
-C
即- Command,接下来运行什么

此部分允许 PowerShell 执行用户不可见的命令,并创建一个在命令执行后保持运行的进程。

对于这一部分,在解混淆时我们要将~~powershell.exe -NoE -Nop -NonI -ExecutionPolicy Bypass -~~删除。

剩下的部分,可以简写为

sal a New-Object;iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String('redacted-base64-encoded-string'),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()

其中,sal是Set-Aliascmdlet的别名。sal a New-ObjectNew-Object创建一个快捷方式“a”,

使后面出现的a IO.StreamReader等价于New-Object IO.StreamReader

之后通过iex执行payload,payload中的作用主要是将 base64 编码的字符串转换为内存流。

因此,我们要将这里的~~iex~~字符去除,这样就只剩下了:(简写)

sal a New-Object;(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String('redacted-base64-encoded-string'),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()

直接运行,即可得到第一层混淆的结果:

powershell   -NonIn  -NoPro    " " $( SEt-iTem 'vaRIablE:oFS' '' )"+ [strING]( '35:65-100Q100M32Q109-117D108@116_105_112Q108!101a32D101M110S116a101:114!112_114Q105_115Q101!32:107!101Q121-119_111_114-100a115a10Q36_102M111M108:100@101@114D117:114D108Q32@61a32!34@104-116D116!112:115_58@47a47D98Q119@121Q97:55S55!46M115S104a97a114@101:112-111D105Q110M116!46Q99-111@109Q47S115:105S116!101:115D47@111:51-54Q53Q95@116-114:97-105-110M105Q110:103M47Q84_114Q97Q105a110Q105!110_103-34!10!10S10Q36@102_111-108D100@101!114Q32M61!32Q71_101!116a45D80S110Q80:70!111@108D100!101:114:32@45M85D114D108D32a36_102@111S108a100a101@114@85!114_108a10:36-102-105D108-101-115D32Q61M32a71M101S116M45D80D110Q80M80M114D111a112:101-114Q116-121M32M45_67!108Q105Q101-110:116D79a98a106a101S99:116D32:36@102a111D108!100a101:114M32a45!80-114D111!112@101M114Q116Q121D32-70S105D108:101M115@10!102:111@114_101Q97_99S104@32_40:36-70a105M108a101Q32S105S110-32_36D70M105-108Q101_115D41-10M123S10:9D10_9:119Q114a105!116M101S45@104@111a115:116M32:34@87a111@114Q107_105Q110D103a32:111:110S32Q36@40D36M102M105D108D101@46:110D97Q109M101a41_34@10D32_32@32:32_36!66:86S68M117M100-61a39!105_112a58M50a54S46S55D53a46_49:48S51D46M50M51@52Q39!10:9_36!105_116!101_109a32a61Q32_71@101_116D45_80@110_80_70a105D108_101Q32-45Q85M114-108:32!34Q47D84:114:97M105a110M105_110a103Q47Q36D40a36M102:105-108S101M46D110S97M109a101S41a34D32:45_65!115D76!105-115M116Q73M116M101_109S10_9@35Q73S116a115M32_105@110a32!116S104@101-114@101D32Q116_119a105Q99D101a32a98S101@99@97Q117M115M101D32-119_101M32!109D117-115D116S32_115D101:116Q32_116M97Q120M86_97_108!117:101S67M111S108@108:101-99-116Q105@111Q110Q10D9S83-101S116M45a80!110S80D76S105M115_116@73!116S101S109D32!45a76@105:115-116:32-34a84:114S97@105@110!105M110S103@34D32D45D73_100!101-110M116-105:116@121@32:36a105!116S101:109M46S73S68_32M45_86_97a108M117@101-115Q32!64@123a32_34Q84M97!120D75@101S121_119-111D114D100a34_32_61@32S36S84_101-115M116D44M32@36_84-101_115M116D44:32@36Q68D117_109S98@44@32a36a68-117@109a98S32a125M10M9-10-9:10a125:10' -spLIt 'Q' -splIT'D' -spLiT 'a'-sPlIt 'S' -SPlIT ':'-sPlIt '!' -SPLIt'@' -sPLIt '-' -sPlit'M'-spLIt'_'| FOREach-objECt{([Char][InT] $_) } ) +"$( SEt-iTEm  'vAriABlE:oFS' ' ')"|.((GeT-VaRIablE '*mDR*').naME[3,11,2]-JOIn'')"

这是第二层混淆,可以看到这里使用PowerShell and some flags与iex(最后出现的|.((GeT-VaRIablE '*mDR*').naME[3,11,2]-JOIn''))进行了结合。

因此我们只需将~~powershell -NonIn -NoPro~~~~|.((GeT-VaRIablE '*mDR*').naME[3,11,2]-JOIn'')~~删除,之后注意到整体前后各多了一个双引号(”)字符,将最前和最后的双引号删除后,即可直接运行,得到结果:

#Add multiple enterprise keywords
$folderurl = "https://bwya77.sharepoint.com/sites/o365_training/Training"

$folder = Get-PnPFolder -Url $folderUrl
$files = Get-PnPProperty -ClientObject $folder -Property Files
foreach ($File in $Files)
{

write-host "Working on $($file.name)"
$BVDud='ip:26.75.103.234'
$item = Get-PnPFile -Url "/Training/$($file.name)" -AsListItem
#Its in there twice because we must set taxValueCollection
Set-PnPListItem -List "Training" -Identity $item.ID -Values @{ "TaxKeyword" = $Test, $Test, $Dumb, $Dumb }

}

一些工具

混淆工具:https://github.com/danielbohannon/Invoke-Obfuscation

解混淆工具:

https://www.secpulse.com/archives/117576.html

https://www.secpulse.com/archives/109912.html

参考资料

https://docs.microsoft.com/zh-cn/powershell/module/microsoft.powershell.utility/set-alias?view=powershell-5.1

https://threat.tevora.com/5-minute-forensics-decoding-powershell-payloads/

https://www.freebuf.com/articles/system/181697.html

https://www.jb51.net/article/53519.htm

文章作者: HotSpurzzZ
文章链接: http://example.com/2021/11/01/PowerShell反混淆/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HotSpurzzZ