.NET逆向工程实战:混淆脱壳与加密算法还原
在针对目标二进制文件进行初步检测时,PE结构分析工具通常会提示程序可能经过加壳或符号混淆处理。若直接套用常规脱壳工具,极易引发二次混淆或结构破坏,从而中断分析流程。实际上,该样本为典型的.NET托管程序,其IL代码特性决定了无需进行底层壳剥离,直接采用托管框架反编译器即可展开静态分析。
符号混淆还原与工具链配置
针对.NET样本,推荐使用ILSpy进行静态反编译,并配合dnSpy执行动态调试验证。初始反编译输出中,核心方法名与局部变量均呈现为无意义乱码,属于标准的标识符混淆手段。为快速恢复代码可读性,可引入de4dot执行反混淆操作。该工具能够自动化剥离名称混淆层与简单的控制流平坦化,使原始逻辑结构清晰暴露。
经反混淆工具处理并重新载入反编译器后,命名空间与方法签名已恢复正常,为后续的逻辑追踪奠定基础。
核心执行流程剖析
程序入口点主要包含数据准备、核心转换与结果校验三个阶段:
- 提取系统当前小时数并递增,转换为整型参数。
- 加载硬编码密钥字符串,调用核心转换例程生成目标校验串。
- 捕获终端输入,与生成的校验串进行严格比对。
入口函数逻辑可重构如下:
static void Main(string[] args)
{
string targetResult = null;
int timeOffset = DateTime.Now.Hour + 1;
const string seedKey = "CreateByTenshine";
BuildTargetString(seedKey, timeOffset, ref targetResult);
string userInput = Console.ReadLine();
if (userInput == targetResult)
{
Console.WriteLine("u got it!");
}
else
{
Console.Write("wrong");
}
}
核心转换逻辑集中于BuildTargetString方法。该方法逐字符遍历种子密钥,并在内部嵌套循环中执行连续的位运算。具体而言,每个字符的Unicode编码会与预设素数数组中索引为1至14的元素依次进行异或运算。每次运算的输出直接作为下一轮迭代的输入,形成链式变换。所有字符处理完毕后,将拼接的中间字符串送入哈希处理模块。
static void BuildTargetString(string source, int offset, ref string finalOutput)
{
StringBuilder buffer = new StringBuilder();
foreach (char originalChar in source)
{
char transformChar = originalChar;
for (int index = 1; index < 15; index++)
{
transformChar = (char)ApplyXorMatrix(transformChar, index);
}
buffer.Append(transformChar);
}
finalOutput = GenerateChecksum(buffer.ToString());
}
哈希处理模块负责将中间字符串计算为MD5摘要,并附加标准格式包装:
static string GenerateChecksum(string rawData)
{
byte[] byteData = Encoding.ASCII.GetBytes(rawData);
using (MD5 engine = MD5.Create())
{
byte[] digest = engine.ComputeHash(byteData);
string hexFormatted = BitConverter.ToString(digest).Replace("-", "").ToLower();
return $"flag{{{hexFormatted}}}";
}
}
异或矩阵模块通过静态常量表实现映射:
static int ApplyXorMatrix(int charValue, int tableIdx)
{
int[] primeLookup =
{
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113
};
return primeLookup[tableIdx] ^ charValue;
}
解密脚本实现
编写还原脚本时,需严格遵循链式异或的依赖关系。循环内部必须保证中间变量状态的正确传递,避免因作用域覆盖或重新赋值导致的前置计算丢失。
以下为经过逻辑优化与结构重写的Python求解脚本:
import hashlib
def resolve_challenge():
base_key = "CreateByTenshine"
xor_sequence = [3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
transformed_output = []
for char_code in map(ord, base_key):
current_state = char_code
for delta in xor_sequence:
current_state ^= delta
transformed_output.append(chr(current_state))
payload = "".join(transformed_output)
digest = hashlib.md5(payload.encode("ascii")).hexdigest()
return f"flag{{{digest}}}"
if __name__ == "__main__":
print(resolve_challenge())
执行脚本后即可获取最终校验标识:
flag{967dddfbcd32c1f53527c221d9e40a0}