完整教程:dvwa3——CSRF

LOW:

先尝试change一组密码:123456

修改成功,我们观察上面的url代码

http://localhost/DVWA/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#

将password_new部分与password_conf部分改成我们想要的密码:4321

http://localhost/DVWA/vulnerabilities/csrf/?password_new=4321&password_conf=4321&Change=Change#

新建一个页面打开,发现密码修改成功

 MEDIUM:

尝试同样的方法发现请求失败

并且上方跳出来这个 ,第一行说请求头缺失,请求头记录着

查看这一关的源码并与low的做对比 ,多出来的这个if判断条件应该是判断当前的访问请求是否更换页面了,如果不是,就不执行请求

bp抓包原来的请求,可以注意到这里有一个referer


***Referer***:

http请求头中的一个字段,作用是指示当前请求的网页的来源,也就是说, referer后面的内容会告诉服务器该请求来自于哪个页面或者url


在url里面像low一样修改成我们想要的密码,新起一个页面,bp抓包,抓到这些

send to repeater,添加如下代码

Referer:localhost

render!修改成功!!!

HIGH:

我们刚才改的密码是1111,这一级我们要把它改成0000

先提交一个新密码hhhh,并且bp抓包,抓到这些,发现这一关有了token验证

send to intreuder,和第一关一样,先clear,再把三个参数add进去,攻击方式选择Pithchfork

然后去Payloads,在payloas setting里add进我们要修改的密码,防止token失效,我们多加几组

然后和第一关一样,递归找token,先在资源池resoource pool里设置单线程

 settings里(有的版本的dp是options)

回payloads,加上

Start attack!!!!!!!!!!

关闭bp,去第一关,输入用户名和密码

登陆成功!!!!!!!!!

IMPOSSIBLE:

 我们观察一下源码

  1. CSRF Source
  2. vulnerabilities/csrf/source/impossible.php
  3. <?php
  4. if( isset( $_GET[ 'Change'] ) ) {
  5. //Check Anti-CSRF token
  6. checkToken( $_REQUEST['user_token'], $_SESSION['session_token' ], 'index.php' );
  7. // Get input
  8. $pass_curr= $_GET[ 'password_current' ];
  9. $pass_new= $_GET[ 'password_new' ];
  10. $pass_conf= $_GET[ 'password_conf' ];
  11. //Sanitise current passwordinput
  12. $pass_curr=stripslashes( $pass_curr );
  13. $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)) ? "" : ""));
  14. $pass_curr= md5( $pass_curr );
  15. //Check that the current passwordiscorrect
  16. $data = $db->prepare('SELECT password FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' );
  17. $data->bindParam(':user', dvwaCurrentUser(), PDO::PARAM_STR );
  18. $data->bindParam(':password', $pass_curr, PDO::PARAM_STR );
  19. $data->execute();
  20. //Do both new passwords matchanddoes the current password match the user?
  21. if( ( $pass_new==$pass_conf )& & ( $data->rowCount()== 1 ) ) {
  22. //It does!
  23. $pass_new=stripslashes( $pass_new );
  24. $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)) ? "" : ""));
  25. $pass_new= md5( $pass_new );
  26. //Update databasewithnew password
  27. $data = $db->prepare('UPDATE users SET password = (:password) WHERE user = (:user);' );
  28. $data->bindParam(':password', $pass_new, PDO::PARAM_STR );
  29. $data->bindParam(':user', dvwaCurrentUser(), PDO::PARAM_STR );
  30. $data->execute();
  31. //Feedbackforthe user
  32. echo "<pre>Password Changed.</pre>";
  33. }
  34. else {
  35. // Issue withpasswords matching
  36. echo "<pre>Passwords did not match or current password incorrect.</pre>";
  37. }
  38. }
  39. // GenerateAnti-CSRF token
  40. generateSessionToken();
  41. ?>

优化地方:

  1. 使用了pdo预处理:我的理解是提前规划好了传递数据的模板,只从用户的输入中提取数据,而其输入不能当成代码处理,比如 'or '1'=1,只能被当初密码
  2. checktoken
  3. mysqli_real_escape_string 转义
  4. 原密码验证,攻击者很难知道
  5. MD5加密,好像需要彩虹表解密,还不了解

综上,无法突破

❀❀❀ 完结撒花!!❀❀❀ 

posted on 2025-06-05 22:51  ljbguanli  阅读(91)  评论(0)    收藏  举报