将用户输入拼接到命令行中执行 导致的任意命令执行问题

例子

  1. <?php
  2. $command = 'ping -c 1 '.$_GET['ip'];
  3. system($command); //system函数特性 执行结果会自动打印
  4. ?>

这是一段简单的php代码 专门执行ping 命令并输出内容

正常输入: /xxx.php?ip=114.114.114.114

执行命令 ping -c 1 114.114.114.114

由于ip参数没有任何过滤限制

所以攻击者可以这样输入: /xxx.php?ip=114.114.114.114;whoami

执行命令 ping -c 1 114.114.114.114;whoami

这样就可以执行攻击者定义的命令 whoami

实际审计时输入常常不会非常简单 都有复杂的处理 慢慢追踪参数来源

遇到不会的函数可以在PHP手册查找对应的功能

命令执行基本语法不会的可以学习学习linux windows命令行语法基础

在审计时遇到输入可控时 要检查是否存在escapeshellarg escapeshellcmd 函数转义 或者是其他的处理方法(如 强制类型转换 替换字符 等)

常见bash shell 语法

符号 描述 示例
<和> 输入输出重定向 echo abc >1.txt
;分号 按照从左到右顺序执行命令 id;whoami;ls
| 管道符 将左侧命令的输出作为右侧命令的输入 ps -aux|grep root
&& 按照从左到右顺序执行命令 只有执行成功才执行后面的语句
|| 按照从左到右顺序执行命令 只有执行失败才执行后面的语句

一些常见的可以执行系统命令的函数/语法

函数/语法 描述 例子
system 执行命令并输出结果 system(‘id’);
exec 执行命令 只可获取最后一行结果 exec(‘id’,$a); print_r($a);
passthru 同 system passthru(‘id’);
shell_exec ` (反引号) 执行命令并返回结果 $a=shell_exec(‘id’);print_r($a); $a=id;print_r($a);
popen 执行命令并建立管道 返回一个指针 使用fread等函数操作指针进行读写 $a=popen(“id”, “r”); echo fread($a, 2096);
proc_open 同 popen (进程控制功能更强大) 见PHP手册
pcntl_exec 执行命令 只返回是否发生错误 pcntl_exec(‘id’);