webshell就是以asp、php、jsp或者cgi等网页文件形式存在的一种命令执行环境,也可以是指定以服务端动态脚本形式存在的一种网页后门。黑客在入侵了一个网站后,通常会将asp或php后门文件与网站服务器WEB目录下正常的网页文件混在一起,然后就可以使用浏览器来访问asp或者php后门,得到一个命令执行环境,以达到控制网站服务器的目的。
Webshell一般是指以服务端动态脚本形式存在的一种网页后门。在入侵检测的过程中,检测检测Webshell无疑是一大重点,比较常见的检测手法有:
1. 文件内容检测(静态检测)
2. 文件行为检测(动态检测)
其中,静态检测是比较简单有效的检测Webshell的手段之一。根据Webshell的文件特征建立异常模型,并使用大量的Webshell样本对模型进行训练,通过诸如异常函数、关键代码以及文件内容与普通业务代码的相似度等等关键点来进行分析检测。
WebShell检测模型
Webshell的运行流程:hacker -> HTTP Protocol -> Web Server -> CGI。
黑客通过浏览器以HTTP协议访问Web Server上的一个CGI文件。棘手的是webshell就是一个合法的TCP连接,在TCP/IP的应用层之下没有任何特征(当然不是绝对的),只有在应用层进行检测。
黑客入侵服务器,使用webshell,不管是传文件还是改文件,必然有一个文件会包含webshell代码,很容易想到从文件代码入手,这是静态特征检测;webshell运行后,B/S数据通过HTTP交互,HTTP请求/响应中可以找到蛛丝马迹,这是动态特征检测。
静态检测
静态检测通过匹配特征码,特征值,危险函数函数来查找webshell的方法,只能查找已知的webshell,并且误报率漏报率会比较高,但是如果规则完善,可以减低误报率,但是漏报率必定会有所提高。优点是快速方便,对已知的webshell查找准确率高,部署方便,一个脚本就能搞定。缺点漏报率、误报率高,无法查找0day型webshell,而且容易被绕过。对于单站点的网站,用静态检测还是有很大好处,配合人工,能快速定位webshell,但是如果是一个成千上万站点的大型企业,再人肉那工作量会很大。
所以用这样一种思路:强弱特征。即把特征码分为强弱两种特征,强特征命中则必是webshell;弱特征由人工去判断。
加入一种强特征,即把流行webshell用到的特征作为强特征重点监控,一旦出现这样的特征即可确认为webshell立即进行响应。
要解决误报和漏报,就不能拘泥于代码级别了,需要人工运维来处理。
可以换个角度考虑问题:文件系统。我们可以结合文件的属性来判断,比如apache是noboy启动的,webshell的属主必然也是nobody,如果我的Web目录无缘无故多了个nobody属主的文件,这里就有问题了。最理想的办法是需要制度和流程来建设一个web目录唯一发布入口,控制住这个入口,非法进来的Web文件自然可以发现。
yara规则:
- $eval = /(<\?php|[;{}])[ \t]*@?(eval|preg_replace|system|assert|passthru|(pcntl_)?exec|shell_exec|call_user_func(_array)?)\s*\(/ nocase // ;eval( <- this is dodgy
- $eval_comment = /(eval|preg_replace|system|assert|passthru|(pcntl_)?exec|shell_exec|call_user_func(_array)?)\/\*[^\*]*\*\/\(/ nocase // eval/*lol*/( <- this is dodgy
- $b374k = "'ev'.'al'"
- $align = /(\$\w+=[^;]*)*;\$\w+=@?\$\w+\(/ //b374k
- $weevely3 = /\$\w=\$[a-zA-Z]\('',\$\w\);\$\w\(\);/ // weevely3 launcher
- $c99_launcher = /;\$\w+\(\$\w+(,\s?\$\w+)+\);/ // http://bartblaze.blogspot.fr/2015/03/c99shell-not-dead.html
- $nano = /\$[a-z0-9-_]+\[[^]]+\]\(/ //https://github.com/UltimateHackers/nano
- $ninja = /base64_decode[^;]+getallheaders/ //https://github.com/UltimateHackers/nano
- $variable_variable = /\${\$[0-9a-zA-z]+}/
- $too_many_chr = /(chr\([\d]+\)\.){8}/ // concatenation of more than eight `chr()`
- $concat = /(\$[^\n\r]+\.){5}/ // concatenation of more than 5 words
- $concat_with_spaces = /(\$[^\n\r]+\. ){5}/ // concatenation of more than 5 words, with spaces
- $var_as_func = /\$_(GET|POST|COOKIE|REQUEST|SERVER)\s*\[[^\]]+\]\s*\(/
- $comment = /\/\*([^*]|\*[^\/])*\*\/\s*\(/ // eval /* comment */ (php_code)
静态检测的webshell工具:
GitHub - he1m4n6a/findWebshell: findWebshell是一款基于python开发的webshell检测工具。
GitHub - nbs-system/php-malware-finder
注:以下所有特征值汇总全部均被采用为webshell的静态检测,需要在工具扫描后对扫描的文件进行人为判定确定其是否为webshell,以防止误报情况的发生。
动态检测
Webshell分析检测层,hook可疑函数
特征维度:
webshell传到服务器了,黑客总要去执行,webshell执行时刻表现出来的特征,我们称为动态特征。webshell通信是HTTP协议,只要我们把webshell特有的HTTP请求/响应做成特征库,加到IDS里面去检测所有的HTTP请求就好了。
webshell起来如果执行系统命令的话,也会有进程,Linux下就是nobody用户起了bash,Win下就是IIS User启动cmd,这些都是动态特征。如果黑客反向连接的话,那很更容易检测了,Agent和IDS都可以抓现行。
Webshell总会有一个HTTP请求,如果我在网络层监控HTTP,并且检测到有人访问了一个从没反问过得文件,而且返回了200,则很容易定位到webshell,这便是http异常模型检测,就和检测文件变化一样,如果非管理员新增文件,则说明被人入侵了。
缺点也很明显,黑客只要利用原文件就很轻易绕过了,并且部署代价高,网站时常更新的话规则也要不断添加。
还有一个思路利用函数劫持,把eval改成alert就好了。类似的,所以我们可以在CGI全局重载一些函数(比如ASP.Net的global.asax文件),当有webshell调用的时候就可以发现异常。已js为例(php,asp等语言思路一样的,都是保存原函数,然后从新定义原函数,最后在调用保存的原函数),比如下面就是把eval重载,还可以弹出个危险提示等,吓退一些没经验黑客。
- <script type="text/javascript">
-