概述
略,详细看链接
CSRF依赖:
- web浏览器中有关会话相关信息(比如cookie和http身份验证信息)的处理的行为。
- 攻击者对有效web应用的URL、请求及功能的了解。
- web会话管理只依赖于浏览器知道的信息。
- 存在能够引发立即访问http[s]资源的html标签,比如图片标签img。
第1,2,3点对于漏洞的存在必不可少,而第4点则是实际利用,但并非严格要求。
- 浏览器自动发送标识会话身份的信息。假设有个web站点,和一个刚登陆此站点的用户。在响应中,站点发送一个标识用户会话身份的cookie。一旦浏览器接收到此cookie,此cookie将随着以后发向此网站的请求一起发送。
- (狗屎,看不懂了)If the application does not make use of session-related information in URLs, then the application URLs, their parameters, and legitimate values may be identified. This may be accomplished by code analysis or by accessing the application and taking note of forms and URLs embedded in the HTML or JavaScript.
- 浏览器已知的信息指的是cookie或基于http的身份认证信息,它们保存至浏览器中,并随每个需要验证的请求包一起发送。接下来讨论的漏洞完全依赖于此类验证用户会话的信息。
为了简单起见,考虑GET访问方式的URL(对POST也是用)。如果用户已登录,提交其他请求将附带cookie一起。下图说明了用户如何访问www.example.com
GET请求能用几种方式发送:
- 使用web应用(?)
- 浏览器中输入URL
- 外链(html中跳转的链接)
这些调用难以被web服务分辨。尤其第三种方式可能非常危险。**有很多技术和漏洞能够伪装链接的实际属性。**链接能够被嵌入到邮件信息中,出现在引诱用户的恶意网站中,或出现在托管在第三方平台的内容中(例如其他web站点或HTML邮件)并且指向某站点的资源。如果用户点击此链接,由于他们已经登录了网站,浏览器将随着网站的认证信息发送GET请求到此网站(会话id 或cookie等)。结果就是在网站上执行了用户所不希望的操作,比如在银行站点汇款。
通过使用标签比如img,用户甚至可以不用跟随特定链接,假如攻击者发送给用户一封包含访问以下HTML的URL(非常简化)。
<html>
<body>
...
<img src="https://www.company.example/action" width="0" height="0">
...
</body>
</html>
当浏览器显示这个页面,它将会尝试显示这个指定的来自https://www.company.example 0维图片(不可见)。图片URL未指向正确的图片并不重要,因为它的存在会触发src字段中的指定的请求操作。这在图片下未被禁用的浏览器中发生。大部分浏览器并不禁用图片下载,因为这回破坏大部分web应用的可用性。
这个问题是由以下原因造成的:
- HTML标签引起自动的http请求发送(img是其中一个)
- 浏览器无法分辨img所指向的资源不是个合法图片
- 无论所称图片的资源地址是哪,图片都会加载。即表单和图片本身本身不必位于同一主机或甚至同一域中。
与web无关的html内容可能引用web的组件,浏览器自动构建有效的请求发送给web。这两点使csrf成为可能。没有办法去禁止这类行为,除非使攻击者无法与web功能进行交互。
在集成浏览器和邮件的环境中,简单的显示带有图片引用的邮件信息会提交请求到web应用中,带着相关的cookie。邮件信息可能简单的引入以下有效突破URL。
<img src="https://[attacker]/picture.gif" width="0" height="0">
在这个例子中,[attacker]使由攻击者控制的网站。使用重定向机制,恶意网站可能用http://[attacker]/picture.gif
重定向受害者到http://[thirdparty]/action
并且触发该功能。
cookie并非是涉及此漏洞的唯一例子。会话信息完全由浏览器提供的web应用也容易受到此攻击。这包括仅依赖http身份验证机制的web应用,因为认证信息是浏览器已知的且随每个请求自动发送。这不包括基于表单的验证,它只发还望一次且生成某种形式与会话相关的信息,通常是cookie。
让我们假设用户已登录一个防火墙web管理控制台。为了登录,用户必须进行身份验证,并且会话信息存储在cookie中。
让我们假设防火墙web管理控制台有个功能,允许一名已登录用户删除一个由ID指定的规则,或所有规则,如果用户指定为*(现实中的一项危险功能,但这是一个更有趣的例子)。删除功能页面如下所示。让我们假设这个表单提交了一个GET请求(为了简单起见)。为了删除ID为1的rule:
https://[target]/fwmgt/delete?rule=1
为了删除所有rules:
https://[target]/fwmgt/delete?rule=*
这个例子有意简单的,但展示了CSRF的危害。
使用上图中的表单,输入*并点击删除按钮将提交以下GET请求:
https://www.company.example/fwmgt/delete?rule=*
这将删除所有防火墙的规则。
用户可能完成此功能,通过手动发送URL:
https://[target]/fwmgt/delete?rule=*
或通过直接或者重定向指向上述URL的链接。或者,再一次,通过访问嵌入指向此URL的img标签的html网页。
在所有这些例子中,如果用户最近已经登录防火墙管理应用,此请求将会成功并修改防火墙的配置。我们可以想到攻击者会以敏感的web应用为目标,进行自动竞标、汇款、订单以及更改关键软件组件的配置等。
有趣的是,这些漏洞可能在防火墙后面执行。即只要攻击者攻击的链接能被受害者访问到就足够了,攻击者不必要访问到。特别是在内网中。举个例子,在前面防火墙管理的场景中,他不可能在互联网中访问到。
Self-vulnerable applications,即既用作攻击媒介,又用作目标的web应用(比如web邮件应用),会更糟糕。因为当用户浏览邮件时,他已经登录,一个易受CSRF攻击的web应用允许攻击者执行类似删除信息或发送信息的操作,它们都来自受害者。(简单说就是蠕虫了,自身作为CSRF的攻击端,能够执行CSRF的链接,同时又是受害端,会执行CSRF的链接内容。)
测试目标
- 确定是否可以发起不是由用户发起的请求。
如何测试
审查web应用以确定会话管理是否容易受到攻击。**如果会话管理仅依赖客户端的值(浏览器可用信息),那么这个web应用则容易受到CSRF攻击。**客户端的值涉及cookies和http认证证书(基本认证以及其他形式的http认证。不是基于表单的认证,这是应用程序级别的认证。)
通过http的GET请求获得资源,容易受到攻击,尽管POST请求也可以通过JS自动执行,并且也容易受到攻击。因此,仅使用POST方法不足以抵御CSRF的发生。
如果是POST,以下示例可以被使用:
- 创建一个和下面展示类似的html页面
- 托管html在恶意网站或第三方平台
- 发送此页面的链接给受害者,并引诱他们点击链接
<html>
<body onload='document.CSRF.submit()'>
<form action='http://targetWebsite/Authenticate.jsp' method='POST' name='CSRF'>
<input type='hidden' name='name' value='Hacked'>
<input type='hidden' name='password' value='Hacked'>
</form>
</body>
</html>
如果在开发者使用json给浏览器和服务器之间交互的web应用中,由于不存在json格式的查询参数(which are a must with self-submitting forms.)(自己提交的表单?),所以可能会出现问题。为了绕过,我们可以使用带json载荷(包含隐藏输入值)的self-submitting form来利用CSRF。我们必须修改加密方式(enctype
)为text/plain
,以包重载荷能原样传递出去。利用代码如下所示:
<html>
<body>
<script>history.pushState('', '', '/')</script>
<form action='http://victimsite.com' method='POST' enctype='text/plain'>
<input type='hidden' name='{"name":"hacked","password":"hacked","padding":"'value='something"}' />
<input type='submit' value='Submit request' />
</form>
</body>
</html>
此POST请求将如下所示:
POST / HTTP/1.1
Host: victimsite.com
Content-Type: text/plain
{"name":"hacked","password":"hacked","padding":"=something"}
当此数据作为POST请求发送,服务器会很开心的接收name和password字段,并且忽略padding字段,因为它并不需要。
CSRF利用实验
1.简单的GET请求
初始密码为admin,页面如下:
GET请求如下
构建触发此GET请求的页面:
访问查看效果
重新登陆时候密码已经变更为qwe。
至此,CSRF完成。
2.POST方法
由于dvwa都是get方法,因此就只模拟post发包。
构建恶意页面,访问后会自动提交post请求到192.168.2.69页面(这里是自身页面):
访问结果,如与其一般提交了post请求并打印了post表单的值。
查看burp能够发现其会不断发送此post请求。
3.json格式的post请求。
构建恶意页面
发送请求查看结果,可以看到成功发送json数据包。
最后一点,能用burp自动生成csrf的poc
他会自动生成发送此请求包的html代码。
更新:
无token无referer验证的情况较少,一般出现在新上线的业务中。
我们先测试referer值,如果不报错,则可以去看token的影响。如果报错,我们可以测试referer,尝试修改部分字段,
如:原referer为t.qq.com/xxx的话,试着修改为t.qq.com.baidu.com/xxx。如果服务器只是验证了referer是否存在t.qq.com或者qq.com等关键词。针对后一种情况。可以在腾讯的某个子站点(http://xx.qq.com)发个贴,将图片地址修改为我们构造的csrf链接或者鞋好csrf表单后,将地址发不在微博等待其他用户点击。针对前一种情况,我们可以建立个t.qq.com.yourdomain.com的域名,存放csrf表单来绕过referer检测。
token部分,如果存在xss的话,可能点击链接后自动访问目标网站且获取token,然后进行提交.