DVWA靶场命令注入impossible源码分析详解
字数 914 2025-08-10 20:35:54
DVWA靶场命令注入Impossible级别源码分析与防御机制详解
一、源码解析
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// 验证CSRF令牌
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
$target = $_REQUEST[ 'ip' ];
$target = stripslashes( $target );
$octet = explode( ".", $target );
// 验证IP格式
if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) &&
( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) &&
( sizeof( $octet ) == 4 ) ) {
$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
// 根据操作系统执行不同的ping命令
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
$cmd = shell_exec( 'ping ' . $target );
} else {
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
echo "<pre>{$cmd}</pre>";
} else {
echo '<pre>ERROR: You have entered an invalid IP.</pre>';
}
}
// 生成会话令牌
generateSessionToken();
?>
二、关键安全防御机制
1. CSRF防护
- 使用
checkToken()函数验证表单提交的CSRF令牌 - 每次请求后使用
generateSessionToken()生成新的会话令牌 - 防止跨站请求伪造攻击
2. 输入验证
- 使用
explode()将IP地址分割为4个八位字节 - 使用
is_numeric()严格验证每个八位字节是否为数字 - 使用
sizeof()确保分割后正好是4部分 - 验证通过后重新拼接IP地址,防止注入
3. 命令执行安全
- 不直接拼接用户输入到命令中
- 先验证后拼接,确保只执行合法的ping命令
- 根据操作系统类型(
php_uname('s'))选择适当的ping参数
4. 输出处理
- 使用
stripslashes()处理转义字符 - 输出使用
<pre>标签包裹,保持格式但防止XSS
三、核心函数详解
1. stripslashes()
$str = "Is your name O\'reilly?";
echo stripslashes($str); // 输出: Is your name O'reilly?
- 作用:删除由
addslashes()添加的反斜杠 - 安全意义:防止双重转义导致的问题
2. explode()
$ip = "192.168.1.1";
$octets = explode(".", $ip); // ["192", "168", "1", "1"]
- 作用:使用分隔符分割字符串
- 安全应用:用于IP地址的严格验证
3. is_numeric()
is_numeric("42"); // true
is_numeric("42 "); // true
is_numeric("\u{A0}9001"); // false (含非中断空格)
- 作用:检测变量是否为数字或数字字符串
- 安全意义:严格验证IP地址各部分
4. sizeof()/count()
$arr = [1, 2, 3];
sizeof($arr); // 3
- 作用:统计数组元素数量
- 安全应用:确保IP地址被正确分割为4部分
四、安全设计总结
- 多层验证:先格式验证,再内容验证,最后重组输出
- 最小化命令执行:仅允许执行验证后的ping命令
- 上下文感知:根据操作系统选择适当命令参数
- 会话安全:完善的CSRF防护机制
- 输入净化:严格限制输入格式和内容
五、实际应用建议
- 所有系统命令执行前都应进行类似的严格验证
- 对于用户输入,应采用白名单而非黑名单策略
- 敏感操作必须包含CSRF防护
- 命令执行应尽可能使用参数化方式而非字符串拼接
- 输出时应考虑适当的编码/转义防止XSS
此Impossible级别的实现展示了命令注入漏洞的终极防御方案,通过严格的输入验证和多重安全机制,几乎完全消除了命令注入的可能性。