executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
re-script-deob脚本/宏去混淆:PowerShell、VBA、JavaScript。触发词:PowerShell混淆、VBA宏、JS去混淆、脚本解密、恶意脚本
Independent GitHub snapshot · Automated classification · Original documentation governs
参考 [[re-analyze/platform-tips]]——本技能静态解码为主,免沙箱;执行链跟踪中需要运行时(跑脚本/开宏)的步骤按最高原则进沙箱。
apt install python3 / dnf install python3 / pacman -S pythonchoco install pythonpython3 --versionpip install oletools(依赖 pyparsing 自动装上)olevba --helpapt install xxd(新版本独立包,旧版本在 vim-common);Fedora: dnf install vim-common(xxd 传统由 vim-common 提供,F38+ 也有独立 xxd 子包);Arch: pacman -S xxdFormat-Hexxxd -v && sed --versionpowershell.exe(或 PowerShell 7 pwsh)apt install powershell(Microsoft 源)或 snap install powershell;macOS: brew install --cask powershellpwsh --versionpip install jsbeautifier;验证: js-beautify --version按顺序执行;每层还原结果存档编号(layer_01.ps1 → layer_02.ps1 …),执行链跟踪中"运行脚本拿下一层"的步骤一律在沙箱内。
识别脚本类型与混淆风格:
file sample.ps1 && head -c 512 sample.ps1
grep -oiE 'IEX|Invoke-Expression|-EncodedCommand|FromBase64String|eval\(|unescape|fromCharCode|Chr\(|StrReverse|Document_Open|AutoOpen' sample.ps1
-EncodedCommand / IEX / FromBase64String / [Convert]::Sub AutoOpen / Document_Open / Chr( / StrReverse / Evaluate / Shelleval( / unescape / fromCharCode / \xHH 十六进制 / document.write'co'+'mmand')、执行链(外层 IEX/eval 嵌套内层载荷)、字符反转/替换逐层还原(先解码,再跟执行链):
PowerShell(-enc 解码、IEX 链):
-enc 解码(安全,不执行):
pwsh -NoProfile -Command '$d=[Convert]::FromBase64String("BASE64"); [Text.Encoding]::Unicode.GetString($d)'
sed 's/IEX(/Write-Host (/g' layer_01.ps1 > layer_02.ps1$ast = [System.Management.Automation.Language.Parser]::ParseFile('layer_01.ps1', [ref]$null, [ref]$null)
$ast.FindAll({ $args[0] -is [System.Management.Automation.Language.StringConstantExpressionAst] }, $true) | % { $_.Value }
-join/-split 字符拼接、$env:XXX 变量替换、字符串反转VBA(olevba 提取宏 + 还原):
olevba -c sample.docm > macro.txt # 提取宏源码
olevba --decode -c sample.docm > macro_decoded.txt # 自动解常见字符串混淆(--decode 自 oletools 0.24/2015 起就有,无版本门槛)
Chr(65) 拼接用 python3 换算 ASCII;StrReverse(...) 反转;Evaluate("...") 里的执行串AutoOpen / Document_Open / Workbook_Open / Auto_OpenJS(去混淆/解编码):
eval( → 静态替换为 console.log((或 print()观察载荷python3 -c "print(''.join(chr(int(c)) for c in '72,101,108,108,111'.split(',')))"\xHH 十六进制: python3 -c "print(bytes.fromhex('68656c6c6f').decode())"(先剥 \x 前缀)python3 -c "import base64; print(base64.b64decode('...'))"js-beautify layer_01.js -o pretty.jsnode payload.js 或浏览器沙箱执行拿下一层承接步骤 1 的混淆风格分类,按配方执行(方法为核心,工具可替换):
eval / 执行函数替换:把 eval / IEX / Invoke-Expression / bash 替换为输出语句(JS 中 eval = console.log;PowerShell 中把 IEX(...) 换成打印),运行后打印底层代码;解一层、看一层、再解下一层,每层存档(layer_01.ps1 → layer_02.ps1 …)。
JS 常见编码函数(看到即解码目标):unescape()(URL 解码 %XX)、String.fromCharCode()(字符码数组)、atob()(Base64);十六进制 \xHH / Unicode \uHHHH 批量转义解码(python3 -c "import sys; print(sys.argv[1].encode().decode('unicode_escape').decode(errors='replace'))" '<串>');document.write 换成打印。
PowerShell -enc / IEX 链:-EncodedCommand 后的 base64 解码注意 UTF-16LE:
[System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($encoded))
垃圾代码检测(识别特征五条):
真实逻辑形如 junk, junk, junk, CALL target, junk, junk——提取所有真实调用目标、忽略周围噪音(可用脚本按 call 指令 + 垃圾目标过滤实现)。
Hex 编码载荷:hex 转字节后先试常见变换:逐字节减 1、XOR 单字节密钥(0x01 起递增试)。
常见解码链模式:base64 decode → gzip decode → reverse → base64 decode;每层输出用 file 判断类型并验证可读性;验证失败说明层序或编码判断错,回退一层重试。
JScrambler 类商业混淆器的手法与对抗:
_0x 变量重命名模式、函数体加密(运行时解密)olevba -c 提取的宏还是满屏 Chr(65) & Chr(66) 拼接;原因——olevba 只负责提取不负责还原;对策——用 --decode 自动解常见手法,剩余手动还原,最后动态验证还原结果正确pwsh sample.ps1 后系统被改/发生外联;原因——脚本可能是下载器或持久化植入(platform-tips 默认沙箱原则的典型违例场景);对策——一切动态执行进 [[re-sandbox]](网络隔离 + 快照),静态解码可免沙箱pwsh -NoProfile -Command "[scriptblock]::Create((Get-Content layer.ps1 -Raw))" / node --check layer.js)再进入下一步sign=)或用网络面板 initiator 列回溯发起请求的调用栈(比搜源码快)Math.floor(Date.now() / 1000)(秒级)var state=0; while(true){switch(state){…}} 状态机循环或 _asyncToGenerator(function*(){…}) 包装,逻辑像一团乱麻;原因——generator/async 被 Babel/Regenerator 等转译链降级为状态机与包装器,源级语义被机械摊平;对策——识别「真常量条件 while + 单 switch 体」模式后按 case 顺序展平为线性语句,人工状态变量随之消失;async 则先全程序扫描出被包装的 generator 函数,再把函数体内 Yield 还原为 Await 并内联包装器;先看 helper 函数名确认转译链(Babel/Regenerator 等各有特征指纹),针对已知工具链写反变换,比通用还原更省力
(来源:hermes-decomp(SymbioticSec),MIT)