干货!!学习CSRF跨站请求伪造,看这一篇就够了

跨站请求伪造CSRF

CSRF是Cross Site Request Forgery的缩写,乍一看和XSS差不多的样子,但是其原理正好相反,XSS是利用合法用户获取其信息,而CSRF是伪造成合法用户发起请求。

在XSS危害——session劫持中我们提到了session原理,用户登录后会把登录信息存放在服务器,客户端有一个用户标识存在cookie中,只要用户不关闭浏览器或者退出登录,在其有效期内服务器就会把这个浏览器发送的请求当作当前客户,如果这时候用户被欺骗,使用浏览器打开了某些恶意网址,里面就会包含一些不是用户希望发送的请求,服务器也会把这些请求当作是当前客户发送的请求,这时候用户的个人信息、资金安全、如果用户权限高整个站点都可能会受到危害。

CSRF原理

CSRF原理很简单,当用户登录以站点时用浏览器打开一恶意网址,就有可能遭受攻击。有同学会奇怪了这个很难实现吧,必须同时满足两个条件才行。其实很简单,比如我们使用QQ,看看QQ zone,突然蹦出个包含中奖或者问卷调查链接的聊天窗口(或者是。。。),这个腾讯做了防范,但是我们收到封邮件包含此内容,很多用户会选择去点击

在网上找了张图片很能说明这个过程 在这里插入图片描述

简单小例子

在某个论坛管理页面,管理员可以在list.php页面执行删除帖子操作,根据URL判断删除帖子的id,像这样的一个URL

java

复制代码http://localhost/list.php?action=delete&id=12

当恶意用户想管理员发送包含CSFR的邮件,骗取管理员访问http://test.com/csrf.php,在这个恶意网页中只要包含这样的html语句就可以利用让管理员在不知情的情况下删除帖子了

java

复制代码<img alt="" arc="http://localhost/list.php?action=delete&id=12"/>

这个利用了img的src可以跨域请求的特点,这种情况比较少,因为一般网站不会利用get请求修改资源信息

升级

是不是网站利用post修改信息就安全了呢,还拿刚才例子,改成post修改的

java复制代码<?php
            $action=$_POST['action'];
            $id=$_POST['id'];
            delete($action,$id);
        ?>

但是恶意网站这么写一样可以攻击

java复制代码<!DOCTYPE html>
<html>
  <body>
    <iframe display="none">
      <form method="post" action="http://localhost/list.php">
        <input type="hidden" name="action" value="delete">
        <input type="hidden" name="id" value="12">
                <input id="csfr" type="submit"/>
      </form>
    </iframe>

        <script type="text/javascript">
           document.getElementById('csfr').submit();
    </script>
  </body>
</html>

攻击演示 如下表单

java复制代码<form action="buy.php" method="POST">
  <p>
  Item:
  <select name="item">
    <option name="pen">pen</option>
    <option name="pencil">pencil</option>
  </select><br />
  Quantity: <input type="text" name="quantity" /><br />
  <input type="submit" value="Buy" />
  </p>
</form>   

php请求处理

java复制代码  <?php
   
    session_start();
    $clean = array();
   
    if (isset($_REQUEST['item'] && isset($_REQUEST['quantity']))
    {
      /* Filter Input ($_REQUEST['item'], $_REQUEST['quantity']) */
   
      if (buy_item($clean['item'], $clean['quantity']))
      {
        echo '<p>Thanks for your purchase.</p>';
      }
      else
      {
        echo '<p>There was a problem with your order.</p>';
      }
    }
   
  ?>

攻击者尝试使用get方式:store.example.org/buy.php?ite… 如果能成功的话,攻击者如果取得了当合法用户访问时,可以引发购买的URL格式。在这种情况下,进行跨站请求伪造攻击非常容易,因为攻击者只要引发受害者访问该URL即可

攻击者并不需要取得用户授权

用户再访问其他网站的时候,如果这个网站引导用户发起了上面的请求,浏览器会带上用户相关的cookie,相当于非法网站取得了用户授权。

虽然有多种发起跨站请求伪造攻击的方式,但是使用嵌入资源如图片的方式是最普遍的。为了理解这个攻击的过程,首先有必要了解浏览器请求这些资源的方式。

当你访问http://www.google.com,你的浏览器首先会请求这个URL所标识的资源。你可以通过查看该页的源文件(HTML)的方式来看到该请求的返回内容。在浏览器解析了返回内容后发现了Google的标志图片。这个图片是以HTML的img标签表示的,该标签的src属性表示了图片的URL。浏览器于是再发出对该图片的请求,以上这两次请求间的不同点只是URL的不同。

根据上面的原理,跨站请求伪造攻击可以通过img标签来实现。考虑一下如果访问包括下面的源代码的网页会发生什么情况:

java

复制代码<img src="http://store.example.org/buy.php?item=pencil&quantity=50" />

由于buy.php脚本使用REQUEST而不是_REQUEST而不是REQUEST而不是_POST,这样每一个只要是登录在store.example.org商店上的用户就会通过请求该URL购买50支铅笔。

跨站请求伪造攻击的存在是不推荐使用$_REQUEST的原因之一。

防范方法

  1. 使用post,不使用get修改信息
  2. 验证码,所有表单的提交需要验证码,但是貌似用起来很麻烦,所以一些关键的操作可以
  3. 在表单中预先植入一些加密信息,验证请求是此表单发送

使用POST方式而不是使用GET来提交表单,在处理表单提交时使用$_POST而不是$_REQUEST

验证表单来自真正的页面,而不是伪造的。需要验证。

生成表单token

java复制代码  <?php
   
    session_start();
    $token = md5(uniqid(rand(), TRUE));
    $_SESSION['token'] = $token;
    $_SESSION['token_time'] = time();
   
  ?>

提交表单的时候,token也以前提价到服务器。

java复制代码  <form action="buy.php" method="POST">
    <input type="hidden" name="token" value="<?php echo $token; ?>" />
    <p>
    Item:
    <select name="item">
      <option name="pen">pen</option>
      <option name="pencil">pencil</option>
    </select><br />
    Quantity: <input type="text" name="quantity" /><br />
    <input type="submit" value="Buy" />
    </p>
  </form>

一个跨站请求伪造攻击就必须包括一个合法的验证码以完全模仿表单提交。由于验证码的保存在用户的session中的,攻击者必须对每个受害者使用不同的验证码。这样就有效的限制了对一个用户的任何攻击,它要求攻击者获取另外一个用户的合法验证码。使用你自己的验证码来伪造另外一个用户的请求是无效的。

该验证码可以简单地通过一个条件表达式来进行检查:

java复制代码  <?php
   
    if (isset($_SESSION['token']) && $_POST['token'] == $_SESSION['token'])
    {
      /* Valid Token */
    }
   
  ?>  

你还能对验证码加上一个有效时间限制,如5分钟,并且让token只能使用一次:

java复制代码  <?php
   
    $token_age = time() - $_SESSION['token_time'];
    $token = $_SESSION['token'];
    unset($_SESSION['token']);
    if ($token_age <= 300)
    {
      /* Less than five minutes has passed. */
    }
   
  ?>

通过在你的表单中包括验证码,你事实上已经消除了跨站请求伪造攻击的风险。可以在任何需要执行操作的任何表单中使用这个流程。

你也可以让token只能使用一次,在每次请求被请求后token通过后销毁这个token。可以更安全,同时也可以防止表单重复提交。

防范方法

使用cookei验证

如果我们不考虑用户的Cookies很容易由于网站中存在XSS漏洞而被偷窃(我们已经知道这样的事情并不少见)这一事实,这是一个很好的应对对CSRF的解决方案。如果我们为用户的每一个表单请求中都加入随机的Cookies,那么这种方法会变得更加安全,但是这并不是十分合适

java复制代码   <?php
   // Hash the cookie
   $hash = md5($_COOKIE['cookie']);
   ?>
   <form method="POST" action="resolve.php">
        <input type="text" name="first_name">
        <input type="text" name="last_name">
        <input type="hidden" name="check" value="<?=$hash;?>">
        <input type="submit" name="submit" value="Submit">
   </form>

   <?php
   // Check if the "check" var exists
   if(isset($_POST['check'])) {
        $hash = md5($_COOKIE['cookie']);
        // Check if the values coincide
        if($_POST['check'] == $hash) {
             do_something();
        } else {
             echo "Malicious Request!"$$
        }
   } else {
        echo "Malicious Request!"$$
   }
   ?>

最后,为了感谢读者们,我想把我收藏的一些网络安全/渗透测试学习干货贡献给大家,回馈每一个读者,希望能帮到你们。
黑客&网络安全如何学习

今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。

1.学习路线图

攻击和防守要学的东西也不少,具体要学的东西我都写在了上面的路线图,如果你能学完它们,你去就业和接私活完全没有问题。

2.视频教程

网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己录的网安视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。

内容涵盖了网络安全法学习、网络安全运营等保测评、渗透测试基础、漏洞详解、计算机基础知识等,都是网络安全入门必知必会的学习内容。

3.技术文档和电子书

技术文档也是我自己整理的,包括我参加大型网安行动、CTF和挖SRC漏洞的经验和技术要点,电子书也有200多本,由于内容的敏感性,我就不一一展示了。

4.工具包、面试题和源码

“工欲善其事必先利其器”我为大家总结出了最受欢迎的几十款款黑客工具。涉及范围主要集中在 信息收集、Android黑客工具、自动化工具、网络钓鱼等,感兴趣的同学不容错过。

还有我视频里讲的案例源码和对应的工具包,需要的话也可以拿走。

这些题目都是大家在面试深信服、奇安信、腾讯或者其它大厂面试时经常遇到的,如果大家有好的题目或者好的见解欢迎分享。

参考解析:深信服官网、奇安信官网、Freebuf、csdn等

内容特点:条理清晰,含图像化表示更加易懂。

内容概要:包括 内网、操作系统、协议、渗透测试、安服、漏洞、注入、XSS、CSRF、SSRF、文件上传、文件下载、文件包含、XXE、逻辑漏洞、工具、SQLmap、NMAP、BP、MSF…

img

因篇幅有限,仅展示部分资料,如果你对网络安全入门感兴趣,需要的话可以在下方

  • 22
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值