php入侵
凌晨两点十七分,我盯着屏幕上的终端窗口,心跳漏了一拍。那台跑着PHP 5.6的老服务器,日志文件里多了一行奇怪的POST请求——`eval(base64_decode(...))`。我点开,解码,一串加密的PHP代码像蠕虫一样展开。有人进来了。
这不是电影。这是上个月我帮朋友维护一个电商网站时遇到的真实情况。那网站用的是十年前的ThinkPHP框架,漏洞多得像筛子。攻击者没费什么力气,就通过一个未过滤的`$_GET['id']`参数,注入了恶意代码。
PHP入侵,说白了就两种路子:一种是直接利用代码漏洞,另一种是骗过人的判断。前者靠技术,后者靠心理。我见过最狠的一次,攻击者把恶意代码伪装成一张图片,上传到服务器,然后用`include`函数把它当PHP文件执行。图片的二进制数据里藏着完整的webshell,服务器就这么被架空了。
你可能会问,PHP不是有类型检查吗?不是有`htmlspecialchars`吗?不是有预处理语句吗?对,理论上是这样。但现实是,很多程序员写代码的时候图省事,直接拼SQL,直接`echo $_POST['name']`,连个过滤都不加。我见过一个内部管理系统,登录验证写的是`if ($_POST['password'] == $admin_password)`——明文比较,连hash都不用。这种代码,入侵者连猜都懒得猜,直接暴力破解就行。
有一次,我故意在一个测试站点上留了个后门——一个看似无害的`file_get_contents($_GET['url'])`。三天后,日志显示有人尝试从`192.168.1.105`访问这个接口,传参是`php://filter/convert.base64-encode/resource=config.php`。他们想读数据库密码。我改了下代码,把那个请求重定向到一个蜜罐文件,里面放了一堆假数据。对方居然真的用那些假密码登录了,还在系统里折腾了半小时。那种感觉挺奇妙的——你在暗处看着入侵者在你的陷阱里打转,就像看一只老鼠在迷宫里乱窜。
但别误会,我不是在嘲笑攻击者。真正的PHP入侵往往悄无声息,等你发现的时候,数据库早就被拖走了。去年有个客户,网站被植入了挖矿脚本,CPU占用率飙到100%,他愣是拖了一个月才找人排查。我上去一看,恶意代码藏在一个看似正常的`cache.php`文件里,用`ob_start`和`register_shutdown_function`做掩护,每次页面加载都会执行一次挖矿运算。代码写得还挺工整,注释都用英文写的。
说句实话,PHP本身不背这个锅。语言只是工具,问题出在使用方式上。我见过用PHP写的银行系统,安全级别高得吓人——每个输入都经过白名单验证,每个SQL都用预处理,每个文件上传都检查MIME类型和文件头。也见过用PHP写的个人博客,后台密码是`123456`,连个验证码都没有。入侵者不是神,他们只是比你更了解代码的弱点。
那次深夜发现的入侵,最后怎么解决的?我先把那个恶意请求的IP拉黑,然后删掉上传的webshell文件,再给所有输入点加了过滤函数。折腾到凌晨四点,总算清理干净。但我知道,这只是暂时的。只要代码里还有漏洞,就总会有下一个入侵者。PHP的世界就是这样——你永远不知道下一行代码会不会成为别人的入口。
写代码的人,总觉得自己写的代码是安全的。直到有一天,你看到日志里那行陌生的`eval`,才会明白:安全不是一种状态,而是一场持续的对抗。