鸡肋漏洞组合拳
2020-04-13 15:50:17 Author: www.secpulse.com(查看原文) 阅读量:409 收藏

0x00 前言

最近在挖业务漏洞的时候想起了之前看到过的JSONP劫持,CORS跨域漏洞。这种涉及敏感信息的漏洞一般都是中危以上,并且测试方式简单,所以这次打算研究一下。刚好在昨天碰到了一个涉及到敏感信息的接口,所以在此记录一下。

0x01 漏洞原理

CORS漏洞

简单来说就是服务器配置了http头部字段,让客户端有资格跨域访问资源,而判断客户端权限的依据就是CORS。

我们通过浏览器向服务器发起请求,浏览器为其添加Origin表头(也就是该请求的来源URI),服务器接收到请求后会根据配置信息生成响应包,如果该请求来源是正确的,则允许跨域访问资源。

比如我们设置Origin为 http://foo.example.org 如果在响应头中出现了

Access-Control-Allow-Origin: http://foo.example.org
Access-Control-Allow-Credentials: true

则代表允许跨域访问资源。

所以我们在测试时可以修改Origin的值,通过响应头的内容来判断是否存在CORS漏洞。

不过大部分的厂商应该都是设置为匹配子域名可访问,所以如果我们能找到子域名下的一个XSS(反射型也可以)就能通过XSS+CORS漏洞来形成组合拳。

JSONP劫持漏洞

JSONP是一种协议,它是利用<script>标签的跨域能力实现跨域数据的访问,请求动态生成的JavaScript脚本同时带一个callback函数名作为参数。服务端收到请求后,动态生成脚本产生数据,并在代码中以产生的数据为参数调用callback函数。

借用一张图(https://xz.aliyun.com/t/5143

那么如果一个返回敏感信息的接口存在callback函数,我们可以通过外部写一个js函数,然后通过这个callback调用函数,弹出返回的敏感信息。比如

<script>function jsonp2(data){alert(JSON.stringify(data));}</script>
<script src="http://localhost/userinfo/?callback=jsonp2"></script>

在测试该漏洞的时候也很简单,只要fuzz一下callback参数,看看响应包内容即可。

0x02 实战鸡肋漏洞组合拳

在网站上到处点点,看看有没有返回敏感信息的接口,碰巧就发现了一个。

在这里有一个修改信息的操作,于是我开启抓包看了几个请求,发现一个很像访问接口的请求。

这里已经返回了用户的姓名,住址,电话,***等敏感信息。

看见了Origin我就想着试一试 CORS跨域漏洞,我先尝试修改 Origin为 http://foo.example.org

发现响应包中的Access-Control-Allow-Origin 没了,所以任意构造的Origin是不行的。

那么就尝试了一下它的子域名是否可以(废话

所以我现在的目标就是找一个xss,就是反射型的也可以利用了。

这个waf我绕了很久都绕不过去。。。然后我一点返回,却发现弹窗了

我审查一下元素发现

这居然是个dom型xss。。用户搜索了以后会将查询的内容放到搜索历史中,我总不可能让用户带着我的payload去搜索内容吧,但是CSRF可以啊。

我尝试将搜索的请求报文拿出来生成一个CSRF的POC,看看我自己访问以后搜索历史会不会出现我们的xsspayload。直接利用burp生成。

在生成的html页面直接点击后还是跳转到了waf界面。检查搜索历史,发现并没有payload。

然后我再次思考,既然要用户点击,那是不是可以做一个点击劫持呢?而这个站也刚好有着点击劫持的漏洞。所以我调整了一下按钮的位置最后生成了一个可以利用的页面。

那么问题再次出现,我要怎么把payload输进去,不可能让用户自己敲吧,所以我在想能不能用JavaScript给输入框提前赋默认值。先获取iframe的作为父页面,然后再获取父页面的输入框dom元素进行修改。

<script>
   var childHtml = document.getElementById("frame").contentWindow;
   var a = childHtml.document.getElementById("city").value='abc';
</script>

但是在chrome的console界面我看到无法获取到value的值,那么问题就应该是无法加载iframe中id为city的dom元素,应该是同源策略的问题。

后来我又想了想能否利用JavaScript来复制我们的payload,但是越往后想,我感觉攻击的思路越过于理想化,遂放弃了这个domxss的攻击方法。

重新回到返回敏感信息的接口,我想起了jsonp劫持,我好像还没有fuzz callback函数,结果是并不用fuzz,函数名就是callback。所以直接在本地构造好

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP劫持测试</title>
</head>
<body>
<script>function jsonp2(data){alert(JSON.stringify(data));}</script>
<script src="http://user.xxxx.com/webapi/contact/query/?callback=jsonp2"></script>
</body>
</html>

但是我又翻了看看,这个弹窗里为什么只有姓名手机号和生日,最重要的地址和***号没了呢?回过头去看了一下访问接口的请求包

发现要显示的信息是有参数设置的,而我们又知道jsonp是不能发起post请求的,那么就不能带上这几个参数,但是我又仔细想了想,如果后端设置的并不只是post接收,还可以get接收呢?

修改了一下jsonp劫持的代码。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP劫持测试</title>
</head>
<body>
<script>function jsonp2(data){alert(JSON.stringify(data));}</script>
<script src="http://user.xxxx.com/webapi/contact/query/?callback=jsonp2&attribute=base%2Caddress%2Cinvoice%2Ctravelcard%2Ccredentials&credentialsTypes=1%2C2%2C3%2**%2C5%2C6%2C7%2C8%2C9%2C10%2C11%2C12%2C13%2C14%2C15%2C16"></script>
</body>
</html>

再次访问

这一次,***和地址都出现了。

0x03 后记

这次虽然没有按照预想打出鸡肋漏洞的组合拳,但是也在思考中收获了很多,最终的jsonp劫持没有什么技术含量,师傅们见笑了。

参考文章:

https://gh0st.cn/archives/2017-12-20/1

https://xz.aliyun.com/t/6539

本文作者:星盟安全团队

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/127974.html


文章来源: https://www.secpulse.com/archives/127974.html
如有侵权请联系:admin#unsafe.sh