- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
Insecure CAPTCHA(不安全的验证码),CAPTCHA全程为Completely Automated Public Turing Test to Tell Computers and Humans Apart(全自动区分计算机和人类的图灵测试)的简称。这一模块的内容叫做不安全的验证流程比较好,主要是验证流程出现了逻辑漏洞,而不是谷歌的验证码有问题。这一模块验证码使用的是Google提供的reCAPTCHA服务,以下是验证具体的流程.
服务器通过调用recaptcha_check_answer函数检查用户输入的正确性.
recaptcha_check_answer($privkey,$remoteip,$challenge,$response) 。
参数$privey是服务器申请的private key,$remoteip是用户的IP,$challenge是recaptcha_challenge_field字段的值,来自前端页面,$response是recaptcha_response_field字段的值。函数返回ReCaptchaResponse class的实例,ReCaptchaResponse类有2个属性:
$is_valid是布尔型的,表示校验是否有效.
$error是返回的错误代码.
这里打开DVWA靶场的Inseure CAPTCHA的时候,会发现上方有一行这样的报错“ reCAPTCHA API key missing from config file: D:\phpstudy_pro\WWW\DVWA\config\config.inc.php”这种情况.
出现这种情况是因为使用reCAPTCHA没有申请密钥,因此需要手动填入密钥,打开提示的配置文件找到文件“config.inc.php”,然后我们找到如下:
$_DVWA [ 'recaptcha_public_key' ] = ' ' ; $_DVWA [ 'recaptcha_private_key' ] = ' ';
然后将他们改为如下,然后就可以保存了,最后就可以开始进行实战项目了.
$_DVWA [ 'recaptcha_public_key' ] = '6LdK7xITAAzzAAJQTfL7fu6I-0aPl8KHHieAT_yJg' ; $_DVWA [ 'recaptcha_private_key' ] = '6LdK7xITAzzAAL_uw9YXVUOPoIHPZLfw2K1n5NVQ';
代码分析:
<? php if ( isset ( $_POST [ 'Change' ] ) && ( $_POST [ 'step' ] == '1' ) ) { // Hide the CAPTCHA form $hide_form = true ; // Get input $pass_new = $_POST [ 'password_new' ]; $pass_conf = $_POST [ 'password_conf' ]; // Check CAPTCHA from 3rd party $resp = recaptcha_check_answer( $_DVWA [ 'recaptcha_private_key'], $_POST ['g-recaptcha-response' ] ); // Did the CAPTCHA fail? if ( ! $resp ) { // What happens when the CAPTCHA was entered incorrectly $html .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>" ; $hide_form = false ; return ; } else { // CAPTCHA was correct. Do both new passwords match? if ( $pass_new == $pass_conf ) { // Show next stage for the user $html .= " <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 { // Both new passwords do not match. $html .= "<pre>Both passwords must match.</pre>" ; $hide_form = false ; } } } if ( isset ( $_POST [ 'Change' ] ) && ( $_POST [ 'step' ] == '2' ) ) { // Hide the CAPTCHA form $hide_form = true ; // Get input $pass_new = $_POST [ 'password_new' ]; $pass_conf = $_POST [ 'password_conf' ]; // Check to see if both password match if ( $pass_new == $pass_conf ) { // They do! $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 ); // Update database $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>' ); // Feedback for the end user $html .= "<pre>Password Changed.</pre>" ; } else { // Issue with the passwords matching $html .= "<pre>Passwords did not match.</pre>" ; $hide_form = false ; } (( is_null ( $___mysqli_res = mysqli_close ( $GLOBALS ["___mysqli_ston"]))) ? false : $___mysqli_res ); } ?>
这里修改密码一共有两个步骤,第一步是CAPTCHA的验证环节,第二步是将参数POST到后台。 由于两步操作完全是分开的,没有联系,于是我们可以忽略第一步的验证,直接提交修改申请。 两个步骤对应的step参数不同,可以通过抓取报文并且修改step,来实现的验证绕过。 代码没有对CSRF进行任何的防护,可以利用CSRF进行攻击.
我们开始进行攻击,我们思路就是将第一步跳过直接进行第二步。所以我们这里将输入两个一致的密码不进行验证,直接用Burpsuite进行抓包操作.
将“step1”修改为“step2”重新发送后,得到以下界面,说明修改成功.
代码分析:
<? php if ( isset ( $_POST [ 'Change' ] ) && ( $_POST [ 'step' ] == '1' ) ) { // Hide the CAPTCHA form $hide_form = true ; // Get input $pass_new = $_POST [ 'password_new' ]; $pass_conf = $_POST [ 'password_conf' ]; // Check CAPTCHA from 3rd party $resp = recaptcha_check_answer( $_DVWA [ 'recaptcha_private_key' ], $_POST ['g-recaptcha-response' ] ); // Did the CAPTCHA fail? if ( ! $resp ) { // What happens when the CAPTCHA was entered incorrectly $html .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>" ; $hide_form = false ; return ; } else { // CAPTCHA was correct. Do both new passwords match? if ( $pass_new == $pass_conf ) { // Show next stage for the user $html .= " <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 { // Both new passwords do not match. $html .= "<pre>Both passwords must match.</pre>" ; $hide_form = false ; } } } if ( isset ( $_POST [ 'Change' ] ) && ( $_POST [ 'step' ] == '2' ) ) { // Hide the CAPTCHA form $hide_form = true ; // Get input $pass_new = $_POST [ 'password_new' ]; $pass_conf = $_POST [ 'password_conf' ]; // Check to see if they did stage 1 if ( ! $_POST [ 'passed_captcha' ] ) { $html .= "<pre><br />You have not passed the CAPTCHA.</pre>" ; $hide_form = false ; return ; } // Check to see if both password match if ( $pass_new == $pass_conf ) { // They do! $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 ); // Update database $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>' ); // Feedback for the end user $html .= "<pre>Password Changed.</pre>" ; } else { // Issue with the passwords matching $html .= "<pre>Passwords did not match.</pre>" ; $hide_form = false ; } (( is_null ( $___mysqli_res = mysqli_close ( $GLOBALS ["___mysqli_ston"]))) ? false : $___mysqli_res ); } ?>
我们可以看出基于Low级别,在第二步增加了第一步是否通过的验证,即判断参数passed_captcha是否为真。 Passed_captcha参数是通过POST提交的,整个请求也就是POST请求,故可以人为加上此参数.
接下来我们开始攻击,一共也是分两步,但是不同于Low,我们这次使用Burpsuite开始修改报文,将步骤直接调整到第二步,第二步的验证伪造为已验证。然后我们直接加入passed_captcha参数,混入POST参数提交。 将“step=1”改为“step=2”,然后加上“&passed_capcha=true”即可.
放包以后,我们可以观察到页面显示 “Password Change”成功即是完成.
代码分析:
<? php if ( isset ( $_POST [ 'Change' ] ) ) { // Hide the CAPTCHA form $hide_form = true ; // Get input $pass_new = $_POST [ 'password_new' ]; $pass_conf = $_POST [ 'password_conf' ]; // Check CAPTCHA from 3rd party $resp = recaptcha_check_answer( $_DVWA [ 'recaptcha_private_key' ], $_POST ['g-recaptcha-response' ] ); if ( $resp || ( $_POST [ 'g-recaptcha-response' ] == 'hidd3n_valu3' && $_SERVER [ 'HTTP_USER_AGENT' ] == 'reCAPTCHA' ) ){ // CAPTCHA was correct. Do both new passwords match? 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 ); // Update database $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>' ); // Feedback for user $html .= "<pre>Password Changed.</pre>" ; } else { // Ops. Password mismatch $html .= "<pre>Both passwords must match.</pre>" ; $hide_form = false ; } } else { // What happens when the CAPTCHA was entered incorrectly $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 ); } // Generate Anti-CSRF token generateSessionToken(); ?>
High级别将验证流程合并,通过连续的判断将两个步骤相同的部分合并,避免第一步验证的直接改参绕过。 加入了token机制,有效防止了CSRF漏洞攻击,下面不再做攻击页面.
我们开始攻击,看到了后端代码发现了,及时不验证也有机会绕过验证,于是针对g-recaptcha-response和HTTP_USER_AGENT操作.
同样不验证,直接提交请求对相关参数进行抓包修改.
。
代码分析: 。
<? php if ( isset ( $_POST [ 'Change' ] ) ) { // Check Anti-CSRF token checkToken( $_REQUEST [ 'user_token' ], $_SESSION [ 'session_token' ], 'index.php' ); // Hide the CAPTCHA form $hide_form = true ; // Get input $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 ); // Check CAPTCHA from 3rd party $resp = recaptcha_check_answer( $_DVWA [ 'recaptcha_private_key' ], $_POST ['g-recaptcha-response' ] ); // Did the CAPTCHA fail? if ( ! $resp ) { // What happens when the CAPTCHA was entered incorrectly $html .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>" ; $hide_form = false ; } else { // Check that the current password is correct $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(); // Do both new password match and was the current password correct? if ( ( $pass_new == $pass_conf ) && ( $data ->rowCount() == 1 ) ) { // Update the database $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(); // Feedback for the end user - success! $html .= "<pre>Password Changed.</pre>" ; } else { // Feedback for the end user - failed! $html .= "<pre>Either your current password is incorrect or the new passwords did not match.<br />Please try again.</pre>" ; $hide_form = false ; } } } // Generate Anti-CSRF token generateSessionToken(); ?>
Impossible的代码作为防御模板,使用Anti-CSRF token机制防御CSRF攻击。验证步骤合并为同一步,无需分开,使得验证环节无法绕过。要求输入修改之前的密码,攻击者无法绕过。利用PDO技术输入内容过滤,防止了sql注入.
最后此篇关于DVWA靶场实战(六)——InsecureCAPTCHA的文章就讲到这里了,如果你想了解更多关于DVWA靶场实战(六)——InsecureCAPTCHA的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
实战-行业攻防应急响应 简介: 服务器场景操作系统 Ubuntu 服务器账号密码:root/security123 分析流量包在/home/security/security.pcap 相
背景 最近公司将我们之前使用的链路工具切换为了 OpenTelemetry. 我们的技术栈是: OTLP C
一 同一类的方法都用 synchronized 修饰 1 代码 package concurrent; import java.util.concurrent.TimeUnit; public c
一 简单例子 1 代码 package concurrent.threadlocal; /** * ThreadLocal测试 * * @author cakin */ public class T
1. 问题背景 问题发生在快递分拣的流程中,我尽可能将业务背景简化,让大家只关注并发问题本身。 分拣业务针对每个快递包裹都会生成一个任务,我们称它为 task。task 中有两个字段需要
实战环境 elastic search 8.5.0 + kibna 8.5.0 + springboot 3.0.2 + spring data elasticsearch 5.0.2 +
Win10下yolov8 tensorrt模型加速部署【实战】 TensorRT-Alpha 基于tensorrt+cuda c++实现模型end2end的gpu加速,支持win10、
yolov8 tensorrt模型加速部署【实战】 TensorRT-Alpha 基于tensorrt+cuda c++实现模型end2end的gpu加速,支持win10、linux,
目录如下: 为什么需要自定义授权类型? 前面介绍OAuth2.0的基础知识点时介绍过支持的4种授权类型,分别如下: 授权码模式 简化模式 客户端模式 密码模式
今天这篇文章介绍一下如何在修改密码、修改权限、注销等场景下使JWT失效。 文章的目录如下: 解决方案 JWT最大的一个优势在于它是无状态的,自身包含了认证鉴权所需要的所有信息,服务器端
前言 大家好,我是捡田螺的小男孩。(求个星标置顶) 我们日常做分页需求时,一般会用limit实现,但是当偏移量特别大的时候,查询效率就变得低下。本文将分四个方案,讨论如何优化MySQL百万数
前言 大家好,我是捡田螺的小男孩。 平时我们写代码呢,多数情况都是流水线式写代码,基本就可以实现业务逻辑了。如何在写代码中找到乐趣呢,我觉得,最好的方式就是:使用设计模式优化自己
我们先讲一些arm汇编的基础知识。(我们以armv7为例,最新iphone5s上的64位暂不讨论) 基础知识部分: 首先你介绍一下寄存器: r0-r3:用于函数参数及返回值的传递 r4-r6
一 同一类的静态方法都用 synchronized 修饰 1 代码 package concurrent; import java.util.concurrent.TimeUnit; public
DRF快速写五个接口,比你用手也快··· 实战-DRF快速写接口 开发环境 Python3.6 Pycharm专业版2021.2.3 Sqlite3 Django 2.2 djangorestfram
一 添加依赖 org.apache.thrift libthrift 0.11.0 二 编写 IDL 通过 IDL(.thrift 文件)定义数据结构、异常和接口等数据,供各种编程语言使用 nam
我正在阅读 Redis in action e-book关于semaphores的章节.这是使用redis实现信号量的python代码 def acquire_semaphore(conn, semn
自定义控件在WPF开发中是很常见的,有时候某些控件需要契合业务或者美化统一样式,这时候就需要对控件做出一些改造。 目录 按钮设置圆角
师父布置的任务,让我写一个服务练练手,搞清楚socket的原理和过程后跑了一个小demo,很有成就感,代码内容也比较清晰易懂,很有教育启发意义。 代码 ?
? 1 2
我是一名优秀的程序员,十分优秀!