背景
很久之前做过webshell检测方案调研(https://gist.github.com/leveryd/161ffd8e918d70b5029ab828333837c9),webshell可以在流量安全产品(比如waf、nids)和主机安全产品(hids)检测。
在流量安全产品常见的检测场景包括:
-
文件上传接口,比如检查上传的文件名、文件内容 -
webshell访问,比如检查常见的webshell管理工具
在主机安全产品常见的检测场景包括:
-
文本内容,比如检查所有php文件是否webshell -
内存马
根据网络上公开资料总结,”文本内容”检测手段包括:
webshell检测技术 | 举例 |
---|---|
动态分析-沙箱 | 百度webdir(https://scanner.baidu.com/#/pages/intro) |
静态分析-正则 | |
静态分析-统计学角度 | |
静态分析-AST | |
机器学习/深度学习 | |
RASP | 百度OpenRASP(https://rasp.baidu.com/doc/dev/official.html) |
长亭开源的cloudwalker(https://github.com/chaitin/cloudwalker)检测方式较全,个人觉得值得学习。
本文简要分析cloudwalker的检测手段,应该适合正在调研webshell检测方案的读者阅读。
PS: p牛说他们目前的方案已经和开源版本有非常大的不同,目前方案的线上demo:https://forum.xray.cool/webshell
分析
-
cloudwalker是什么?
牧云(CloudWalker)开源手记 | Webshell 监控检测策略初探(https://mp.weixin.qq.com/s?__biz=MzIwNDA2NDk5OQ==&mid=2651372030&idx=1&sn=682c49b3decda87ddf0ed641d5d347c6&chksm=8d39c876ba4e4160e88bacf0ffc3cadc39b60a269a6facec9f62134823af829624e42df52376&token=496332164&lang=zh_CN)
牧云(CloudWalker)开源|如约而至: Webshell核心检测引擎(https://zhuanlan.zhihu.com/p/45796590)
这两篇官方文章其实已经把检测策略介绍过了,总结起来包括四类:
-
基于模糊哈希 -
基于模糊正则 -
基于代码风格 -
基于机器学习:模型使用svm,特征包括了三个维度(代码风格、操作序列、操作名)
模糊哈希
-
是什么?
用
ssdeep
命令来实践,看一下生成的模糊哈希。[root@vm10-50-0-18 ssdeep_test]# ssdeep /usr/bin/sleep /usr/bin/sleep1 -s
ssdeep,1.1--blocksize:hash:hash,filename
768:VQ1Q5jc5QNAVo5FWQkckarfJ8JV3XAiqbolRX7:O35Q2Vo5FWkfJ8nXX7,"/usr/bin/sleep"
768:VQ1Q5jc5QNAVo5FWQkckarfJ8JV3XAiqbolRX7:O35Q2Vo5FWkfJ8nXX7,"/usr/bin/sleep1"
[root@vm10-50-0-18 ssdeep_test]# echo 11 >> /usr/bin/sleep1
[root@vm10-50-0-18 ssdeep_test]# ssdeep /usr/bin/sleep /usr/bin/sleep1 -s
ssdeep,1.1--blocksize:hash:hash,filename
768:VQ1Q5jc5QNAVo5FWQkckarfJ8JV3XAiqbolRX7:O35Q2Vo5FWkfJ8nXX7,"/usr/bin/sleep"
768:VQ1Q5jc5QNAVo5FWQkckarfJ8JV3XAiqbolRX7B:O35Q2Vo5FWkfJ8nXX7B,"/usr/bin/sleep1"可以看出来,
/usr/bin/sleep1
在添加了两个字节的数据后,算出来的模糊哈希虽然和原来的不同,但是很相似。所以可以得出结论:如果文件的”模糊哈希”相似,就很可能文件内容非常相似。
-
cloudwalker怎么用”模糊哈希”检测webshell?
在 tool/webshell-detector/bin/static/model-latest/SampleHash.txt 文件有计算好的”webshell模糊哈希列表”
在检测文件时,先计算出”检测对象”的模糊哈希,然后和”webshell模糊哈希列表”做相似度比较
代码风格
-
是什么?
从代码字符串中统计出的如下信息:
* WM:代码中的单词总数
* LM:代码行数
* SPL:代码中的分号数量/总行数
* SR:符号比例 = 符号长度/总长度
* ...这一部分业务逻辑在 Stat.go(https://github.com/leveryd/cloudwalker-source-read/blob/master/tool/webshell-detector/src/Stat.go)
-
cloudwalker怎么用”代码风格”检测webshell?
在 statState.json(https://github.com/leveryd/cloudwalker-source-read/blob/master/tool/webshell-detector/bin/static/config/statState.json) 中允许用户配置”代码风格合理范围”。cloudWalker计算出”检测对象”的”代码风格”后,会检查是否在此范围内。
另外,”代码风格”信息会作为机器学习模型中的特征。
机器学习
-
cloudwalker怎么用”机器学习”检测webshell?
使用了两层的机器学习。
第一层模型使用svm算法,特征包括三类:
* 前面说的"代码风格"
* "操作序列模型"的预测结果
* "操作名称模型"的预测结果 -
“操作序列模型”是什么?
训练好的模型在 tool/webshell-detector/bin/static/model-latest/OpSerial.model
它使用svm算法,特征是”操作序列”处理后的数据。
“操作序列”包含了php代码中的”操作特征”。
-
怎么生成”操作序列”?
由代码获取到抽象语法树后,再由抽象语法树生成”操作序列”。
举个例子:
假设待检测的php代码如下
<?php eval($_POST[0]);?>
代码生成的抽象语法树(ast)
{"status":"successed","ast":{"kind":132,"flags":0,"lineno":1,"children":[{"kind":269,"flags":1,"lineno":1,"children":{"expr":{"kind":512,"flags":0,"lineno":1,"children":{"expr":{"kind":256,"flags":0,"lineno":1,"children":{"name":"_POST"}},"dim":0}}}}]}}
对应的”操作序列”如下:
可以看出来,”操作序列”包含了”抽象语法树”两层之间的联系。
抽象语法树
-
怎么生成”抽象语法树”?
代码在 tool/webshell-detector/php 目录。
流程如下:
* 在cloudwalker启动时,php.c(https://github.com/leveryd/cloudwalker-source-read/blob/master/tool/webshell-detector/php/php.c)新建子线程,并等待输入。
* 子线程接收php代码后,解析生成"抽象语法树",将结果返回给主线程。子线程通过管道与主线程通信。解析能力基于php-ast项目(https://github.com/nikic/php-ast),业务逻辑可以见index.php
可以运行index.php做一点简单的测试:输入包括”字符串长度”和”代码”,输出ast字符串
➜ php git:(master) ✗ ./bin/php payload/index.php
26
<?php eval('$_POST[0]');?>
142
{"status":"successed","ast":{"kind":132,"flags":0,"lineno":1,"children":[{"kind":269,"flags":1,"lineno":1,"children":{"expr":"$_POST[0]"}}]}}
总结
仓库(https://github.com/leveryd/cloudwalker-source-read/)中放了我阅读代码时的注释,方便有需要的读者。
从测试效果来看,开源版本和目前线上版本有很大差异:开源版本cloudwalker比较容易绕过,线上(https://forum.xray.cool/webshell)则难度大很多。
end
招新小广告
ChaMd5 Venom 招收大佬入圈
新成立组IOT+工控+样本分析+AI 长期招新
原文始发于微信公众号(ChaMd5安全团队):webshell检测总结与实例分析