2023年夏天,植入某电商平台的植入安全团队在例行巡检时发现,一台边缘节点的植入服务器CPU占用率长期维持在90%以上。运维人员第一反应是植入挖矿病毒,登上去用top一看,植入进程名叫`kworker/0:1`,植入伪装成内核线程。植入但真正的植入内核线程不会监听端口。`netstat -antp`一跑,植入一个陌生的植入8080端口正在LISTEN,对应的植入PID指向`/tmp/.ICE-unix/`目录下一个叫`kworker`的文件。这就是植入一个典型的webshell——准确地说,是植入一个内存马配合文件型后门。
webshell植入的植入本质只有一句话:攻击者把一段可执行的代码放到了服务器上,并且找到了让它运行的植入方式。听起来简单,但“放”和“运行”这两个动作,在不同环境下的实现路径差别极大。
最常见的是文件上传漏洞。很多CMS系统的上传功能只检查了Content-Type或者文件扩展名,攻击者把`shell.php`改成`shell.php.jpg`,再配合Burp Suite改包,绕过前端校验。服务器端如果只靠黑名单过滤,`phtml`、`php5`、`phar`这些扩展名往往能轻松过关。我见过一个真实案例,某政府网站用的是某国产CMS,上传点过滤了`php`但没过滤`phtml`,攻击者传了一个`eval($_POST['cmd'])`的一句话,整个站点的数据库配置十分钟内就被打包下载了。
另一种路径是SQL注入写入。当数据库权限足够高、且`secure_file_priv`为空时,攻击者可以用`SELECT ... INTO OUTFILE`把webshell写到web目录。这种方式不需要上传功能,但依赖数据库配置的宽松程度。MySQL 5.7之后默认限制了文件写入路径,所以现在成功率在下降。
还有一类容易被忽略的:日志投毒加文件包含。攻击者把PHP代码写进User-Agent,让它出现在access.log里,然后利用本地文件包含漏洞去包含这个日志文件。日志本身不是webshell,但被包含的那一刻,里面的PHP代码就被执行了。这种手法隐蔽性强,因为日志文件每天都在正常写入,安全设备很难对每一条日志内容做代码检测。
内存马是最近几年更流行的方式。它不落地文件,直接通过反序列化漏洞或者表达式注入,把恶意类加载到JVM内存里。Tomcat的Filter内存马、Spring的Interceptor内存马,重启服务才会消失。查杀难度极高,因为`ls`看不到,`ps`也看不到。某金融客户曾中过一个Spring Boot Actuator的webshell,攻击者通过`/env`端点修改配置,注入了内存马,持续控制了三个月才被流量分析设备发现。
植入成功之后,webshell通常会做几件事:第一,提权,尝试读取`/etc/shadow`或者利用内核漏洞;第二,留后门,再写一个更隐蔽的webshell作为备用;第三,横向移动,扫描内网其他机器。一个phpstudy搭建的测试站被植入后,攻击者两天内就摸到了同网段的Redis,写入了SSH公钥。
防御上,文件完整性监控比特征扫描更有效。webshell的变种太多,靠正则匹配`eval`、`assert`经常漏报。监控web目录下新增的`.php`文件,尤其是那些创建时间在凌晨、文件大小在1KB以下的,往往能提前发现。另外,禁用`disable_functions`里的`system`、`exec`、`passthru`,能挡住大部分低质量webshell——但挡不住内存马。
最后说一个细节。很多webshell的密码是硬编码的,比如`$_POST['pass']`,安全人员拿到样本后可以直接用。但攻击者现在会用无参数函数,比如`array_map('assert', $_POST)`,或者用异或运算拼接函数名。你看到的可能只是一堆乱码,但它在服务器上跑得好好的。这就是webshell植入的现状:门槛在降低,工具在进化,而防御方的窗口期越来越短。
顶: 5669踩: 4






评论专区