JSON劫持攻击

此类攻击属于 CSRF( Cross-site request forgery 跨站请求伪造)攻击范畴。当某网站通过 JSONP 的方式来跨域(一般为子域)传递用户认证后的敏感信息时,攻击者可以构造恶意的 JSONP 调用页面,诱导被攻击者访问来达到截取用户敏感信息的目的。

概念理解

同源策略

通俗来说是为了防止网站之间互相进行数据访问一种策略,如www.hack.com可轻松读取www.bank.com中的cookie,利用cookie攻击者可轻松完成登录,进行转账等操作,后果可想而知,因此诞生了同源策略。如果两个页面的协议,端口(如果有指定)和主机都相同,则两个页面具有相同的源。

注意:调用js文件不受同源的影响,并且src属性引入的文件都不受同源的限制,json数据是被js原生支持的。

json

是一种轻量级的数据交换格式

jsonp

全称是 JSON with Padding ,是基于 JSON 格式的为解决跨域请求资源而产生的解决方案。他实现的基本原理是利用了 HTML 里 <script></script>元素标签,远程调用 JSON 文件来实现数据传递。

json劫持

属于 CSRF( Cross-site request forgery 跨站请求伪造)攻击的一种类型,攻击者构造恶意的 JSONP 调用页面,诱导被攻击者访问来达到截取用户敏感信息的目的,下面会进行举例。

举例说明

假设网站有获取用户名和密码的功能。

前端index.php代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<head>
<title>Test</title>
</head>
<body>
<script>
function show(data){
alert("name:"+data.name+"\npass:"+data.pass);
}
</script>

<script src="http://www.test.com/api.php?callback=show&name=admin"></script>
</body>
</html>

后端接口api.php代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$callback = $_GET['callback'];
$data1=array("name"=>"admin","pass"=>"admin");
$data2=array("name"=>"test","pass"=>"test");
if ($_GET['name']==='admin') {
$data=$data1;
}

if ($_GET['name']==='test') {
$data=$data2;
}
exit($callback."(".json_encode($data).")");
?>

显示结果如下:

image-20200229145732284

可以看到,后台通过接收到的callback可动态调用前端js代码。假设作为一个攻击者,当攻击者在登录网站的情况下,我们可以自定义js函数,改变callback的值,使其调用我们自定义的js代码,假设存在网站www.hack.com,诱导受害者访问该网站。

www.hack.comindex.php如下,为了便于查看,还是以弹窗的形式展示数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<head>
<title>Test</title>
</head>
<body>
<script>
function send_data(data){
alert("name:"+data.name+"\npass:"+data.pass);
}
</script>

<script src="http://www.test.com/api.php?callback=send_data&name=admin"></script>
</body>
</html>

结果如下,可以看到敏感数据已经被hack.com获取:

image-20200229145904336

防御

限制referer,同源检测

当服务器端收到调用的请求时,判断是否为该网站发起的请求,进而做下一步判断,修改api.php如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$callback = $_GET['callback'];
if ($_SERVER['HTTP_REFERER']!=='http://www.test.com') {
$error=array("name"=>"error","pass"=>"error");
exit($callback."(".json_encode($error).")");
}
$data1=array("name"=>"admin","pass"=>"admin");
$data2=array("name"=>"test","pass"=>"test");
if ($_GET['name']==='admin') {
$data=$data1;
}

if ($_GET['name']==='test') {
$data=$data2;
}
exit($callback."(".json_encode($data).")");
?>

此时,再次访问hack.com得到如下结果:

image-20200229145957134

这是Chrome 51 开始,浏览器的 Cookie 新增加了一个SameSite属性,用来防止 CSRF 攻击和用户追踪。它可以设置三个值。

Strict:最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。

Lax:规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。

None:显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。

使用token

在服务器端可以给用户生成一个随机的token,设置到攻击页面无法读取的地方,每次请求时带有token,,并验证token的准确性。

绕过

data URI 绕过 referer

data URI不会发送referer头 data还可以使用base64编码

https转到http referer

https转到http会返回一个空的referer (为了防止数据泄露)

绕过token

具体案例

http://www.91ri.org/13407.html

参考链接

1
2
3
https://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html
https://tech.meituan.com/2018/10/11/fe-security-csrf.html
https://xz.aliyun.com/t/6539#toc-8
Author: Sys71m
Link: https://www.sys71m.top/2019/11/10/JSON劫持攻击/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.