回顾一下,我们是根据特征来检测webshell,已提到的特征有
(1)webshell 访问特征(主要特征) ——webshell提取阶段
(2)webshell path特征(辅助特征)——webshell提取阶段
(3)webshell 时间特征(辅助特征)——webshell提取阶段
(4)webshell Payload特征(辅助特征)——webshell提取阶段
(5) webshell 行为特征 ——webshell提取阶段
(6)webshell Reponse网页特征(内容特征/结构特征/视觉特征) ——webshell确认
最后还有一个特征——(7)webshell 攻击关联特征
“如果发现一个站点植入webshell,那远远不只一个站点被植入”
“如果发现一个站点被植入一个webshell,那远远不只一个webshell被植入”
搜索的优势在这个时候就可以发挥了,用确认webshell的访问者特征(IP/UA/Cookie),Payload特征,时间特征进行关联搜索,像这次xcode事件,360在构建了基础数据后(这里引用我非常崇拜的楚安一段话“永远记得,数据基础设施不是采一堆垃圾进来存下就完了,这背后是完善的数据生命周期解决方案。采集,etl,数据质量,快捷的数据交互这些才是最重要的。)利用搜索将数据关联起来,按时间线进行还原,讲述了个有意思的故事。
补充20151103:讲到搜索,有两个难点:
(1)如何将结果按时间线与行为关联展示
(2)基础数据设施建设的如何,比如说使用elasticsearch,保留多久的数据量,索引如何建立,集群的负载均衡等
(说到基础数据设施建设,超级心塞,先是hadoop碎片化导致的数据传输坑,然后再是日志字段飘逸变更的坑,还有不可解释靠重启解决了的集群莫名挂掉的坑,所幸身边有不少朋友提供帮助,特别感谢hadoop小王子)
二、实现
1. 数据获取
数据源:web访问日志
获取方式:如果存储在hdfs里,采用distcp的方式拷贝到模型计算集群上
p.s. 光数据的获取,就遇到了很多坑,不同版本的hadoop之间的数据传输(hadoop碎片化的问题,也是工程师文化导向的产物之一,都爱用开源的东西去组装一套单独的完整的系统,当然也因此培养出了不少全栈工程师)
2.feature提取
http_host
root_domain
url
path
query 查询字符串
referer
ip
timestamp
http_response_code
http_method
request_body 请求体 非必要字段
cookie 非必要字段
user_agent
3.预处理
在统计之前我们需要对数据做预处理
预处理1:按小时切割日志(切割主要是为了避免日志量大的情况下计算时间过长)
预处理2: 提取响应码为2xx,3xx的日志
预处理3: 特征规范化处理,非常重要,如果不做预处理,将会形成一个超级大的有向图,mapreduce这种批处理会处理不过来
Host规范化: 将*.xxx.com或.xxx.com 变成 www.xxx.com
Path规范化:归并多个/,替换为/
referer规范化:
(1)将相对地址还原为绝对地址,e.g. /a.php => www.xxx.com/a.php
(2)将host部分非本域(不在根域名内)、空字段、不符合referer规范的referer字段皆设置为空
(3)去除query部分
4.模型建立
1)webshell提取(全自动)
第一步:建立(path,referer)有向图,提取孤立页面(入度为0,出度为0 )与自回路页面( 入度为1,出度为1,自己指向自己)webshell 的访问特征
第二步:去除不符合规范的path( 是否符合(?:https?://)?[-./\w]+)
第三步:去除静态path(例如jpeg,jpg,gif,png,bmp,css,js,xls,xlsx,doc,xml,wav,tar.gz,zip,swf,mp3,ico,pidf,torrent)
第四步:去除白名单path (例如主页index.php,index.asp,index.aspx,index.ashx,index.html)
第五步:去除非webshell后缀的path (例如asp,aspx,php,jsp,py,cgi,pl,java,sh,war,cfm,phtml)
第六步:去除扫描器造成的path(按扫描器IP信誉库(云扫描器IP信誉库与时效性扫描器IP信誉库)与扫描器行为(可以简单的按ip+host聚类,将单位时间内请求数超过M,独立路径数超过N的请求视为扫描器)来去除)
第七步:去除响应码非200的path
第八步:按path特征定义webshell的可信度,符合特征的标记为1(例如常见的上传文件目录,随机文件名)webshell 的path特征
第九步:按webshell payload特征定义webshell的可信度,符合特征的标记为1,等同于WAF中的webshell检测规则(但要更宽松些,因为不怕误报),如果日志中有WAF检测结果标记字段,可以直接用该字段来标记webshell可信度 (例如envlpass=) webshell Payload特征
第十步:去除独立IP访问数与path访问请求总数超过阈值的path
2)webshell确认
第一步:对webshell 提取的path进行GET回放(限速),若有参数,带参数回放
这里需要考虑两种badcase:
(1)对脚本语言,设置不带参数隐藏为不存在或者发生跳转的webshell
(2)对非脚本语言,不带参数回放,由于Null异常直接500异常
第二步:去除响应码非200的path
补充:修改为保留401的请求,避免漏掉通过http basic认证的webshell
第三步:去除404重写path
方法一:随机生成2个文件名,回放,看response body的大小是否一样,若一样,则存在重写
方法二:神奇的fuzz hashing又要发挥作用了,可以对重写的response content求fuzz hashing值,设置相似度阈值,在阈值范围内的判定为404,例下图所示,将安全狗重写页面剔出
第四步:对空白响应页面,进行带payload的回放(限速与脱敏)
第五步:对响应页面计算fuzz hashing值,并做聚类处理
第六步:读取weshell fuzz hashing特征值库,将相似度在阈值范围内的path判定为webshell webshell Reponse网页相似性特征
第五步:网页信息提取,分为静态提取,动态提取,提取title,表单,Link,Image信息(全自动)
第六步:抽象webshell行为的关键路径,制定策略,基于策略库进行webshell异常提取
第七步:基于webshell样本签名(网页的内容/结构、视觉)的自动化攻击确认,与人工干涉的对属于异常但不符合样本签名的攻击确认补漏
第八步:提取确认webshell的访问者特征(IP/UA/Cookie),Payload特征,时间特征,关联搜索,将搜索结果按时间排序,还原事件 webshell 攻击关联特征
5. 模型评估
一般会用召回率,准确率来评估。但如何确认所有的webshell已检出呢,我采用在自己站点植入webshell,然后看是否能全部检出,但这种方式有明显问题——站点的访问流量非常态的,待解决。
三、模型缺陷
模型待改善的地方
问题一:referer伪造
问题二:图片webshell(因为静态文件的放行)
问题三:已有文件植入后门(因为不孤立了)
问题四:URL回放时的响应问题(例如读取注册表的小马,响应时间会超过默认的120s)
问题五: URL重写导致的伪静态放行
问题六:多个脚本相互交互的webshell(破坏了孤立性 )
问题七:网页信息动态提取时JS解析错误(无法正确提取表单来确认webshell输入点)
四、其他检测方法
上文介绍了如何通过web日志分析来查找webshell,现在来回顾一下传统的webshell检测产品
(p.s.从商品化的检测技术中总能获得不少检测灵感,他们的方法虽然土但有效)
WAF/IDS/IPS:检测HTTP请求是否符合webshell通信特征(被动检测)
漏洞扫描器:扫描是否存在已知后门植入漏洞,例如常见webshell路径,菜刀连接(主动检测)
后门检测查杀工具:检查文件系统中是否存在webshell恶意文件
目录监控工具:文件完整性监控、关注文件的修改时间、所有者,权限(增加的webshell文件,被植入webshell的已存在文件时间都会发生变化)
SIEM日志分析(取证)工具:检查是否有webshell的访问事件 (现有的一般是基于特征与简单关联,非常少的用到机器学习方法)
而这些产品用到的技术划分为静态检测方法与动态检测方法,其实也是反病毒领域采用的方法。
1. 静态检测
(1) 文件内容检测,检测是否包含webshell特征,例如webshell常用函数
缺点: webshell 花式混淆绕过
花式混淆参见:
http://weibo.com/p/1001603888457062702792
http://pastebin.com/raw.php?i=ctswucid
检测方法参见:
PHP Shell Detector
(2)文件内容检测,检测是否加密(混淆处理)
吸取上面的经验,增加了通过检测是否加密来判断webshell(1,2,3,4都是)
1、重合指数(Index of Coincidence):本质是概率,简单的说,有意义的词汇重合指数高,被加密或混淆的字符串的重合指数低
2、信息熵(Entropy):本质还是概率,简单的说,有意义的词汇熵值小,被加密或混淆的字符串的熵值大
3、最长单词(LongestWord):比较粗暴的假设,字符串越长被加密或混淆的可能性越大
4、压缩(Compression):非常有趣的想法,尽然能想到利用压缩的原理来描述混淆或加密字符串与常规字符串的区别
5、签名(Signature):特征匹配,属于传统方法
检测方法参见:
NeoPi方法
NeoPi方法的国人介绍:
http://www.freebuf.com/articles/web/23358.html
http://www.freebuf.com/articles/4240.html
缺点:
第一篇文章下的吐槽能说明一些问题,第二篇文章正好证明了这个问题
数据分析方法特别是机器学习,更多的时候考虑的是大数据量下的概率指向,对特殊情况的覆盖率低,但优势也是很明显的,只是不能单独使用。
(3)文件Hash检测,创建webshell样本hashing库,将待检测文件与之对比,在阈值范围内的判定为可疑文件
ssdeep检测webshell (fuzzy hashing检测)
(4)文件完整性检测
文件的创建时间(新增文件(新增webshell),修改时间(原有文件注入webshell)),文件权限,所有者
缺点:更新频繁的站点无法运维
2. 动态检测
沙箱技术,根据动态语言沙箱运行时的行为特征来判断
缺点:
加密文件无法执行,写的很挫(本身有语法错误)的文件无法执行,
检测产品参加:
五、结语
这篇文章写了快半个月了,本人是个收集狂魔,喜欢收集资料,也喜欢收集方法,收集了需要验证,因此花了不少时间,但这个过程还是蛮有趣的,玩过界(汇集不同领域的特长)的感觉真好。