DVWA Insecure CAPTCHA 不安全验证码通关教程

漏洞简介

验证码这东西,本来是用来区分人和机器的。但如果验证码机制写得有问题,那跟没有也差不多,暴力破解、批量注册什么的照样搞。

这关主要学怎么绕过不安全的验证码。

验证码类型

先了解下常见的验证码:

类型 说明
图形验证码 识别图片里的字符
短信验证码 手机收验证码
邮箱验证码 邮箱收验证码
滑动验证码 拖滑块到指定位置
点击验证码 按顺序点文字

Low 级别

Low 级别用的是 reCAPTCHA,但验证逻辑有问题:

1
2
3
4
5
6
7
8
9
10
11
if( isset( $_POST[ 'Change' ] ) ) {
$hide = $_POST[ 'step' ];
if( $hide == '1' ) {
// 第一步:输入验证码
}
elseif( $hide == '2' ) {
// 第二步:直接改密码,不验证验证码
$pass_new = $_POST[ 'password_new' ];
$pass_conf = $_POST[ 'password_conf' ];
}
}

流程分两步,但第二步根本不检查验证码,直接跳到第二步就行了。

绕过方法

  1. 抓包拦截改密码请求
  2. step=1 改成 step=2
  3. 删掉验证码相关参数
1
step=2&password_new=hacked&password_conf=hacked&Change=Change
  1. 发送,密码改完了

验证码成了摆设。

Medium 级别

Medium 级别在第二步检查了 passed_captcha 参数:

1
2
3
if( $hide == '2' && $_POST[ 'passed_captcha' ] == 'true' ) {
// 改密码
}

但问题是这参数是客户端传过来的,想传啥都行。

绕过方法

  1. 抓包
  2. 加个 passed_captcha=true 参数
1
step=2&passed_captcha=true&password_new=hacked&password_conf=hacked&Change=Change
  1. 发送,又绕过去了

客户端传来的东西哪能信啊。

High 级别

High 级别用 reCAPTCHA API 验证:

1
2
3
4
5
6
7
8
9
10
11
$resp = recaptcha_check_answer(
$_DVWA[ 'recaptcha_private_key' ],
$_POST["recaptcha_challenge_field"],
$_POST["recaptcha_response_field"]
);

if( !$resp->is_valid ) {
// 验证码错误
} else {
// 通过,改密码
}

这个真去调 Google API 验证了,不太好搞。

绕过方法

禁用 JavaScript:

有些验证码依赖前端 JS,禁用浏览器 JS 可能就失效了。

重放攻击:

如果验证码没做一次性使用,抓到验证成功的请求可以重复用。

伪造响应:

如果能拦截 API 响应,可以改成验证成功。

不过说实话,到 High 级别再绕已经比较难了,正常情况下不太现实。

Impossible 级别

Impossible 级别是正确做法:

1
2
3
4
5
6
7
8
9
10
11
12
13
$resp = recaptcha_check_answer(
$_DVWA[ 'recaptcha_private_key' ],
$_POST["recaptcha_challenge_field"],
$_POST["recaptcha_response_field"]
);

if( !$resp->is_valid ) {
dvwaMessagePush( "reCAPTCHA incorrect" );
log_event( "CAPTCHA failed for user: " . dvwaCurrentUser() );
exit;
}

checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

服务端验证,还加了 CSRF Token,验证失败还记日志。这才是正经的验证码实现。

常见绕过方式

绕过方式 说明
参数篡改 改验证相关参数
流程跳过 直接跳过验证步骤
重放攻击 验证成功的请求重复用
禁用 JS 有些前端验证能绕
打码平台 人工识别
OCR 识别 自动识别简单验证码

小结

验证码防护要点:

  1. 一定要在服务端验证,客户端的东西都不能信
  2. 验证码用完就失效,别让人重复用
  3. 设个有效期,过期作废
  4. 错误太多次就锁定
  5. 用成熟的方案,别自己瞎写