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 复习常见的高危漏洞,产生,利用 ...
随机推荐
- (Jmeter笔记)设置全局变量,跨线程调用变量,函数助手使用方法__setProperty和__p
需求: 线程2获取线程1的Token成功,并可用 1.使用方法__setProperty定义一个内置函数 2.添加BeanShell后置处理程序 String Token=bsh.args[0]; / ...
- SSM框架 拦截器 出现“发现了以元素 'mvc:exclude-mapping' 开头的无效内容。应以 '{"http://www.springframework.org/schema/mvc":mapping}' 之一开头”错误
导致错误位置与代码: spring-mvc.xml文件中的拦截器配置代码,代码如下: <mvc:interceptors> <mvc:interceptor> <mvc: ...
- 最简单明了的yield from解释
def one(): print('one start') res = yield from two() print('function get res: ', res) return 'one' + ...
- bzoj 3924
动态点分治好题 首先我们考虑一个暴力做法: 每次修改之后选一个点作为根搜索整棵树,然后换根dp即可 考虑每次换根时,移向的点的消耗会减少子树代价之和*边权,而其余部分代价会增加剩余代价*边权 这样每次 ...
- MySQL Atlas 读写分离软件介绍
MySQL Atlas介绍 目录 MySQL Atlas介绍 一.MySQL Atlas介绍 1.1.1 MySQL Atlas介绍 1.1.2 Atlas基本管理 一.MySQL Atlas介绍 1 ...
- 圣诞树代码_HTML
这个冬天给TA栽不一样的圣诞树 直接上效果 <!DOCTYPE html> <html lang="en" > <head> <meta ...
- 用bcftools将多个vcf文件合并成一个vcf文件 或将多个vcf和合并成的vcf文件拆分成单个样本的vcf文件
1. 软件的安装 a. bcftools 的安装 b. bgzip的安装: https://blog.csdn.net/weixin_30471065/article/details/95108525 ...
- linux一些指令
一. 文件操作命令 查看当前目录下的文件或文件夹 详细查看ls –l 每列代表不同的意义: 第一列drwxr-xr-x 表示权限, n 其中第一个字符d表示 目录(可能有b-块 ...
- 递推(dp)纪中真题
前言: 日月如梭,光阴似箭.大家好,我盛艺承又回来了.今天给大家讲一下纪中的DP(递推)真题. 题目描述 在网格中取一个N x 1的矩形,并把它当作一个无向图.这个图有2(N+1)个顶点,有3(N-1 ...
- scroll-view 横向滚动无效
scroll-view的内层view元素需要: display: inline-block scroll-view的外层元素需要: white-space: nowrap 使得内部组件不换行.