安全矩阵

 找回密码
 立即注册
搜索
查看: 4201|回复: 0

鸡肋漏洞组合拳

[复制链接]

991

主题

1063

帖子

4315

积分

论坛元老

Rank: 8Rank: 8

积分
4315
发表于 2020-4-11 11:52:46 | 显示全部楼层 |阅读模式
本帖最后由 gclome 于 2020-4-11 11:54 编辑

原文链接:鸡肋漏洞组合拳

0x00 前言

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

0x01 漏洞原理
CORS漏洞
简单来说就是服务器配置了http头部字段,让客户端有资格跨域访问资源,而判断客户端权限的依据就是CORS。
我们通过浏览器向服务器发起请求,浏览器为其添加Origin表头(也就是该请求的来源URI),服务器接收到请求后会根据配置信息生成响应包,如果该请求来源是正确的,则允许跨域访问资源。
比如我们设置Origin为 http://foo.example.org 如果在响应头中出现了
  1. Access-Control-Allow-Origin: http://foo.example.org
  2. 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调用函数,弹出返回的敏感信息。比如
  1. <script>function jsonp2(data){alert(JSON.stringify(data));}</script>
  2. <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元素进行修改。
  1. <script>
  2. var childHtml = document.getElementById("frame").contentWindow;
  3. var a = childHtml.document.getElementById("city").value='abc';
  4. </script>
复制代码

但是在chrome的console界面我看到无法获取到value的值,那么问题就应该是无法加载iframe中id为city的dom元素,应该是同源策略的问题。
后来我又想了想能否利用JavaScript来复制我们的payload,但是越往后想,我感觉攻击的思路越过于理想化,遂放弃了这个domxss的攻击方法。
重新回到返回敏感信息的接口,我想起了jsonp劫持,我好像还没有fuzz callback函数,结果是并不用fuzz,函数名就是callback。所以直接在本地构造好
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>JSONP劫持测试</title>
  6. </head>
  7. <body>
  8. <script>function jsonp2(data){alert(JSON.stringify(data));}</script>
  9. <script src="http://user.xxxx.com/webapi/contact/query/?callback=jsonp2"></script>
  10. </body>
  11. </html>
复制代码


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


发现要显示的信息是有参数设置的,而我们又知道jsonp是不能发起post请求的,那么就不能带上这几个参数,但是我又仔细想了想,如果后端设置的并不只是post接收,还可以get接收呢?
修改了一下jsonp劫持的代码。
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>JSONP劫持测试</title>
  6. </head>
  7. <body>
  8. <script>function jsonp2(data){alert(JSON.stringify(data));}</script>
  9. <script src="http://user.xxxx.com/webapi/contact/query/?callback=jsonp2&attribute=base%2Caddress%2Cinvoice%2Ctravelcard%2Ccredentials&credentialsTypes=1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11%2C12%2C13%2C14%2C15%2C16"></script>
  10. </body>
  11. </html>
复制代码
再次访问


这一次,身份证和地址都出现了。


0x03 后记
这次虽然没有按照预想打出鸡肋漏洞的组合拳,但是也在思考中收获了很多,最终的jsonp劫持没有什么技术含量,师傅们见笑了。
参考文章:
https://gh0st.cn/archives/2017-12-20/1
https://xz.aliyun.com/t/6539







回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-9-19 09:03 , Processed in 0.015105 second(s), 19 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表