由于PowerShell作为一种非常有用的系统管理员脚本工具,在微软的Windows系统中广泛使用,并且大部分攻击者可以利用PowerShell来编写恶意代码,实现无文件落地攻击,所以攻击者更加偏爱使用PowerShell脚本进行攻击。
在对PowerShell去混淆之前,我们得要先了解一下PowerShell的混淆方式有哪些。目前PowerShell主要以下面三种层次进行混淆:
-
字符串相关:不仅对常量字符串进行混淆,还有对cmdlet,函数参数等进行混淆
-
编码:Base64或者二进制
-
压缩:就是压缩整个脚本
这里主要讲一下字符串混淆:
混淆方式 | 原文 | 混淆后 |
大小写 | hello | HeLLo |
分割 | hello | ‘hel’+’lo’ 或者$a =’hel’; $b = ‘lo’; $a + $b |
重新排序 | hello | ‘{3}{2}{1}{1}{0}’ -f ‘o’, ‘l’, ‘e’, ‘h’ |
使用反引号(反引号可以作为连接符) | hello | h`ell`o |
空格 | hello | hel lo |
使用&将字符串转换成命令操作 | iex | &(iex) |
使用字符的ASCII码替代字符 | A | [cHAr]65 |
更多的混淆方法可以看Invoke-Obfuscation,该项目是一个开源的PowerShell脚本混淆项目。
PowerShell 去混淆的方法
下面将介绍几种PowerShell脚本去混淆的方法。
1. 利用PowerShell日志去混淆
本地组策略编辑器->计算机配置->管理模板->Windows PowerShell
启用模块日志记录中的模块名称填写 *
查看PowerShell日志方式:
事件查看器->应用程序和服务日志->WindowsPowerShell
运行样本,即可直接通过查看日志来观察去混淆后的PowerShell脚本。
使用日志的好处就在于只要调用了PowerShell,日志就能把PowerShell记录下来。
2. 手动还原PowerShell脚本
许多PowerShell脚本都会使用Invoke-Expression/iex cmdlet来将混淆后的字符串当作代码使用。找出iex将是PowerShell去混淆的关键。只要我们对iex后面混淆的字符串进行还原就能知道恶意样本的意图。这是因为在PowerShell中,使用Invoke-Expression cmdlet将字符串作为命令运行,字符串就会被自动去混淆。
例子:
我们首先得要识别出来哪个是iex。
而iex后面的内容就是cmdlet。这个时候将cmdlet保存到变量中,并且使用echo输出变量,便可得到去混淆后的结果。
我们可以发现,此时输出的字符串还存在着一定的混淆。接着我们再从输出的字符串去混淆后的中识别出iex。
再使用同样的方式对iex后的字符串进行解密,便可得到去混淆后的PowerShell脚本。
3. 使用工具进行去混淆
笔者在这里收集了四个比较常用的PowerShell去混淆工具,大家可以直接使用工具对PowerShell进行去混淆。
-
PSDecode(https://github.com/PrateekKumarSingh/PSDecode)
-
PowerShellProfiler(https://github.com/pan-unit42/public_tools/tree/master/powershellprofilerhttps://www.freebuf.com/sectool/219057.htm,值得一提的是该工具还会对恶意PowerShell脚本功能进行评分)
-
PowerDrive(https://github.com/denisugarte/PowerDrive)
-
PowerDecode(https://github.com/Malandrone/PowerDecode)
4. 对PowerDrive进行分析
下面将对上述其中一个工具:PowerDrive进行简单的分析:
PowerDrive主要分为四大模块,分别是预处理模块,去混淆模块,反调试检测模块,执行脚本模块。
-
预处理模块,主要由以下三部分组成。
-
将多行转换成一行。
-
去除不可见的ASCII字符或者去除格式错误的转义字符。
-
检查符号是否正确。
-
去混淆模块,主要使用以下两种策略进行去混淆。
-
使用正则来匹配需要重新排序的字符串,并进行重新排序。
-
重写cmdlet。因为在PowerShell中,使用
cmdlet Invoke-Expression将混淆后的字符串作为命令运行,字符串就会被自动去混淆。
-
反调试检测模块,由于PowerShell脚本中可能会出现一些反调试的技术来避免动态调试。
-
检测sleep指令。
-
检测恶意软件的输出是否被重定向到空输出。
-
检测死循环。
-
检测是否使用try-catch模块来引发异常。
-
执行脚本模块,主要是为了检索后续阶段的有效载荷,并通过覆盖3个cmdlet:Invoke-WebRequest、 Invoke-Rest
和New-Object来提取和下载脚本关联的所有其他可执行⽂件。
(这里上述为原文翻译,但实际上我在源码中看到仅是通过正则匹配提取URL,并检查URL是否存活进行输出)
总结
以上就是本次对PowerShell去混淆的总结,大家可以尝试着用上面的方法对PowerShell脚本去混淆。
参考链接
https://bbs.pediy.com/thread-248034.htm
https://bbs.pediy.com/thread-261262.htm
https://github.com/Malandrone/PowerDecode
https://github.com/denisugarte/PowerDrive
https://github.com/pan-unit42/public_tools/tree/master/powershellprofilerhttps://www.freebuf.com/sectool/219057.htm
https://github.com/PrateekKumarSingh/PSDecode
http://ceur-ws.org/Vol-2940/paper19.pdf
https://arxiv.org/abs/1904.10270
https://www.blackhat.com/docs/us-17/thursday/us-17-Bohannon-Revoke-Obfuscation-PowerShell-Obfuscation-Detection-And%20Evasion-Using-Science.pdf
原文始发于微信公众号(ReverseHub):PowerShell去混淆总结