Automatic string formatting deobfuscation
字数 1152 2025-08-06 08:35:11
PowerShell恶意脚本字符串格式化混淆与自动化去混淆技术详解
一、混淆技术概述
混淆技术是恶意软件作者常用的对抗分析方法,通过使代码难以阅读和理解来增加分析难度。本文重点分析的PowerShell样本使用了三种主要混淆技术:
- 字符串格式化混淆:将完整字符串拆分为多个部分,运行时重新组装
- 字符串串联:通过加法运算符连接多个子字符串
- 反引号干扰:在变量名中插入无意义的反引号字符
二、样本基本信息
- MD5: 907dbc3048f75bb577ff9c064f860fc5
- SHA-1: 667b8fa87c31f7afa9a7b32c3d88f365a2eeab9c
- 文件大小: 368.42 KB
- 代码行数: 2763行
- 检测率: 混淆后57个引擎中仅2个检测为恶意;去混淆后56个引擎中11个检测为恶意
三、混淆技术详解
1. 字符串格式化混淆
原理:使用字符串格式化功能将完整字符串拆分为多个部分,运行时按指定顺序重组。
示例:
$var = "{4}{2}{3}{1}{0}" -f 'ion', 'at', 'fu', 'sc', 'ob'
实际值为"obfuscation"
特点:
- 使用
-f或-F格式化标志 - 花括号内数字表示参数索引
- 参数顺序与显示顺序无关
2. 字符串串联混淆
原理:将单个字符串拆分为多个子字符串通过加法连接。
示例:
$y = "Va" + "RI" + "ABL" + "E:Rbh" + "0"
特点:
- 使用
+运算符连接字符串 - 可阻止代码重构工具正常工作
- 常用于反射调用方法时的参数构造
3. 反引号干扰
原理:在变量名中插入反引号,不影响代码执行但妨碍阅读。
示例:
function iN`VokE`-r`F`BuxmE`HAEmZbhI
实际函数名为iNVokE-rFBuxmEHAEmZbhI
四、自动化去混淆技术
1. 反引号处理
方法:直接删除所有反引号字符
Python实现:
line = line.replace("`", "")
2. 字符串格式化去混淆
正则表达式:
""((?:\{\d+\})+)"\s*-[fF]\s*((?:'.*?',?)+)"
处理步骤:
- 提取花括号中的索引列表
- 提取单引号中的字符串列表
- 按索引顺序重组字符串
- 移除原始格式字符串和参数列表
示例处理:
输入:
"{7}{2}{5}{10}{13}{1}{4}{9}{14}{12}{0}{3}{11}{6}{8}" -f 'mAR','opse','yst','sh','R','eM.RuNti','T','S','E','v','ME.','ALAsATtrIbu','ces.','intEr','I'
输出:
"System.Runtime.InteropServices.MarshalasAttribute"
3. 字符串串联去混淆
正则表达式:
"(?<=$)\"(?:\"|\s*\+\s*\")+\"(?=$)"
处理步骤:
- 识别被括号包围的串联字符串
- 移除所有引号、加号和空格
- 重新组合为完整字符串
示例处理:
输入:
("Va" + "RI" + "ABL" + "E:Rbh" + "0")
输出:
("VARIABLE:Rbh0")
4. 格式化标志清理
正则表达式:
"(-[fF])(?=[^\w])"
方法:安全移除不影响代码的-f和-F标志
五、完整Python去混淆脚本
import re
# 文件处理
powershellPath = 'powershellSample.txt'
powershellFile = open(powershellPath, 'r')
powershellContent = powershellFile.readlines()
# 统计变量
output = ''
formatCount = 0
variableCount = 0
backtickCount = 0
# 逐行处理
for line in powershellContent:
# 反引号处理
backtickCount += line.count("`")
line = line.replace("`", "")
# 字符串格式化处理
matchedLine = re.findall(""((?:\{\d+\})+)"\s*-[fF]\s*((?:'.*?',?)+)", line)
if len(matchedLine) > 0:
for match in matchedLine:
indices = list(map(int, re.findall("{(\d+)}", match[0])))
strings = re.findall("'(.*?)'", match[1])
result = "".join([strings[i] for i in indices])
line = line.replace(match[0], result, 1)
line = line.replace(match[1], "", 1)
formatCount += 1
# 格式化标志清理
formatFlag = re.findall("""(-[fF])(?=[^\w])""", line)
if len(formatFlag) > 0:
for formatFlagMatch in formatFlag:
line = line.replace(formatFlagMatch, "")
# 字符串串联处理
varDeclaration = re.findall("(?<=$)\"(?:\"|\s*\+\s*\")+\"(?=$)", line)
variable = ''
if len(varDeclaration) > 0:
for string in varDeclaration:
variable = string.replace("\"", "")
variable = variable.replace("+", "")
variable = variable.replace(" ", "")
variable = "\"" + variable + "\""
variableCount += 1
line = line.replace(varDeclaration[0], variable)
output += line
# 输出结果
with open('deobfuscatedSample.txt', 'w') as f:
f.write(output)
# 统计信息
print("反引号移除次数:", backtickCount)
print("格式化字符串处理次数:", formatCount)
print("串联变量处理次数:", variableCount)
print("总处理次数:", (backtickCount + formatCount + variableCount))
六、去混淆效果对比
混淆前代码片段:
$I7KUHX = [tYpe]("{7}{2}{5}{10}{13}{1}{4}{9}{14}{12}{0}{3}{11}{6}{8}" -f 'mAR','opse','yst','sh','R','eM.RuNti','T','S','E','v','ME.','ALAsATtrIbu','ces.','intEr','I');
&("{0}{2}{1}" -f'sE','-iTeM','T')("V"+"Ari"+"Ab"+"LE:cF84")([TYPe]("{2}{0}{1}{7}{9}{6}{10}{3}{4}{5}{8}" -F'yste','m.RU','s','es','.un','ManaGeDty','rV','nTiME.inTEroP','se','iC','pe'));
去混淆后代码片段:
$I7KUHX = [tYpe]("System.Runtime.InteropServices.MarshalasAttribute");
&("sET-iTeM")("VARIABLe:cF84")([TYPe]("system.RUnTiME.inTEroPserViCes.unManaGeDtype"));
七、技术要点总结
- 正则表达式设计是关键,需准确匹配各种混淆模式
- 处理顺序很重要:先处理反引号,再处理字符串格式化,最后处理串联
- 统计信息有助于评估混淆程度和去混淆效果
- 保留原始功能是去混淆的基本原则,不能改变代码行为
通过这种自动化方法,可以显著提高恶意PowerShell脚本的分析效率,使安全研究人员能够专注于实际的恶意行为分析而非代码解构。