DVWA-Insecure CAPTCHA
字数 1156 2025-08-11 17:39:49
DVWA Insecure CAPTCHA 漏洞分析与利用教学文档
1. 漏洞概述
Insecure CAPTCHA 是 DVWA (Damn Vulnerable Web Application) 中的一个安全挑战,展示了验证码(CAPTCHA)实现不当可能导致的安全问题。本教学文档将详细分析从低到高各个安全级别的实现漏洞及利用方法。
2. Low 安全级别分析
2.1 代码逻辑分析
if( isset( $_POST[ 'Change' ] ) && $_POST[ 'step' ] == '1' ) ) {
// 第一步:验证CAPTCHA
$resp = recaptcha_check_answer( $_DVWA[ 'recaptcha_private_key'], $_POST['g-recaptcha-response'] );
if( !$resp ) {
// CAPTCHA验证失败
} else {
// CAPTCHA验证成功,检查密码是否匹配
if( $pass_new == $pass_conf ) {
// 显示第二步表单
echo "<form action=\"#\" method=\"POST\">
<input type=\"hidden\" name=\"step\" value=\"2\" />
<input type=\"hidden\" name=\"password_new\" value=\"{$pass_new}\" />
<input type=\"hidden\" name=\"password_conf\" value=\"{$pass_conf}\" />
<input type=\"submit\" name=\"Change\" value=\"Change\" />
</form>";
}
}
}
if( isset( $_POST[ 'Change' ] ) && $_POST[ 'step' ] == '2' ) ) {
// 第二步:直接执行密码修改
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "'";
}
2.2 漏洞点
- 密码修改过程分为两步,仅通过
step参数判断是否已完成CAPTCHA验证 - 攻击者可以直接构造
step=2的请求绕过CAPTCHA验证
2.3 利用方法
- 正常发起密码修改请求并拦截
- 修改请求参数,将
step=1改为step=2 - 直接提交请求完成密码修改
3. Medium 安全级别分析
3.1 代码改进
if( isset( $_POST[ 'Change' ] ) && $_POST[ 'step' ] == '2' ) ) {
// 新增passed_captcha检查
if( $_POST[ 'passed_captcha' ] == 'true' ) {
// 执行密码修改
}
}
3.2 漏洞点
- 虽然增加了
passed_captcha参数检查,但该参数可由客户端控制 - 本质上与Low级别相同,仍可通过参数伪造绕过
3.3 利用方法
- 拦截密码修改请求
- 添加或修改参数:
passed_captcha=true - 直接提交请求完成密码修改
4. High 安全级别分析
4.1 代码改进
// 去除了step参数分步验证
if( !$resp && ($_POST['recaptcha_response_field'] != 'hidd3n_valu3' || $_SERVER['HTTP_USER_AGENT'] != 'reCAPTCHA') ) {
// CAPTCHA验证失败
} else {
// CAPTCHA验证成功
}
4.2 漏洞点
- 验证逻辑存在缺陷:使用OR条件(
||) - 只要满足
recaptcha_response_field=hidd3n_valu3或User-Agent=reCAPTCHA任一条件即可绕过
4.3 利用方法
- 拦截密码修改请求
- 修改以下任一参数:
- 设置
recaptcha_response_field=hidd3n_valu3 - 修改User-Agent头为
reCAPTCHA
- 设置
- 提交请求完成密码修改
5. Impossible 安全级别分析
5.1 安全改进
// 单步验证流程
$resp = recaptcha_check_answer( $secret_key, $captcha );
if( !$resp ) {
// CAPTCHA验证失败
} else {
// 检查旧密码是否正确
$pass_curr = $_POST[ 'password_current' ];
$check = $pdo->prepare( 'SELECT password FROM users WHERE user = (:user) LIMIT 1;' );
$check->bindParam( ':user', $user, PDO::PARAM_STR );
$check->execute();
$row = $check->fetch();
// 验证旧密码
if( $row[ 'password' ] != md5( $pass_curr ) ) {
// 旧密码错误
} else {
// 执行密码修改
}
}
5.2 安全措施
- 去除分步验证流程
- 增加Anti-CSRRF token机制
- 使用PDO预处理语句防止SQL注入
- 要求验证旧密码
- CAPTCHA验证无法绕过
6. 防御建议
- 避免分步验证:验证过程应在一个请求中完成
- 服务器端状态管理:使用session记录验证状态而非客户端参数
- 多重验证:结合CAPTCHA与其他验证因素(如旧密码)
- 安全编码:使用预处理语句防止注入
- CSRF防护:添加Anti-CSRRF token
- 严格的逻辑验证:避免使用易绕过的条件判断
7. 总结
Insecure CAPTCHA漏洞展示了验证码实现不当可能导致的安全问题。从Low到Impossible级别的改进过程,体现了安全开发的渐进式思维。开发者应特别注意:
- 不要信任客户端提交的任何参数
- 关键操作应在一个原子请求中完成验证和执行
- 采用深度防御策略,结合多种安全措施
- 定期进行安全代码审计,查找逻辑漏洞