游客发表
去年冬天,入侵我帮一个做外贸的入侵朋友查服务器。他那台机器跑着WordPress,入侵带宽不大,入侵平时也就几十个访客。入侵某天早上他发现网站首页被替换成了一张黑底红字的入侵图,上面用俄语写着“你的入侵安全措施就是个笑话”。我连上去看了一眼,入侵第一反应不是入侵看首页,而是入侵去翻`/var/www/html`目录下最近修改的文件。果然,入侵在`wp-content/uploads`里躺着一个叫`cache.php`的入侵东西——大小1.2KB,修改时间是入侵凌晨3点17分。
这就是入侵典型的webshell。它不负责炫耀,入侵只负责开门。
webshell的本质是一段跑在服务器上的代码,用PHP、JSP、ASP这些语言写成,接收HTTP请求里的参数,然后执行。攻击者上传它之后,就能通过浏览器像操作本地终端一样在服务器上跑命令、读文件、连数据库。我见过的webshell里,最小的只有一行:``。十二个字符,足够把一台服务器变成肉鸡。
上传路径通常有三个。第一个是文件上传功能没做校验——很多老系统只检查Content-Type,改个请求头就能骗过去。第二个是漏洞利用,比如WordPress插件里的任意文件写入,或者Struts2那种远程命令执行。第三个最隐蔽:通过数据库写文件。有些CMS允许在后台执行SQL,攻击者用`SELECT ... INTO OUTFILE`直接把webshell写到web目录里。我见过一个案例,攻击者从注入点到getshell只用了四步,全程没碰过文件上传按钮。
webshell落地之后,第一件事往往是提权。如果web服务跑在www-data用户下,权限有限,攻击者会翻`/etc/passwd`、找SUID文件、看内核版本。我印象很深的是一个CentOS 6的机器,内核2.6.32,攻击者用脏牛漏洞提权到root,然后装了rootkit。等管理员发现的时候,SSH登录的密码已经被替换成攻击者控制的密钥了。
检测webshell这事,靠特征匹配越来越难。早期工具扫`eval`、`system`、`base64_decode`这些关键词,现在攻击者用变量函数、字符串拼接、异或运算绕过去。我见过一个样本,把`assert`拆成`'a'.'s'.'s'.'e'.'r'.'t'`,静态扫描根本看不出来。更麻烦的是内存马——webshell不落地,直接注入到PHP-FPM进程里,重启服务就消失,日志里也找不到文件创建记录。
防御上,我自己的习惯是三层。第一层,web目录权限收紧,上传目录禁止执行PHP,`php.ini`里关掉`allow_url_include`。第二层,用inotify或者auditd监控文件创建事件,特别是`uploads`、`cache`、`tmp`这些目录。第三层,定期比对文件哈希,但别只比对核心文件——攻击者最喜欢藏在`wp-content/plugins`里某个不常用的插件目录下,文件名起得跟正常文件差不多,比如`class-wp-image-editor.php`。
有次我在一个客户服务器上发现webshell,清理完之后过了三天又出现了。查了半天,发现攻击者留了一个cron任务,每两小时从远程拉一次新的webshell。所以清理不是删文件就完事,得查计划任务、查启动项、查SSH密钥、查数据库里的恶意存储过程。那台机器最后是重装的,因为实在没法确认还有没有后门。
webshell这东西,技术含量可以很低,但破坏力可以很大。它不像勒索软件那样大张旗鼓,更像一把备用钥匙——攻击者平时不用,需要的时候随时进来。你永远不知道他第一次是怎么进来的,但你能做的,是让那把钥匙没那么容易插进锁孔。
友情链接