PHP 混淆代码解密记录

  1. 前言
  2. 分析
  3. 解密
  4. 结果
  5. 参考

前言

逛论坛看到一个师傅发了个《关于解密之后未进行发放 tubi》的帖子,顺着找到了原讨论。帖子只给了结果,没有解密方法,所以试试用 echo 大法能不能解开。

分析

原代码省略长字符串后是这样:

<?php
$table = base64_decode("...");
$decoder = $table[3].$table[6].$table[33].$table[30];
$decoder .= $table[22].$table[36].$table[29].$table[26];
eval($decoder("..."));
?>

函数名通过字符表索引动态拼接,真正的代码放在 eval() 参数中。

把 eval 改成 echo:

-eval($decoder("..."));
+echo($decoder("..."));

输出仍然是 PHP:

$payload = "...";
eval('?>'.$decoder($transform($payload)));

把输出插回 ?> 前,接着把新一层的 eval 改成 echo。后面又出现两个结构相同的代码块,输出分别要插在 ?> 前后。

解密

规律已经比较明显:把 eval 改成 echo 执行;输出以 <?php 开头就接在尖括号外,否则接在括号内。不过一直手工重复不知道要解多少次,还是写个脚本跑。

当时的思路:

  1. 把 eval 改成 echo。
  2. 执行 PHP 文件拿到输出。
  3. 把输出插回 PHP。
  4. 删除上一轮的 echo 语句,继续循环。

脚本:

import os
import re
origin_data = ""
new_data = ""
file = "unknown.php"

with open(file, "r", encoding="utf-8") as f:
    for line in f:
        if "echo" in line:
            line = re.sub(r"echo.*?;", "", line)
        if "eval" in line:
            line = line.replace("eval", "echo")
        origin_data += line

with open(file, "w", encoding="utf-8") as f:
    f.write(origin_data)

result = os.popen(f"php {file}").read()
print(result)

with open(file, "r", encoding="utf-8") as f:
    new_data = f.read()

new_data = re.sub(r"\?>$", "", new_data)

with open(file, "w", encoding="utf-8") as f:
    if "<?php" not in result:
        f.write(new_data + result + "?>")
    else:
        f.write(new_data + result)

结果

执行 4 次就出了源码,看来不太难,手动其实也能解开。结果和帖子里师傅解出来的一样。

第四轮解密结果对比,作者联系方式已打码

参考

T00ls 原讨论


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。

文章标题:PHP 混淆代码解密记录

字数:444

本文作者:

发布时间:2022-11-27, 03:46:00

最后更新:2026-08-26, 21:18:00

原始链接:https://cnlnn.pages.dev/posts/php-obfuscated-code-decryption/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。