很多红队人员都喜欢利用 PowerShell 来执行攻击脚本、C2上线等一切操作。它默认内置于现代 Windows 操作系统中,可以下载远程脚本、在内存中执行,并且由于缺乏控制,可见性比较低。
在过去的几年里,安全防御产品和微软发现了这种脚本语言的滥用情况。所以在 PowerShell v1 之后,开始集成保护措施,例如脚本日志记录、脚本块日志记录、模块日志记录和AMSI。
脚本块日志记录可以为蓝队记录 PowerShell 中执行过的脚本。而且有个巨大的好处是它会自动将混淆的脚本解码为可读形式:
那么,作为红队,我们该如何解决这个问题呢?
在计算机领域要分析一个东西无外乎源码审计、逆向、FUZZ,而Powershell源码是公开的,所以通过查看其源码:https://github.com/PowerShell/PowerShell/blob/7ec8e4ed8f47e81e70de5353500f8a01d5fe396c/src/System.Management.Automation/engine/runtime/CompiledScriptBlock.cs#L4
可以发现PowerShell只使用ScriptBlock的Extent来生成日志,那什么是Extent?
这里就不得不提一点编译原理的东西,不管什么语言编译器在编译的时候都会根据源代码创建一种树状结构(这个结构称为抽象语法树 AST)以便转换创建机器代码
So,当在 PowerShell 中创建 ScriptBlock 时也不例外。所有 PowerShell AST 的父节点都是 ScriptBlock AST,此对象除了树的子节点之外还包含许多属性。这些属性之一是 Extent ,可以将其视为 ScriptBlock 的字符串表示形式
每当通过在{}中嵌入代码或使用[ScriptBlock]::create()创建脚本块时,AST和随后的Extent都会自动生成,那么如何利用这些信息呢?实际上,我们可以自己构建AST:
[System.Management.Automation.Language.ScriptBlockAst]::new($Extent,
$ParamBlock,
$BeginBlock,
$ProcessBlock,
$EndBlock,
$DynamicParamBlock
)
参数*Block这些块是 AST 中包含可执行代码的地方。因此,如果可以创建这些块和 Extent 之间的不匹配(block里包含实际执行的脚本代码,Extent 中包含一些正常无害的伪装脚本),那么理论上能够执行代码,并且日志看起来不同