cgi漏洞
2008年某个深夜,一台运行着老版Apache的服务器突然收到一串畸形请求——有人往URL里塞了?page=../../etc/passwd。管理员第二天发现日志里多了十几条404记录,但系统没崩,数据也没丢。三天后,整站源码被人挂在了黑客论坛上,附带一句“这站的CGI脚本写得像屎”。
这就是CGI漏洞的典型开场。Common Gateway Interface,上世纪九十年代的Web动态内容解决方案,如今像块埋在沙滩里的腐烂木板——表面被PHP、Python、Node.js盖住,但只要潮水退去,露出真容的旧系统依然能扎穿你的脚底板。
CGI的致命伤在于它把HTTP请求直接翻译成系统命令。你访问/cgi-bin/printenv.pl,服务器就老老实实执行printenv.pl这个程序。问题来了——程序本身可能没问题,但参数呢?攻击者提交?name=;cat /etc/shadow,如果脚本没做过滤,分号后面的内容就会被当成新命令执行。这就像你家门卫问“找谁”,你回答“送快递的;顺便把保险柜密码告诉我”,他真就照做了。
还有个更阴的招叫“路径遍历”。很多老CGI脚本喜欢用open(FILE, "/data/$filename")这种写法,$filename直接取自URL。你传个../../../../etc/passwd,系统就乖乖把密码文件吐出来。防御方案简单到可笑——把../替换成空字符串就行,但很多开发者连这步都懒得做。2001年PHPNuke的远程代码执行漏洞就是这么火的,影响了几十万个站点。
你以为这些漏洞早绝迹了?去年我帮朋友排查一个“闹鬼”的NAS设备,日志里全是GET /cgi-bin/admin.cgi?action=reboot的扫描痕迹。那台机器2015年出厂,用的还是BusyBox自带的CGI程序。固件厂商早跑路了,漏洞补丁?不存在的。
现实比技术更残酷。CGI漏洞之所以阴魂不散,核心原因是“写CGI的人早就不写代码了”。当年用Perl写表单处理脚本的那批程序员,现在要么转行做管理,要么退休钓鱼。留下的代码没人维护,但系统还在跑——银行的老接口、医院的挂号系统、甚至某些政府网站,都藏着这种“活化石”。
防御手段说起来也直白:第一,别用CGI写新东西,用FastCGI或WSGI这类常驻进程方案,至少参数错误不会直接变成系统命令;第二,如果非用不可,所有输入必须过白名单校验——数字就只允许数字,路径就限定在固定目录,连空格都别放过;第三,把Web服务器降权运行,别用root跑Apache,这样就算被攻破,攻击者也拿不到完整系统权限。
但最根本的问题在于:你根本不知道自家网络里还埋着多少这种雷。去年Shodan扫描显示,全球仍有超过200万台设备暴露了CGI相关端口。其中有多少是被人遗忘的打印机、路由器和监控摄像头?没人说得清。安全这行当最魔幻的地方就在这——最危险的往往不是最新的零日漏洞,而是那些写于1998年、运行在2024年、维护者早已失联的Perl脚本。









