webshell如何
凌晨两点,某金融公司运维老张的监控屏突然跳出警报。他点开日志,发现一台内网服务器在凌晨一点四十七分执行了一条whoami命令——这不是他干的。三分钟后,攻击者用菜刀连接了同一个文件,上传了一个带图片马头的PHP脚本。老张说,那一刻他后背发凉,因为那台服务器上存着三千个客户的身份证照片。
webshell说白了就是一个网页后门。攻击者往你的服务器塞一段代码,这段代码伪装成正常文件,但能通过浏览器远程操控你的机器。它不挑语言,PHP、ASP、JSP都行,甚至Python写的也能跑。最操蛋的是,很多webshell长得跟正常文件一模一样,杀毒软件扫不出来,防火墙拦不住,因为它走的就是80端口的正常流量。
我见过一个真实的案例。某电商平台被植入webshell后,攻击者没急着拖库,而是潜伏了四个月。他每隔两周登录一次,用system('cat /etc/passwd')探探路,然后慢慢摸清了整个内网结构。最后一天晚上,他一次性执行了三十七条命令,把备份数据库的加密密钥打包带走了。整个过程中,安全设备没报一次警——因为那台服务器本来就是合法的web服务器,所有请求看起来都像正常浏览。
webshell怎么进来的?最常见的路径是上传漏洞。很多程序员写上传功能时,只校验了文件扩展名,没校验文件内容。攻击者把PHP代码藏进图片的EXIF信息里,上传成功后用短标签<?=绕过执行。还有一种路径是第三方组件漏洞,比如某个编辑器插件有个已知的任意文件上传漏洞,攻击者直接扫描全网,找到暴露的站点就扔一个webshell上去。
检测webshell这事,说实话挺头疼。基于特征码的扫描器能查已知的苍蝇,但遇到变种就抓瞎。我见过最狠的一次,攻击者把webshell代码拆成七段,分别藏在七个不同的日志文件里,用include函数在运行时拼接执行——这种你靠静态扫描根本发现不了。更现实的做法是盯行为:正常PHP脚本不会在凌晨三点去连外网IP,正常上传目录不会出现eval(base64_decode(...))这种函数调用。
有一次我帮朋友排查被黑的服务器,发现webshell藏在/tmp/.cache目录下,文件名是index.php,内容只有一行:@eval($_POST['x']);。就这么一行代码,攻击者就能通过POST请求执行任意命令。我删掉文件后不到两小时,它又回来了——攻击者留了第二个后门在wp-includes里,伪装成WordPress的更新缓存。那晚我陪他搞到天亮,把整个站点的文件哈希全部重算了一遍,才确认干净。
防御webshell,我的态度很明确:别指望一劳永逸的工具,得靠纵深防御。最小权限原则是最基础的,上传目录坚决不给执行权限,数据库账号不用root,定期轮换密钥。代码层面,对所有上传文件做二次校验,不光看扩展名,还要检查文件头魔数,甚至用getimagesize()验证图片是否真的能解析。日志这块,重点监控eval、assert、system这些敏感函数调用,一旦出现就告警。
老张后来告诉我,那次事件让他养成了个习惯——每天凌晨三点起来看一眼监控屏。我说你这不是办法,他说不然呢,webshell这玩意儿就跟感冒一样,你防不住它不来,只能保证它来了你能第一时间发现。这话糙理不糙。攻防对抗永远在升级,今天你堵住了上传漏洞,明天攻击者可能就利用反序列化漏洞写webshell。别指望哪个安全厂商能给你兜底,最后兜底的还是你自己的那点敏感度和执行力。