Insecure CAPTCHA,意思为不安全的验证码

全称为Completely Automated Public Turing Test to Tell Computers and Humans Apart,意思是全自动公共图灵测试,区分计算机和人类

顾名思义,想通过验证码拦截我们的操作,绕过即可

在进行实验前,可能又出现报错信息,只需要修改dvwa目录下得配置文件dvwa/config/config.inc.php

将这两个的值改为统一内容即可

LOW

审计源码

<?php
// 判断 POST 传参 Change ,和 step 为 1
if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) {
// 隐藏验证码表单
$hide_form = true; // 获取输入的新密码和二次密码
$pass_new = $_POST[ 'password_new' ];
$pass_conf = $_POST[ 'password_conf' ]; // 检查第三方验证码
$resp = recaptcha_check_answer(
$_DVWA[ 'recaptcha_private_key'],
$_POST['g-recaptcha-response']
); // 查看验证码正确 if( !$resp ) {
// 判断 $reps 进行了 ! 取反,代表 $resp 返回的错误是一个 True 值
// 验证码错误
$html .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
$hide_form = false;
return;
}
else {
// 验证码正确
// 判断两次输入密码是否想通过
if( $pass_new == $pass_conf ) {
// 进入下一阶段
// 你通过了验证码!单击按钮确认更改。
echo "
<pre><br />You passed the CAPTCHA! Click the button to confirm your changes.<br /></pre>
<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>";
}
else {
// 两次输入密码不匹配
$html .= "<pre>Both passwords must match.</pre>";
$hide_form = false;
}
}
} // 判断传参 Change,并判断 step 是否为 2
// 这里很明显有一个漏洞,这个if语句不在上一个 step 2的嵌套中,直接传参 step == 2 就可以绕过验证码
if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '2' ) ) {
// 隐藏验证码表单
$hide_form = true; // 获取两次输入密码
$pass_new = $_POST[ 'password_new' ];
$pass_conf = $_POST[ 'password_conf' ]; // 检查两次输入密码是否相同
if( $pass_new == $pass_conf ) {
// 相同
// 这里也是用 mysqli_real_escape_string 进行了一个转移,所以sql注入不太理想
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// 使用md5加密输入的新密码
$pass_new = md5( $pass_new ); // 更新数据库
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' ); // 密码更改成功
echo "<pre>Password Changed.</pre>";
}
else {
// 两次输入密码不一致
echo "<pre>Passwords did not match.</pre>";
$hide_form = false;
} ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
} ?>

这里的验证码是调用的Google的,所以需要访问外网就可以调用成功。不能访问可无妨。

一个很明显的错误,step = 2的判断应该在step = 1的嵌套中,所以直接传参step=2,输入两次一样的密码就可以绕过验证码

HackBar测试,当然也可以使用burpsuite



可以看到密码更改成功,更改成功后,我使用更改的密码发现登录失败,使用空密码更改成功

后开看了源码发现,这里传参的两次密码应该是password_newpassword_conf,眼花了,不过没什么问题





所以这里使用burpsuite更好,可以直接获取数据包头

Medium

审计源码

<?php
// 判断传入的 Change 和 step
if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) {
// 隐藏验证码
$hide_form = true; // 获取两次输入密码
$pass_new = $_POST[ 'password_new' ];
$pass_conf = $_POST[ 'password_conf' ]; // 检查引入的 Goolge 验证码
$resp = recaptcha_check_answer(
$_DVWA[ 'recaptcha_private_key' ],
$_POST['g-recaptcha-response']
); // 检测验证码是否正确
if( !$resp ) {
// 验证码错误
$html .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
$hide_form = false;
return;
}
else {
// 验证码正确
if( $pass_new == $pass_conf ) {
// 进入下一阶段
// 你通过了验证码!单击按钮确认更改。
// 这里于上次不同,多加了一个 passed_captcha 传参,值为 true
echo "
<pre><br />You passed the CAPTCHA! Click the button to confirm your changes.<br /></pre>
<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=\"hidden\" name=\"passed_captcha\" value=\"true\" />
<input type=\"submit\" name=\"Change\" value=\"Change\" />
</form>";
}
else {
// 两次输入密码不一致
$html .= "<pre>Both passwords must match.</pre>";
$hide_form = false;
}
}
}
// 判断传入 Change 和 step == 2
if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '2' ) ) {
// 隐藏验证码
$hide_form = true; // 获取两次输入密码
$pass_new = $_POST[ 'password_new' ];
$pass_conf = $_POST[ 'password_conf' ]; // 检查是否完成了一阶段,判断的方式是检查passed_captcha值是否为空
// !取反,如果为空,打印 你没有通过验证码
if( !$_POST[ 'passed_captcha' ] ) {
$html .= "<pre><br />You have not passed the CAPTCHA.</pre>";
$hide_form = false;
return;
} // 检查两次输入密码是否一致
if( $pass_new == $pass_conf ) {
// 一致
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_new = md5( $pass_new ); // 更改数据库密码
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' ); // 打印密码更改成功
echo "<pre>Password Changed.</pre>";
}
else {
// 两次输入密码不一致
echo "<pre>Passwords did not match.</pre>";
$hide_form = false;
} ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
} ?>

这里加入了一个passed_captcha来检测是否通过了step==1阶段,判断的方式是值是否为空,问题很突出,只需要传参任意值

就可以绕过验证码

HackBar测试,这一次我没有输错



由于截图没有完整,这里我输入的是Change=Change&password_new=Admin123&password_conf=Admin123&step=2&passed_captcha=Junglezt

密码更改成功

其实前面这两题可以进行CSRF攻击,直接复制源代码中的HTLM代码就可以

实际步骤这里就不演示了

High

审计源码

<?php
// 获取传入的 Change
if( isset( $_POST[ 'Change' ] ) ) {
// 隐藏验证码
$hide_form = true; // 后去两次输入的密码
$pass_new = $_POST[ 'password_new' ];
$pass_conf = $_POST[ 'password_conf' ]; // 进入验证码
$resp = recaptcha_check_answer(
$_DVWA[ 'recaptcha_private_key' ],
$_POST['g-recaptcha-response']
);
// 判断两种成立条件 resp 验证码返回正常 或者
// POST g-recaptcha-response的值为hidd3n_valu3 和 $_SERVER获取 HTTP_USER_AGENT 值为 reCAPTCHA
// $_SERVER HTTP_USER_AGENT 获取 请求头中的 User-Agent: 值
if (
$resp ||
(
$_POST[ 'g-recaptcha-response' ] == 'hidd3n_valu3'
&& $_SERVER[ 'HTTP_USER_AGENT' ] == 'reCAPTCHA'
)
){
// 验证码正确,判断两次输入密码是否一直
if ($pass_new == $pass_conf) {
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// 使用 md5 加密密码
$pass_new = md5( $pass_new ); // 更新数据库密码
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "' LIMIT 1;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' ); // 打印密码更改成功
echo "<pre>Password Changed.</pre>"; } else {
// 两次输入密码不一致
$html .= "<pre>Both passwords must match.</pre>";
$hide_form = false;
} } else {
// 验证码错误
$html .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
$hide_form = false;
return;
} ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
} // 生成反CSRF令牌,并没有看到验证user_token的地方
generateSessionToken(); ?>

通过审计代码,通过验证码验证只有两种方式,验证码正常或者获取POST传参g-recaptcha-response值为hidd3n_valu3User-Agent值为reCAPTCHA

就可以绕过,所以这次我们使用burpsuite进行抓包测试



如果出现上述错误服务器返回 500 错误的话,是我们刚开始配置dvwa/config/config.inc.php文件中的两个值没有配置一样



配置一样后,或者是user_token值得问题,你需要再次抓包

再次测试





密码更改成功

Impossible

审计源码

<?php
// 判断传入的 Change
if( isset( $_POST[ 'Change' ] ) ) {
// 检查user_token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); // 隐藏二维码
$hide_form = true; // 获取输入的新密码
$pass_new = $_POST[ 'password_new' ];
// 去除左右两边的空
$pass_new = stripslashes( $pass_new );
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_new = md5( $pass_new ); // 获取第二次输入的密码
$pass_conf = $_POST[ 'password_conf' ];
// 去除左右两边的空
$pass_conf = stripslashes( $pass_conf );
$pass_conf = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_conf ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_conf = md5( $pass_conf ); // 获取输入的当前密码
$pass_curr = $_POST[ 'password_current' ];
// 去除左右两边的空
$pass_curr = stripslashes( $pass_curr );
$pass_curr = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_curr ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_curr = md5( $pass_curr ); // 引入 Goolge 验证码进行验证
$resp = recaptcha_check_answer(
$_DVWA[ 'recaptcha_private_key' ],
$_POST['g-recaptcha-response']
); // 判断验证码是否正确
if( !$resp ) {
// 验证码错误发生什么
echo "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
$hide_form = false;
}
else {
// 使用PDO方法查看当前密码
$data = $db->prepare( 'SELECT password FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' );
$data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR );
$data->bindParam( ':password', $pass_curr, PDO::PARAM_STR );
$data->execute(); // 判断两次输入的密码是否一直,并且当前密码是否相同
if( ( $pass_new == $pass_conf) && ( $data->rowCount() == 1 ) ) {
// 更新数据库密码
$data = $db->prepare( 'UPDATE users SET password = (:password) WHERE user = (:user);' );
$data->bindParam( ':password', $pass_new, PDO::PARAM_STR );
$data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR );
$data->execute(); // 打印密码更改成功
echo "<pre>Password Changed.</pre>";
}
else {
// 密码更改失败
echo "<pre>Either your current password is incorrect or the new passwords did not match.<br />Please try again.</pre>";
$hide_form = false;
}
}
} // 生成 CSRF user_token
generateSessionToken(); ?>

验证码检测已经写死了,不能进行绕过,而且还必须输入当前的密码才可以修改密码,引入了user_token防止CSRF攻击

DVWA-Insecure CAPTCHA(不安全的验证码)的更多相关文章

  1. DVWA 黑客攻防演练(六)不安全的验证码 Insecure CAPTCHA

    之前在 CSRF 攻击 的那篇文章的最后,我觉得可以用验证码提高攻击的难度. 若有验证码的话,就比较难被攻击者利用 XSS 漏洞进行的 CSRF 攻击了,因为要识别验证码起码要调用api,跨域会被浏览 ...

  2. DVWA全级别之Insecure CAPTCHA(不安全的验证码)

    Insecure CAPTCHA Insecure CAPTCHA,意思是不安全的验证码,CAPTCHA是Completely Automated Public Turing Test to Tell ...

  3. 安全性测试入门 (五):Insecure CAPTCHA 验证码绕过

    本篇继续对于安全性测试话题,结合DVWA进行研习. Insecure Captcha不安全验证码 1. 验证码到底是怎么一回事 这个Captcha狭义而言就是谷歌提供的一种用户验证服务,全称为:Com ...

  4. DVWA之Insecure Captcha

    Insecure CAPTCHA Insecure CAPTCHA,意思是不安全的验证码,CAPTCHA是Completely Automated Public Turing Test to Tell ...

  5. DVWA-全等级验证码Insecure CAPTCHA

    DVWA简介 DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法 ...

  6. Insecure CAPTCHA (不安全的验证码)

    dvwa不能正常显示,需要在配置文件中加入谷歌的密钥: $_DVWA[ 'recaptcha_public_key' ] = '6LfX8tQUAAAAAOqhpvS7-b4RQ_9GVQIh48dR ...

  7. DVWA靶场实战(六)——Insecure CAPTCHA

    DVWA靶场实战(六) 六.Insecure CAPTCHA: 1.漏洞原理: Insecure CAPTCHA(不安全的验证码),CAPTCHA全程为Completely Automated Pub ...

  8. captcha.js一个生成验证码的插件,使用js和canvas生成

    一.captcha`captcha.js`是一个生成验证码的插件,使用js和canvas生成的,确保后端服务被暴力攻击,简单判断人机以及系统的安全性,体积小,功能多,支持配置. 验证码插件内容,包含1 ...

  9. 不安全的验证码Insecure CAPTCHA

    没啥好讲的,当验证不合格时,通过burp抓包工具修改成符合要求的数据包.修改参数标志位.USER-AGENT之类的参数. 防御 加强验证,Anti-CSRF token机制防御CSRF攻击,利用PDO ...

  10. DVWA学习笔记

    原来装的DVWA没有认认真真地做一遍,靶场环境也有点问题了,到github上面重新下载了一遍:https://github.com/ethicalhack3r/DVWA 复习常见的高危漏洞,产生,利用 ...

随机推荐

  1. 4. 模板解析,生成render函数,渲染页面

    解析模板,生成render函数,执行render函数,实现视图渲染 1.模板转化成ast语法树 2.ast语法树生成render函数 3.执行render函数生成虚拟dom 4.执行_update方法 ...

  2. 循环4-for循环

    一.语法 for循环和while类似,常用于执行有限次数的循环,有两种语法结构, 1.变量列表循环 语法: for 变量名 in 变量取值列表 do 指令...... done 变量取值列表中的值,要 ...

  3. taro, h5拨打电话和发送短信

    1. h5的实现方式 首先加个允许meta <meta name="format-detection" content="telephone=yes"/& ...

  4. [iOS] 对 UItableView 等界面(ClipsToBounds) 同时使用 圆角和阴影

    展示内容的界面会被 ClipsToBounds = YES(按边缘剪切),但同时需要圆角和阴影效果. 一个界面,ClipsToBounds = YES 之后,阴影会被剪切,不再展示. 感觉只能使用多个 ...

  5. SpringBoot - 参数校验、统一异常、统一响应

    转载自: https://blog.csdn.net/chaitoudaren/article/details/105610962 前言 本篇主要要介绍的就是controller层的处理,一个完整的后 ...

  6. 关于decimal与double数据类型

    关于double和decimal类型, double类型能表示的精度不如decimal,但是其数据范围比decimal的大. 对于double类型的字段,用sum函数会出现多位小数的情况,比如a+b+ ...

  7. linux下使用bt-rm 限速删除文件

    下载限速删除工具: 链接:https://pan.baidu.com/s/1xXu4Hzr99wLlipqxVkXkBg 密码:upbe nohup ./bt-rm -l 10 ${文件地址} &am ...

  8. count(1) and count(*),count(字段)区别及效率比较

    执行结果: count(1)和count(*)之间没有区别,因为count(*)count(1)都不会去过滤空值, count(字段) 会统计该字段在表中出现的次数,忽略字段为null 的情况.即不统 ...

  9. bat脚本批量删除指定源码编译后的文件

    @echo off @REM 使循环内的set命令有效 setlocal enabledelayedexpansion set DIR_ROOT=%~dp0..\ for /f "delim ...

  10. JAVA pta 前三次大作业回顾与分析

    一.前言:总结三次题目集的知识点.题量.难度等情况 今年初次接触java,通过这三次大作业的练习,我对java有了一定的认识,相比于其他编程语言来说,java更复杂,要求也更严谨,需要掌握的知识也更多 ...