上周帮一家电商公司处理安全事件,线检他们的线检后台被塞进一个加密的PHP脚本,整整潜伏了四十七天。线检流量日志里看不出任何异常,线检直到数据库被拖走前半小时,线检那个webshell才发出最后一次外联请求。线检这玩意儿就像一把万能钥匙,线检只要web应用有一道缝,线检它就能钻进去,线检然后安静地等着你犯错。线检
传统检测手段基本靠特征库匹配,线检跟杀毒软件一个思路。线检但现在的线检webshell早就不写eval($_POST['cmd'])这种教科书代码了。我见过用异或运算拆成几百个字符串再动态拼接的线检,也见过把恶意代码藏在图片EXIF信息里的线检。静态扫描面对这种变种,误报率能飙到百分之六十以上,安全工程师光筛告警就得加班到凌晨。
动态检测倒是聪明些,把可疑文件放到沙箱里跑一遍,看它到底干什么。但问题在于webshell的触发条件往往很隐蔽——某个特定的Cookie值,某个时间窗口,甚至需要先访问某个正常页面三次。沙箱里跑十分钟没动静,不代表它真干净。我遇到过一个案例,恶意代码要等服务器时间到凌晨三点才激活,动态检测根本等不到那一刻。
现在业内更倾向行为分析。不纠结代码长什么样,盯着运行时的系统调用。文件操作、网络连接、进程创建,把这些行为串成一条线。正常PHP脚本不会去读/etc/shadow,也不会用fsockopen连外部IP的3389端口。一旦行为偏离基线,哪怕代码伪装得再完美也白搭。有个客户部署了这种方案,两周内就逮住三个绕过传统检测的webshell,其中两个是冰蝎变种。
但行为分析也有死角。如果webshell直接复用正常业务逻辑,比如通过现有的文件上传功能写入恶意内容,那从系统层面看,所有操作都是合法的。这时候需要把应用日志、访问日志、数据库操作日志关联起来看。攻击者总会在某个环节留下痕迹——上传时间异常、参数格式不对、返回状态码有偏差。把这些线索拼在一起,才能拼出完整的攻击链。
说实在的,没有哪套方案能百分百防住webshell。攻击者也在进化,用机器学习生成免杀代码,用内存马躲开文件扫描。安全这事就是猫鼠游戏,你得把检测做成常态化机制,而不是装个工具就完事。定期做红蓝对抗,把最新的攻击手法喂给检测系统,让它越跑越聪明。毕竟webshell检测的本质,是在跟攻击者的耐心和创造力赛跑。