DVWA-Insecure CAPTCHA(不安全的验证码)
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_new和password_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_valu3和User-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(不安全的验证码)的更多相关文章
- DVWA 黑客攻防演练(六)不安全的验证码 Insecure CAPTCHA
之前在 CSRF 攻击 的那篇文章的最后,我觉得可以用验证码提高攻击的难度. 若有验证码的话,就比较难被攻击者利用 XSS 漏洞进行的 CSRF 攻击了,因为要识别验证码起码要调用api,跨域会被浏览 ...
- DVWA全级别之Insecure CAPTCHA(不安全的验证码)
Insecure CAPTCHA Insecure CAPTCHA,意思是不安全的验证码,CAPTCHA是Completely Automated Public Turing Test to Tell ...
- 安全性测试入门 (五):Insecure CAPTCHA 验证码绕过
本篇继续对于安全性测试话题,结合DVWA进行研习. Insecure Captcha不安全验证码 1. 验证码到底是怎么一回事 这个Captcha狭义而言就是谷歌提供的一种用户验证服务,全称为:Com ...
- DVWA之Insecure Captcha
Insecure CAPTCHA Insecure CAPTCHA,意思是不安全的验证码,CAPTCHA是Completely Automated Public Turing Test to Tell ...
- DVWA-全等级验证码Insecure CAPTCHA
DVWA简介 DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法 ...
- Insecure CAPTCHA (不安全的验证码)
dvwa不能正常显示,需要在配置文件中加入谷歌的密钥: $_DVWA[ 'recaptcha_public_key' ] = '6LfX8tQUAAAAAOqhpvS7-b4RQ_9GVQIh48dR ...
- DVWA靶场实战(六)——Insecure CAPTCHA
DVWA靶场实战(六) 六.Insecure CAPTCHA: 1.漏洞原理: Insecure CAPTCHA(不安全的验证码),CAPTCHA全程为Completely Automated Pub ...
- captcha.js一个生成验证码的插件,使用js和canvas生成
一.captcha`captcha.js`是一个生成验证码的插件,使用js和canvas生成的,确保后端服务被暴力攻击,简单判断人机以及系统的安全性,体积小,功能多,支持配置. 验证码插件内容,包含1 ...
- 不安全的验证码Insecure CAPTCHA
没啥好讲的,当验证不合格时,通过burp抓包工具修改成符合要求的数据包.修改参数标志位.USER-AGENT之类的参数. 防御 加强验证,Anti-CSRF token机制防御CSRF攻击,利用PDO ...
- DVWA学习笔记
原来装的DVWA没有认认真真地做一遍,靶场环境也有点问题了,到github上面重新下载了一遍:https://github.com/ethicalhack3r/DVWA 复习常见的高危漏洞,产生,利用 ...
随机推荐
- 4. 模板解析,生成render函数,渲染页面
解析模板,生成render函数,执行render函数,实现视图渲染 1.模板转化成ast语法树 2.ast语法树生成render函数 3.执行render函数生成虚拟dom 4.执行_update方法 ...
- 循环4-for循环
一.语法 for循环和while类似,常用于执行有限次数的循环,有两种语法结构, 1.变量列表循环 语法: for 变量名 in 变量取值列表 do 指令...... done 变量取值列表中的值,要 ...
- taro, h5拨打电话和发送短信
1. h5的实现方式 首先加个允许meta <meta name="format-detection" content="telephone=yes"/& ...
- [iOS] 对 UItableView 等界面(ClipsToBounds) 同时使用 圆角和阴影
展示内容的界面会被 ClipsToBounds = YES(按边缘剪切),但同时需要圆角和阴影效果. 一个界面,ClipsToBounds = YES 之后,阴影会被剪切,不再展示. 感觉只能使用多个 ...
- SpringBoot - 参数校验、统一异常、统一响应
转载自: https://blog.csdn.net/chaitoudaren/article/details/105610962 前言 本篇主要要介绍的就是controller层的处理,一个完整的后 ...
- 关于decimal与double数据类型
关于double和decimal类型, double类型能表示的精度不如decimal,但是其数据范围比decimal的大. 对于double类型的字段,用sum函数会出现多位小数的情况,比如a+b+ ...
- linux下使用bt-rm 限速删除文件
下载限速删除工具: 链接:https://pan.baidu.com/s/1xXu4Hzr99wLlipqxVkXkBg 密码:upbe nohup ./bt-rm -l 10 ${文件地址} &am ...
- count(1) and count(*),count(字段)区别及效率比较
执行结果: count(1)和count(*)之间没有区别,因为count(*)count(1)都不会去过滤空值, count(字段) 会统计该字段在表中出现的次数,忽略字段为null 的情况.即不统 ...
- bat脚本批量删除指定源码编译后的文件
@echo off @REM 使循环内的set命令有效 setlocal enabledelayedexpansion set DIR_ROOT=%~dp0..\ for /f "delim ...
- JAVA pta 前三次大作业回顾与分析
一.前言:总结三次题目集的知识点.题量.难度等情况 今年初次接触java,通过这三次大作业的练习,我对java有了一定的认识,相比于其他编程语言来说,java更复杂,要求也更严谨,需要掌握的知识也更多 ...