十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

在线PHP解密工具V1.2静态版源码解析与应用

在线PHP解密工具V1.2静态版源码解析与应用 简介在线PHP解密工具V1.2静态版源码是一款面向PHP开发者、安全研究者及站长的轻量级在线解密工具可还原部分goto、PHPJiaMi、Enphp、vidun、phpdp神盾、tianyiw等常见PHP混淆与加密代码。资源共6个文件、压缩包仅411KB核心由4个JavaScript文件组成承担前端解密算法与交互逻辑另含2个CSS文件负责界面样式整体为静态版源码无需数据库和复杂环境解压即可运行部署门槛很低。资源已有375人浏览学习界面简洁适合作为独立测试工具或集成到内部管理后台使用。通过源码可以完整梳理各类加密类型的识别与处理流程方便二次开发为自定义解码服务工具还内置未知样本自动留存机制用于持续改进解密能力。使用前需要留意服务条款中对样本数据收集的约定适合希望复现解密过程、研究PHP代码保护机制、搭建辅助工具或学习前端解密切面的技术人员使用。1. 在线PHP解密工具V1.2静态版源码到底解决哪类问题接手别人交接的系统时我经常是先开一个在线PHP解密工具V1.2静态版源码的页面把一段段被加密过的 PHP 贴进去——倒不是真指望它干掉商业加密壳而是它能把日常二开、数据恢复、代码审计里常见的 eval 链和 base64 噪音还原成几句能看懂的 PHP。静态版是纯文件形式没有数据库PHP 7.2 起直接扔进 Web 根目录就能跑适合在隔离网络里做代码分析。它的核心工作清晰确认字符串是不是加密外壳是否可以剥离剥完后哪些危险函数还留在里面。对 PHP 开发者、二开者和做交付物复用的运维人员这是处理乱码 PHP 的第一道工序。2. 部署静态版内置服务器、免数据库与第一次粘贴解密“静态版”这个命名表示页面逻辑和后端解码都打包在几个 PHP 文件中运行时不需要 MySQL、Redis也不依赖 Composer。V1.2 这类版本里我一般把“静态”理解成入口文件负责接收粘贴内容处理文件负责还原配置文件负责限制执行次数和超时三者之间没有第三方框架。把整个目录放进 Web 根目录就能访问所以很适合挂在内网跳板机或者一台废弃测试机上长期使用不去碰现有业务数据库。2.1 认识“静态版”命名为什么它更适合当本地调试工具真正需要解开一段 PHP 的情况多数发生在临时调试阶段线上报错但没法停服务、供应商交付的文件行为异常、历史遗留代码需要逆向理解。把这些场景丢给公网在线工具反而多了麻烦——粘贴的代码里可能带着危险调用你不想把分析样本上传到别人的服务器而 V1.2 这类静态版可以只监听本机回环地址请求不出网样本自然也不会外泄。另一个好处是容易修改。看到某一轮解密结果明显不对时直接改处理文件里的正则刷新页面再来一次比在远程页面反复调整参数快得多。这种“改一版试一版”的节奏正是“源码版”的价值所在它不是编译好的黑盒你能看到每一步还原用的是哪条规则。缺点随之而来没有数据库就存不了历史记录关掉页面结果就丢连续处理超大文件时内存会吃紧。所以我一般把它定位成调试工具而不是像审计平台那样做长期留存也不会拿它处理几十 MB 级别的日志。2.2 三行命令在本地把工具跑起来压缩包解开后目录里通常有 index.php、decode.php、config.php 三个核心文件外加一份说明文档。在 Linux 机器上启动 PHP 内置开发服务器mkdir -p ~/lab/php-decoder unzip php-decoder-v12-static.zip -d ~/lab/php-decoder cd ~/lab/php-decoder php -S 127.0.0.1:8899 -t .这里-S表示启动 PHP 内置 Web 服务器-t指定文档根目录为当前目录只监听 127.0.0.1局域网其他机器访问不到这对处理含敏感逻辑的样本很关键。如果确实需要让同网段另一台机器访问可以改成php -S 0.0.0.0:8899 -t .但建议同时加一层 Basic Auth用完立刻关进程。启动后浏览器访问http://127.0.0.1:8899/index.php页面就是一个大文本域加一个“解密”按钮。先用最小样本验证工具通不通echo ?php eval(base64_decode(cGhwaW5mbygpOw)); sample.php curl -s -X POST http://127.0.0.1:8899/index.php \ --data-urlencode code$(cat sample.php) \ --data-urlencode dodecode | tee result.html请求里code字段是待分析源码dodecode是动作标志。不同分发包的字段名可能叫src或input如果没返回结果先打开 index.php 看它读取的是哪个$_POST键。成功时在 result.html 里看到的应该是phpinfo()而不是 eval 包裹体。之后拿到真正的目标文件贴进去按同样方式提交即可。2.3 表单字段、请求限制与超时控制静态版在线工具的页面结构常见做法是把输入和输出放同一个表单里输入用 textarea输出放到只读 textarea 或 pre 标签。需要注意三个边界条件第一PHP 默认post_max_size是 8M超长样本会被截断导致解密结果少一半第二执行超时受max_execution_time控制多层嵌套的 eval 展开可能一次做 8 到 10 轮复杂样本会逼近超时第三输出体积没有上限时gzinflate 解压出十几 MB 文本会让页面卡死。常用的调整如下配置项默认值静态版建议值作用post_max_size8M128M避免大样本输入被截断max_execution_time300长链路多层解码不超时memory_limit128M512M防止大文本解压时内存溢出如果配置文件里还有MAX_DECODE_TIMES之类的常量把它调到 10 到 15配合set_time_limit(0)使用。更稳妥的做法是在处理文件末尾校验输出长度超过预设值比如 5 MB 时只显示前 4000 个字符避免把浏览器和 PHP 进程一起拖垮。3. 解密逻辑的破拆点base64 嵌套、eval 链与变量拼接还原把“解密”两个字拆开看大部分所谓加密 PHP 并不是真正的编译保护而是对源码做若干层编码再包进一个 eval 里执行。V1.2 在线工具所做的就是把这些编码依次剥掉把最终文本还给用户。理解这个顺序才能判断解密结果是否可靠。3.1 为什么先别碰 eval先做字符串还原直接运行被 eval 包裹的代码可以看到运行现象但拿不到可以阅读的文本。要得到展开后的源码本身第一步就是找到 eval、读到参数、对字符串参数做base64_decode或gzinflate再检查还原后是否还存在新的 eval 层。这种一层层往下剥的操作如果靠人工重复劳动很容易出错工具自动处理的好处是能循环多轮并在每一轮保存中间结果方便比对。这里有一条经验遇到多段拼接时优先提取最内层字符串。常见外形是eval(gzinflate(base64_decode(...)))最外层是 eval往里是 gzinflate再往里是 base64_decode。按同样的顺序逐层识别不要拿到整段直接执行因为执行可能带来副作用。调试时临时写一个file_put_contents(decode_log.txt, $decoded);观察中间层是常见做法正式部署时不需要保留这种日志。3.2 最小解码器循环展开常见链路下面这个函数与 V1.2 静态版的解码思路一致把几种已知包装模式写成规则每次匹配一层最多执行 8 轮直到输出里不再出现 eval 调用。?php function decode_chain(string $src, int $max 8): string { $rules [ /eval\s*\(\s*base64_decode\s*\(\s*([\])(.*?)\1\s*\)\s*\)/is, /eval\s*\(\s*gzinflate\s*\(\s*base64_decode\s*\(\s*([\])(.*?)\1\s*\)\s*\)\s*\)/is, /eval\s*\(\s*str_rot13\s*\(\s*base64_decode\s*\(\s*([\])(.*?)\1\s*\)\s*\)\s*\)/is, ]; for ($i 0; $i $max; $i) { foreach ($rules as $rule) { if (preg_match($rule, $src, $m)) { if (str_contains($rule, gzinflate)) { $decoded gzinflate(base64_decode($m[2])); } elseif (str_contains($rule, str_rot13)) { $decoded str_rot13(base64_decode($m[2])); } else { $decoded base64_decode($m[2]); } if ($decoded false || $decoded ) { break 2; } $src $decoded; continue 2; } } break; } return $src; }每条规则是正则表达式([\])(.*?)\1负责捕获字符串两侧引号并强制左右为同一种引号。i修饰符让 eval、base64_decode 关键字大小写不敏感s修饰符让点号可以匹配换行。每轮循环只剥一层防止把多个嵌套层一次性误合并max限制最大轮数避免载荷被设计成死循环时卡死 Web 进程。这不是万能实现。如果代码用动态变量拼接函数名比如$fbase.64_decode;规则匹配不到函数名就需要先做变量拼接还原。另外某些混淆会故意在 base64 串中间插入\r\n干扰正则处理前先用preg_replace(/\s/, , $m[2])把字符串内空白去掉再交给 base64_decode。3.3 不同编码特征对应的处理顺序与函数选择载荷特征典型外形第一步选择base64 直接包 evaleval(base64_decode(...))base64_decodegzip base64 嵌套eval(gzinflate(base64_decode(...)))先 base64 再 gzinflaterot13 外层包裹eval(str_rot13(base64_decode(...)))先 str_rot13 再 base64hex 字符串组装eval(\x66\x70\x69...)先 hex2bin再看结果变量拼接函数名$aba.se64;$a(...)先替换变量再重跑本表看到哪类特征就先按哪一列处理V1.2 静态版的核心代码基本就是这张表的程序化实现。处理完第一轮后要把结果放回 decode_chain 再跑一次因为 gzip 解出来的文本可能又是一个 base64 串。等到输出里不再出现 eval、base64_decode、gzinflate 这些关键词时才算基本还原结束。4. 用 token_get_all 二次校验解出来的 PHP语法、危险函数和行为边界在线工具解出来的代码不能直接当作可信源码使用。经过多层解码的文本在语法上可能是残缺的混淆器经常丢弃注释、打乱换行、在字符串里混入非法字符甚至构造一个语法根本不对的中间层。把解析工作交给 token_get_all能在运行前发现这些问题。4.1 解密完成后的第一分钟先做语法与字符校验拿到工具输出后我通常先把文本保存成 decoded.php然后跑一次php -l decoded.php。这是 PHP 内建 lint 命令能报出缺少分号、括号不匹配、字符串没闭合这类低级错误php -l decoded.php如果没有语法错误输出No syntax errors detected如果报错沿线号回看混淆前的原始文本确认是哪一层没剥干净。部分文件能通过php -l但里面存在T_BAD_CHARACTER说明字符串带有 PHP 无法识别的字节比如乱码或来源不明的空白。用 tokenizer 可以精确定位?php $tokens token_get_all($decoded); foreach ($tokens as $token) { if (is_array($token) $token[0] T_BAD_CHARACTER) { printf(发现非法字符行号%d\n, $token[2]); } }token_get_all是 PHP 的源码分词接口不执行代码只把源码切成 token 数组is_array($token)判断当前项是带行号的三元组还是单个字符T_BAD_CHARACTER是 PHP 7 以后用来标记无效字符的 token 类型。如果token_get_all本身返回布尔值通常意味着文本不能被解析这时要回到 3.3 的表格换一种还原路径。4.2 危险调用标记与运行环境隔离还原出来的 PHP 更重要的是检查危险调用。eval、include、require 这类动态执行相关操作一旦出现可能与注入逻辑有关。把 token_get_all 和 token_name 配合可以生成一份危险调用清单?php $watch [T_EVAL, T_INCLUDE, T_REQUIRE, T_INCLUDE_ONCE, T_REQUIRE_ONCE]; foreach (token_get_all($decoded) as $token) { if (is_array($token) in_array($token[0], $watch, true)) { printf(%d 行%s\n, $token[2], token_name($token[0])); } }token_name把 T_EVAL 这类数字常量转成可读名称输出形如3 行T_EVAL。看到这个结果先不要下结论要看 eval 里是否还是编码串如果还原完成后仍有 eval 包裹说明工具没剥到底需要再手动处理一层。真正干净的结果里eval 只出现在业务逻辑确实需要动态执行的合法代码中。安全边界同样重要。凡是来历不明的 PHP 文件都要在隔离目录、独立账号下运行不要直接放进生产环境根目录。解密工具本身不执行动态代码这一步没有问题但解出来的文件一旦运行里面的系统调用会以当前 PHP 进程权限生效。下表是我在审阅时最常检查的 tokentoken 常量典型写法关注点T_EVALeval($code)运行时执行任意代码T_INCLUDE/T_REQUIREinclude $path文件包含路径是否可控T_SYSTEM相关调用system($cmd)命令执行入口是否暴露T_EXITexit($msg)可能影响后续逻辑判断4.3 高频踩坑注释干扰正则与 BOM 误判第一个高频问题是正则里的点号跨行匹配注释。如果载荷字符串里带有//或/* */注释在s修饰符作用下(.*?)会把注释和后面的代码一起吞掉导致 base64 解码失败。出现这种情况时去掉s修饰符或先用preg_replace(/\/\*.*?\*\//s, , $src)临时移除注释再做解码。第二个问题是未转义的反斜杠和引号。HTML 表单提交时引号不会被动修改但 curl 命令行里如果整段样本没包好shell 会先吃掉一部分字符。表现是“解密后只剩半个文件”检查时优先看输出结尾是否完整出现?或原文件的最后一个分号。第三个问题是 UTF-8 BOM。在线粘贴时 BOM 不可见浏览器提交后处理函数收到的字符串开头多出三个字节base64_decode 会判定载荷无效。常见做法是在所有正则之前先执行preg_replace(/^\xEF\xBB\xBF/, , $src)去掉头部 BOM。我一般把它放在解码流程的最开始省去反复排查的时间。5. 把解密固化成批处理脚本CLI 版本与输出落盘在线页面适合处理零散样本。拿到一批目录、几十个待分析 PHP 文件时逐个复制粘贴太低效。常见做法是给同一个解码函数写一个 CLI 外壳让目录遍历、批量输出和结果对比自动化。5.1 命令行封装与参数表在 V1.2 静态版解压目录里新增一个 cli_decode.php复用前面 decode.php 中的 decode_chain 函数php cli_decode.php -i encoded_dir -o decoded_dir?php require_once __DIR__ . /decode.php; // 包含 decode_chain 所在文件 $opts getopt(i:o:, [in:, out:]); $srcDir $opts[i] ?? ($opts[in] ?? null); if (!$srcDir || !is_dir($srcDir)) { exit(用法php cli_decode.php -i 输入目录 -o 输出目录\n); } $outDir $opts[o] ?? ($opts[out] ?? decoded); if (!is_dir($outDir)) { mkdir($outDir, 0755, true); } $it new RecursiveIteratorIterator( new RecursiveDirectoryIterator($srcDir, FilesystemIterator::SKIP_DOTS) ); foreach ($it as $file) { if ($file-getExtension() ! php) { continue; } $src file_get_contents($file-getPathname()); $decoded decode_chain($src); $relPath ltrim(substr($file-getPathname(), strlen($srcDir)), /); file_put_contents($outDir . / . $relPath . .dec.php, $decoded); echo 已写入: . $relPath . .dec.php\n; }getopt同时支持短选项和长选项输入目录必须存在输出目录不存在时自动创建结果写到独立文件不覆盖原文件。RecursiveDirectoryIterator配合RecursiveIteratorIterator遍历子目录SKIP_DOTS跳过.和..ltrim去掉相对路径开头斜杠让输出目录结构与原目录一致。短选项长选项说明-i--in输入目录必填-o--out输出目录默认 decoded5.2 残留编码判断与文件确认批量跑完后把 .dec.php 与原文件做一次对比能快速发现处理失败的样本diff -q encoded_dir decoded_dir如果某个 .dec.php 与原文件完全一样说明 decode_chain 没有匹配到任何规则文件本身可能没有经过编码处理也可能是它属于另一类加密方案。后者不是 V1.2 这种纯文本还原工具能解决的问题不要继续堆叠正则。再看输出文件是否还残留关键调用grep -lE eval\(|base64_decode\(|gzinflate\( decoded_dir/*.dec.php有残留时回到 3.3 的表格更换处理规则没有残留且php -l通过这批文件就算还原完毕。批处理结果不要直接输出到生产网站目录保留 .dec.php 后缀与原始文件区分开审阅完成后确认每个文件的内容和原业务预期一致再决定是否替换。本文还有配套的精品资源点击获取
返回列表