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. iOS开发之运行报错 dyld: Library not loaded: *** Reason: image not found

    xcode运行报错 dyld: Library not loaded: @rpath/Flutter.framework/Flutter   Referenced from: /private/var ...

  2. jquery获取父级容器高度

    //获取浏览器显示区域的高度console.log( $(window).height()); //获取浏览器显示区域的宽度console.log($(window).width()); //获取页面 ...

  3. 杭电OJ1029题C++实现

    解题思路:因为要求的数出现的次数总是比其他数字出现的次数多1,所以若总是用相同的数去与其他的数相抵,那么最后只剩下一个,那就是要求的数. 另外需要注意的一点就是,最好不要去开长度为999999的数组, ...

  4. 移动APP测试要点

    一. UI测试 (1) 页面布局 ① 页面布局合理且友好,符合用户习惯 ② 列表型界面有滚动条 ③ 功能入口明显,容易找到 (2) 图形测试 ① 图片大小合适且清晰 ② 页面字体与风格一致 ③ 背景颜 ...

  5. Python基础数据类型-Number(数字)

    a = -1 # int b = 2.0 # float c = 13.11 # float d = 3.14j # complex print(type(a), type(b), type(c), ...

  6. 分布式中间件MyCat 使用

    MySQL 分布式软件MyCAT介绍 目录 MySQL 分布式软件MyCAT介绍 一.MySQL 分布式软件MyCAT介绍 1.1.1 MySQL 分布式软件MyCAT介绍 1.1.2 MyCat 架 ...

  7. 给linux串口,增加登录密码

    一.密码更改 1.在linux系统上,输入passwd,输入需要设定的密码,密码文件保存在/etc/passwd里面. 2.把/etc/passwd文件拷贝出来,放到rootfs的etc/目录下,实现 ...

  8. python 时间戳转日期 不自动补零 without zero-padding

    1. 时间戳转日期 代码 import time timestamp = 1568171336 time_format = "%Y-%m-%d %H:%M:%S" time_loc ...

  9. 【摘】python和它的内置类型子类化

    python和它的内置类型子类化 看个好玩的东西 class Folder(list): def __init__(self, name): self.name = name def dir(self ...

  10. MySQL错误合集

    Error Code: 1052. Column 'Sno' in field list is ambiguous ambiguous意味含糊不清,常见于多个表中有相同名字的属性,在查询时需要分别说明 ...