freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

【初审通过,可编辑】Webshell通用免杀的思考
2020-04-30 17:36:20

本文经授权转载自“七夜安全博客”公众号

作者:七夜安全



前言

良好的习惯是人生产生复利的有力助手

最近一段时间,看了很多认知方面的书,对我的改变还是很大的。

之前看待事物总是看其一角,做技术也是囿于一面,思维不是很开阔,经过不断地看书,思考,认知慢慢有了 改变,获益良多。

作为技术人员,我的建议是不要总是看技术书籍或者一心研究技术,多看看哲学,认知,效率,商业方面的书籍,可以让你看到人生多种可能性,同时反哺技术上的视野和思考模式。

现在遇到技术项目,尽量不再立即着眼于解决它,而是选择如何看待它,比如会问自己一些问题:

  • 它是否真是一个全新项目 ?
  • 它的存在是否合理 ?
  • 它的边界是什么?

。。。。。。

前面只是一些自己的感悟,如果对大家有启发,有帮助的话,那就最好不过了。言归正传,在上一篇文章中,讲解了webshell如何绕过RASP的方法论,并根据方法论设计了 webshell。

虽然有一些绕过方法,但RASP依然是webshell检测中最强的存在,如果再和HIDS联动,那些绕过方法在数据捕获层面都会失效,纵深防御不是说说而已

今天说的承接上文,依然是webshell的绕过,不过不叫绕过,叫免杀。对付的不再是RASP(实时检测手段),而是其它离线的检测手段,目的是以攻促防。

这次讲的内容主要是方法论,我给的是思考方法,而不会直接给一个通杀的webshell,因为没有意义。如果你还在追求这种浮躁的方式,只能说还是没脱离“脚本小子”的范畴。

一.思考

检测方案的边界

在绕过任何一个检测引擎之前,思考是很关键的,尤其是新手。新手特别喜欢的干的是 找一大批样本上传,看看能不能命中一个,这其实对你是没有任何提高的。首先要做的是思考,下面我画了一张思维导图,理了理思路。 

cef67964abad41c283f7436cb762446a

思考过程分为了四个部分,层层递进,应用在其他方案绕过上,也是可以的,接下来我会根据这四个部分进行解释。

二.认知

知己知彼

任何一个检测引擎的大部分检测手段,都是已知的,就算有创新,那毕竟是很少的一部分,因此首要的入手点是熟悉已知的主流检测方案,对已知的检测方案至少有一个原理性的了解。在之前的《Webshell检测能力进化笔记》 一文中,简要概括了主流的检测手段及缺陷:

1.基于正则文本特征检测

初期对付webshell基本上都是这种方案,根据已知webshell使用的函数和参数,使用正则表达式制定相应的黑规则。

但是正则文法表达能力不足,加上webshell语法灵活,很容易通过混淆绕过这种方式。

2.基于统计特征的文本检测

之后为了对付混淆,人们把视野放到了统计学上,通过统计文本熵,字符串长度,特殊符号个数,重合指数,压缩比等信息制定告警阈值,在对付混淆上有一定的威力。之后随着机器学习的兴起,阈值设置就交给了算法。

但是这种方式着眼于全局,无法顾及局部细节,将混淆的恶意代码插入到正常文件中,基本上就失效了。

3.基于AST的语法特征检测

为了弥补统计特征的不足,进一步深化,进行语法检测,关注于每个函数和参数,这种方式精确,误报较少。但是对于PHP这种动态特性很多的语言,检测就比较吃力,AST是无法了解语义的。

4.动/静态符号执行

其实本质上是数据流分析, 如果用户可控的外部变量进入特殊的函数,那么我们就可以判定这个样本的危险系数很高。举例:

<?php$func = $_REQUEST[i];$arr = array('test'=>1,$_REQUEST[j]=>2);uasort($arr,$func);

对数据流进行跟踪分析的话,就会得出如下有向图,这种检测方法覆盖率高,误报少。

e89ab62aecbd4007a8fab67a67936fed

数据流分析分为静态和动态两种,静态分析通过语法树遍历的方式,对数据流进行跟踪,如果做的好的话,可以对混淆的变量和函数进行还原。动态分析不用做变量还原,但难度更高,不过基本原理是一致的。

5.机器学习/深度学习 

这个不是很主流,也算一种辅助手段,特征主要来源于opcode序列和文本分词,遇到问题和2类似。

6.沙箱

沙箱在这方面检测就比较鸡肋了,输入参数未知,沙箱是很难发现威胁的,只是作为一个补充。

这几种检测方案都属于离线检测方式,除了他们自身解决方案的缺陷外,还有一个本质的缺陷就是信息不完备,我们给webshell传参,它是无法得知的。正是因为这个原因,以上检测方案的效果,从原理上是弱于RASP的。(RASP的性能如果做的很高就好了,就不需要其他的了)

三.“敌人”

在了解主流的检测方案后,并不急于设计免杀webshell绕过引擎,你需要了解你的对手,这个时候需要进入探测阶段,是非常重要的一环。我一般从五个方面着手,包括覆盖率,误报率,容忍度,验证已知手段,猜测未知手段。

1.覆盖率,误报率,容忍度

我一般会准备一些常见的webshell,但是种类必须不同,测试一下引擎的覆盖率。

接着制造一些有敏感函数,但是无恶意功能的样本,测试一下引擎的误报率。例如:

eval("echo 2323;")

最后,找一些正常样本,然后不断添加敏感函数和参数,测试一下引擎的容忍度。

2.验证已知手段

已知手段主要分为两大类,静态和动态,每种方式又包含很多小类,如何验证具体手段属于静态或者动态中的哪一个?

选择一个普通的webshell,不要一直换,然后对这个webshell的函数名,参数名进行逐步隐藏,一一验证已知的手段。

<?php echo shell_exec($_GET[‘cmd‘]);?>

3.猜测未知手段

既然是猜测,那就看造化了,还是建议不要一直换webshell,只会让你混乱,而是逐步变形,有创新手法也不会离开静态和动态的圈子。

四.“磨刀”

通过上面的手段,对引擎有了个基本的了解,下面要积累自己的力量,磨刀霍霍了。

1.公开免杀方法

这时候要去涨涨经验了,看看其他人是如何绕过各种检测引擎的,他们对付的是哪种检测手段,需要大家自己总结。我给大家准备了一下资料,足够大家学习一波了。

https://xz.aliyun.com/t/7151 https://xz.aliyun.com/t/3959 https://klionsec.github.io/2017/10/11/bypasswaf-for-webshell/ https://blkstone.github.io/2016/07/21/php-webshell/ https://www.cnblogs.com/littlehann/p/3522990.html

只是看文章还是不够,去github上找一下大家贡献的webshell,看看他们的免杀有什么可取之处。 

4b8a8f9abd404ed5b6b1d735a65cd9f2

2.php手册

php手册是最权威的php资料,中文版网址:https://www.php.net/manual/zh/

 

23284bbb40f14f749157cd3330ebeb97

php的语法灵活,内置函数丰富,大家通过php手册可以随时查询自己想要的功能。

3.练手

1、http://www.d99net.net/down/WebShellKill_V2.0.9.zip

2bba4a8c0c994642836cf61d4769ef30

2、百度WEBDIR+

https://scanner.baidu.com/ 

8de6235b78ca4bb284536b1d0bde6cd5

3、河马

https://www.shellpub.com/ 

bacf66cd83e0440ca55894553bc3625d

4、Web Shell Detector

https://github.com/emposha/PHP-Shell-Detector

8ec49ea5c88141a0897c642a4ebd2613

5、CloudWalker(牧云)

https://webshellchop.chaitin.cn/

https://github.com/chaitin/cloudwalker

c6d720f72d4744c4a22123da9559c597

6、深度学习模型检测PHP Webshell

http://webshell.cdxy.me/

05d5b97829f34093b6a80602ebf1dbc1

五.精准打击

对引擎也熟悉了,对免杀的知识也有了积累,下面就可以根据缺陷和问题进行降维打击了。一般情况下,很多人绕不过的时候,有时候会问能不能给点思路,引擎把XXX给封锁了,遇到XXX就会告警。

其实你发现的问题就是解决问题的方向

举个例子:

<?phpsystem("ls");

样本中出现system就会报警,那你要做的就是根据你发现的问题,将system隐藏掉。可以变量替换,可以字符串拼接,旋转加解密。

<?php$a='sys'."tem"$a("ls");

这时候还报警的话,那就可能会有静态变量还原,动态分析的可能。这个时候再变化,自己写函数生成 system,同时需要外部变量的参与才行。

<?php$a='sys'.$_GET[i];$a("ls");

就这样按照发现的问题,结合现有手段,一步一步变换。

本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者