看我如何玩转PHP代码加密与解密

article/2025/8/22 13:36:51

参考文献:

https://xz.aliyun.com/t/2403

前言

两次比赛,两个题目,两种方式,两个程序。

一切PHP的代码终究是要到Zend Engine上走一走的,因此一切PHP的源码加密都是可以被解密的。(不包括OpCode混淆-VMP)

代码混淆

比较恶心人的一种处理方式,也不太算是加密。

单独拿出来是为了说明代码混淆和代码加密是两种方式。

本质是是对变量进行乱七八糟的修改,多用动态函数处理。处理应该没什么难度,就是比较复杂,浪费时间精力。

混淆方式是按照套路随机生成相关动态函数,替换明文函数,然后批量修改变量名。

该法常与代码加密联合使用。

代码加密解密

用PHP代码进行PHP代码的加密,套了层壳。大多数代码加密都进行了一定的代码混淆,不同的加密工具也有不同的混淆。

  • 壳混淆
  • 代码混淆
  • 壳和代码都分别混淆

常见加密工具

  • phpjiami

加密

源码 -> 加密处理(压缩,替换,BASE64,转义)-> 安全处理(验证文件 MD5 值,限制 IP、限域名、限时间、防破解、防命令行调试)-> 加密程序成品,再简单的说:密文源码 + 自解密外壳 == 密文代码

加密方式

  1. 独立加密程序统一对明文代码进行加密处理

解密

加密也好,混淆也罢,终归是要变成Zend Engine能处理的源码,该“加密”方法的的根本是通过把代码解密并通过eval等函数执行代码。

因此,只要用HOOK EVAL大法,将相关可执行代码的函数Hook住就能拿到其中需要执行的数据,也就是我们想要得到的源码。

调用eval等代码执行的函数,最终会调用PHP内核zend_compile_string函数。

通过PHP本身提供的一个HOOK机制,写个插件轻松搞定。

// 声明一个临时的 compile_string 函数
static zend_op_array *(*orig_compile_string)(zval *source_string, char *filename TSRMLS_DC);
// 在 PHP_MINIT_FUNCTION 中替换
orig_compile_string = zend_compile_string;
zend_compile_string = phpjiami_decode_compile_string;
// 在 PHP_MSHUTDOWN_FUNCTION 中恢复
zend_compile_string = orig_compile_string;
// 提取 compile_string 中的代码并保存
static zend_op_array *phpjiami_decode_compile_string(zval *source_string, char *filename TSRMLS_DC)
{int c, len, yes;char *content;FILE *fp = NULL;char fn[512];if (Z_TYPE_P(source_string) == IS_STRING) {len  = Z_STRLEN_P(source_string);content = estrndup(Z_STRVAL_P(source_string), len);if (len > strlen(content))for (c=0; c<len; c++)if (content[c] == 0)content[c] = '?';sprintf(fn, "/tmp/%s.php", zend_get_executed_filename(TSRMLS_C));fp = fopen(fn,"a+");if (fp!=NULL)fprintf(fp, "<?php\n%s\n?>\n\n", content);fclose(fp);}return orig_compile_string(source_string, filename TSRMLS_CC);
}

案例

Challenge: PWNHUB 公开赛 / 傻 fufu 的工作日 Writeup

扩展加密解密

将文本源码进行加密存储,在使用的时候通过扩展实现解密。

常见加密工具

  • pm9screw
  • pm9screw_plus

加密

源码 -> 加密处理(对称/非对称加密、自定义加密)-> 加密成品:密文代码

加密方式

  1. 独立加密程序统一对明文代码进行加密处理
  2. 扩展存在加密解密功能,执行前判断源码是否经过加密处理,如果没有就进行加密

解密

还是那句话,一切的源码都要到Zend Engine上执行,密文也得解密了再执行。那么在最终的执行之前,提取出来就可以了。

因此Hook住zend_compile_file函数就可以了。

但是其中有一个坑点,PHP的扩展是“栈”加载的,也就是先加载的先Hook,后执行。我们需要获取到解密之后的内容,所以需要让“加密”插件先执行,也就是我们的解密插件要先加载。

要实现这个操作,只需要在INI配置文件中先写我们的插件。(不保证)

extension="decode.so"
extension="encrypt.so"

这个方式需要能够加载执行encrypt.so,我觉得这个还是可以实现的。通过一定手段获取到encrypt.so和密文源码以及服务器,中间件相关信息(版本等)。

利用Docker运行一个基本相同的环境应该是可以做到的。

// 声明一个临时的 compile_file 函数
static zend_op_array *(*orig_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
// 在 PHP_MINIT_FUNCTION 中替换
orig_compile_file = zend_compile_file;
zend_compile_file = phpjiami_decode_compile_file;
// 在 PHP_MSHUTDOWN_FUNCTION 中恢复
zend_compile_file = orig_compile_file;
// 提取 compile_file 中的代码并保存
static zend_op_array *phpjiami_decode_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC){char *buf;size_t size;if (zend_stream_fixup(file_handle, &buf, &size TSRMLS_CC) == SUCCESS) {FILE *ff = NULL;int i=0;php_printf("code size :\n%d\n\nsource code :\n%s\n\n", size, buf);ff = fopen("/tmp/decode.php","a+");if (ff!=NULL)for(i = 0; i <= size; i++)fprintf(ff, "%c", buf[i]);fclose(ff);}return orig_compile_file(file_handle,type TSRMLS_DC);
}

案例

Challenge: SCTF2018 BabySyc - Simple PHP Web Writeup - L3m0n

  • phpinfo

  • login.php

OpCode混淆

一种是比如Swoole Compile的方式,部分脱离了zend虚拟机,对opcode做了混淆,这就比较像是vmp的一种方式。

加密方式

  1. 独立加密程序统一对明文代码进行加密处理(猜测)

解密

我不会啊!emmmmmmm

参考

  1. phpjiami 数种解密方法 - PHITHON
  2. Decrypt php VoiceStar encryption extension - 小鹿师傅
  3. PHPDecode 在线解密工具 - Medici.Yan
  4. Decoding a User Space Encoded PHP Script - Stefan Esser
  5. PHP代码加密技术 郭新华 PHPCON2018 - swoole郭新华

http://chatgpt.dhexx.cn/article/AFADCZwX.shtml

相关文章

一文打尽PHP代码加密方式

原文地址 温馨提示&#xff1a;世界上没有破不了的密码&#xff0c;如果有那也只是时间问题。 我们能做的只是增加破解时间。如果这个破解时间大于一个人的寿命&#xff0c;那么这个加密方式肯定是成功的。 对于加密的程序&#xff0c;就像破解者需要了解、猜测编写者的思路…

大数据运维工程师面试

当前你们公司使用的Hadoop版本是什么 ambari2.5.1 Hadoop 2.7.3.2.6.2.14-5HDFS常见的数据压缩格式有哪些&#xff0c;介绍其中一种详细的实现方式 1 gzip压缩 优点&#xff1a;压缩率比较高&#xff0c;而且压缩/解压速度也比较快&#xff1b;hadoop本身支持&#xff0c;在…

Linux运维工程师常见基础面试题

1、tcp三次握手四次挥手详解 TCP是一种面向连接的协议&#xff0c;通信前需要建立连接&#xff0c;通信结束后需要释放连接。TCP通过三次握手建立连接&#xff0c;四次挥手释放连接。 三次握手&#xff1a; 1、客户端向服务器发送SYN包&#xff0c;表示请求建立连接。 2、服务…

运维工程师面试总结(含答案)

运维工程师面试总结 原文链接&#xff1a;https://www.cuiliangblog.cn/detail/article/2 一、linux 1. linux系统启动流程 第一步&#xff1a;开机自检&#xff0c;加载BIOS第二步&#xff1a;读取&#xff2d;&#xff22;&#xff32;第三步&#xff1a;Boot Loader grub…

Linux运维工程师面试题(1)

文章目录 Linux运维工程师面试题&#xff08;1&#xff09;1 别名、内部命令、外部命令的执行顺序2 linux 系统启动流程3 破解用户密码的方法4 忘记 grub 密码怎么解决5 硬盘空间满了怎么处理&#xff0c;怎么找到硬盘中的大文件6 硬盘明明有很多空间&#xff0c;为什么无法存储…

Linux运维工程师面试题整理

1.Nginx反向代理&#xff0c;负载均衡&#xff0c;动静分离&#xff0c;工作原理及优化 nginx配置反向代理。 vim Nginx.conf Server模块中配置 Listen 80 Server_name ip; 在server段里面的location加上proxy_pass http://ip:端口; Nginx配置完成后重启一下nginx。 配…

FastReport打印标签

1、选择标签向导 2、在这里可以选择自己想要的标签布局&#xff0c;也可以点击左下角的自定义标签 3、点击自定义标签后&#xff0c;可以自定义自己想要的标签 4、点击确定之后&#xff0c;可以在制造商找到自定义&#xff0c;选择自定义的标签1 5、然后可以在数据区自定义想要…

深度学习训练数据打标签过程

深度学习训练数据打标签过程 为了获取大量的图片训练数据&#xff0c;在采集数据的过程中常用视频的方式采集数据&#xff0c;但对于深度学习&#xff0c;训练的过程需要很多的有有标签的数据&#xff0c;这篇文章主要是解决视频文件转换成图片文件&#xff0c;并加标签&#…

k8s-节点打标签

node标签设置后&#xff0c;pod可以根据要求让pod调度到想要的节点上运行&#xff0c;或者不在某节点运行。或者确保pod调度到具有高性能&#xff08;比如ssd的机器&#xff09;的节点山上。 1.展示节点标签&#xff1a; kubectl get node --show-labelstrue2.添加节点标签 …

python 图片数据集批量打标签

1.数据集介绍 OutdoorScene数据集&#xff1a;http://people.csail.mit.edu/torralba/code/spatialenvelope/ This dataset contains 8 outdoor scene categories: coast, mountain, forest, open country, street, inside city, tall buildings and highways. There are 2688…

打印标签时如何解决打印偏移

我们在打印标签时&#xff0c;使用的纸张一般都是不干胶卷纸&#xff0c;这样的卷纸又有单排、双排、三排和四排的规格。这些不同规格的标签纸在条码打印中经常会出现打印偏移的问题&#xff0c;甚至会跳纸&#xff0c;遇到这样的情况该如何调整呢&#xff1f;小编下面详细介绍…

视频打标签算法探讨

随着内容时代的来临&#xff0c;多媒体信息&#xff0c;特别是视频信息的分析和理解需求&#xff0c;如图像分类、图像打标签、视频处理等等&#xff0c;变得越发迫切。目前图像分类已经发展了多年&#xff0c;在一定条件下已经取得了很好的效果。本文因实际产品需求&#xff0…

labelImg打标签教程

前言: 打标签的精度&#xff0c;会直接影响目标检测算法最终的识别准确率 安装: labelImg是图片标注软件&#xff0c;用于数据集的制作、标注等等。 在cmd中依次运行以下命令&#xff1a; pip install PyQt5 -i https://pypi.tuna.tsinghua.edu.cn/simple/ pip install pyqt5-t…

Docker篇之镜像打标签tag

日常线上活动中&#xff0c;当我们对系统进行开发时&#xff0c;做容器化管理&#xff0c;因为每一个版本不同&#xff0c;可能随着业务量的产生&#xff0c;需求的迭代更新&#xff0c;不同版本所需要的环境不同。 因此&#xff0c;为了满足这样的问题&#xff0c;我们通常做的…

K8S给节点打标签和打污点

打标签 kubectl label node node名 key=value kubectl label node node1 env-role=prod查看标签 kubectl get nodes --show-labels打污点 kubectl taint node node名 key=value:污点三个可选值 NoSchedule : 一定不被调度 PreferNoSchedule : 尽量不被调度 NoExecute : 不…

机器学习 数据预处理之数据打标签

工作内容&#xff1a; 1.读取pdf文档内容 2.分页显示 3.每个数据后设置下拉框供手动打标签 4.数据录入txt文档 代码&#xff1a; import math import os import tkinter as tk from tkinter import * import tkinter.ttk as ttk from tkinter.messagebox import * import …

Excel中批量生成标签,批量打印标签。按指定模板批量打印标签

&#xff11;.问题概述 工作中经常需要将产品明细表转换成标签&#xff0c;贴在送货单上&#xff0c;或者将学生成绩转换成标签打印出来发送给学生。 例如在下图中有若干产品的送货信息&#xff0c;要求按图2的模板批量打印。 图1 送货信息 图2 标签模板 要实现此类需求&…

SVN打标签方法及在此过程中的问题处理

所谓的“打标签”&#xff0c;我个人的理解是&#xff1a;项目取得了阶段性成果&#xff0c;需要保存在标签&#xff08;tags文件夹&#xff09;中&#xff0c;以备不时之需。我采用的打标签的方法是&#xff1a; 1、在SVN客户端打标签。前提是本地项目与SVN Server上的项目无…

图片打标签labelimg

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Windows安装二、使用步骤1.在cmd命令行中创建一个新的环境2.对图片打标签3.保存打标签的图片4.如何打开已经安装的labelimg 总结 前言 对图片打标签是数据…

使用Labelimg打标签

1.下载Labelimg &#xff08;1&#xff09;打开cmd命令行 用Windowr打开命令行&#xff0c;输入cmd命令。 &#xff08;2&#xff09;输入命令 pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple -i的后半部分是清华镜像源地址。 &#xff08;3&#xff…