将用户输入拼接到命令行中执行 导致的任意命令执行问题
例子
<?php
$command = 'ping -c 1 '.$_GET['ip'];
system($command); //system函数特性 执行结果会自动打印
?>
这是一段简单的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’); |