-
主要参考自 https://blog.csdn.net/Vie0211/article/details/123671862
我和这位博主基本上是差不多的东西,但是没存图片,就直接借用这位博主的图片了。
在解密之前先用在线的 php zend 解密跑一下,看一看你是什么版本,我这里就是针对 5.6 去做的
解密环境搭建
我是 Debian11 x86_64
先前往github下载以下两个项目文件:
-
https://github.com/Tools2/Zend-Decoder -
https://github.com/lighttpd/xcache
第一个项目直接 clone,第二个项目下载 release 版本。
用 unzip 解压第二个项目,接着安装 php5.6-dev 版本,此处要尽量保证 php 环境干净
sudo dpkg -l | grep php // 查看当前 php 信息
sudo apt-get purge php7.4-* // 删除所有 php7.4 相关的包
安装 php5.6-dev
// 添加源
sudo apt-get install apt-transport-https lsb-release ca-certificates
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list
// update
sudo apt-get update
// 安装 php5.6-dev
sudo apt-get install php5.6-dev
当安装好php后,再前往xcache目录进行xcache的编译:
当终端位于 xcache 目录时,执行下面命令:
patch -p1 < ../Zend-Decoder/xcache.patch
这样的回显就是正常的了
然后再执行下面命令:
注意:如果上面php5.6-dev没有安装上,这里的phpize是无法执行的。
$ phpize
$ ./configure --enable-xcache-disassembler
sudo make
make后如果和上图相似,没有error等信息,即为make完成。这里编译完成之后,会在 xcache
的文件夹下的 /modules
中生成一个 xcache.so
文件,把它复制进去
sudo cp xcache.so /usr/lib/php/20131226/
-
接着要配置一个 .so
依赖文件
zend下载:https://www.zend.com/downloads/zend-guard-loader FAMILY选择:Linux PLATFORM选择:Linux 64-bit (这里根据个人ubuntu位数进行选择) VERSION选择:7.0.0(PHP 5.6)
在下载的时候会让你填写邮件等信息,随便填写即可。
下载好之后将其中的 ZendGuardLoader.so
文件复制到 php 的 lib 中,这个 php lib 的名称也是一样的
sudo cp ZendGuardLoader.so /usr/lib/php/20131226/
配置完成之后,ls php lib 文件夹如图
确保/usr/lib/php/20131226/
目录下存在xcache.so
和ZendGuardLoader.so
文件,下面在php.ini中编写如下代码:
最好使用vim打开
php.ini
文件,因为可以使用 G 跳到文件末尾处。
sudo vim /etc/php/5.6/cli/php.ini
// 添加内容如下:
[Zend]
extension=xcache.so
zend_extension = ZendGuardLoader.so
//:wq 保存退出vim编辑器
当这一步配置好后,在终端执行php,查看是否存在报错信息,这里 php 命令输入完之后会响应很久,直接 ctrl+c 即可,只要不报错就 OK 了
如果如上图没有保存信息,说明部署完成。
如果出现如下图信息说明在复制两个so文件的时候没有复制对位置或者复制少了,具体看报错给予的信息:
文件解密
前往 Zend-Decoder 项目目录,然后使用 php 执行其项目中的 index.php
文件进行解密:
php index.php ../webmail.php
cat 下原本文件看看,是乱码
批量解密
这里是那位师傅写的一个批量解密的 python 脚本,这个脚本会将需要解密文件所在目录进行遍历,对加密的 php 文件进行解密,非加密或非 php 文件进行复制,并且会将其目录结构也一并复制过去。
脚本在使用的时候,需要在该脚本目录下创建两个目录,一个是 source,另一个是 destination,其中source 目录是放入你需要解密的文件或者目录,destination 目录是解密后文件的存放位置。
# !/usr/bin/python
# -*- coding:utf-8 -*-
# __Author__: VVzv
import os
import shutil
decode_php_file_path1 = "index.php"
decode_php_file_path2 = "index2.php"
def dirExist(des_file):
file_dir = "".join([i+"/" for i in des_file.split("/")[:-1]])
if not os.path.exists(file_dir):
os.makedirs(file_dir)
def fileFilter(src_file_dir, des_file_dir):
src_file_list = []
for root, dirs, files in os.walk(src_file_dir):
for file in files:
filename = os.path.join(root, file)
if os.path.splitext(file)[1] == '.php':
src_file_list.append(filename)
else:
des_filename = filename.replace(src_file_dir, des_file_dir)
dirExist(des_filename)
shutil.copy(filename, des_filename)
return src_file_list
def decoder(filename):
# <?php @Zend;
cmd1 = "php {} {}".format(decode_php_file_path1, filename)
cmd2 = "php {} {}".format(decode_php_file_path2, filename)
print("33[36m[*] 正在进行解密:{}".format(filename))
save_name = filename.replace("source", "destination")
info = os.popen(cmd1).read()
if "<?php @Zend;" not in info and "file not foud!" not in info:
dirExist(save_name)
with open(save_name, "w") as f:
f.write(info)
else:
info = os.popen(cmd2).read()
if "<?php @Zend;" not in info and "file not foud!" not in info:
dirExist(save_name)
with open(save_name, "w") as f:
f.write(info)
else:
shutil.copy(filename, save_name)
print("33[35m[-] 解密失败[{}]33[0m".format(filename))
if __name__ == '__main__':
f_list = fileFilter("source", "destination")
for f in f_list:
decoder(f)
如我有一个 www
目录,其中的 php 文件采用的是 zend5.6
加密的,其该目录是一个网站目录,那么这时,只需要将这个www
目录复制到source
目录中,然后执行脚本即可:
如其结构如下:
然后运行脚本,看起来 eoffice10 也可以如此破解
其中可能会遇到一些有问题的文件,有些是软连接之类的配置文件,这种需要直接删除,不然会影响脚本。
小结
这位师傅写的很好,我的情况也基本与他完全一致,写的细的文章不踩坑,实在是太舒服了
原文始发于微信公众号(She11ud0 安全团队):记一次 PHP Zend Engine 5.6 源码解密
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论