内容简介:JSONP注入实战
JSONP注入是一个鲜为人知的但是非常广泛和危险的漏洞。它在近几年才出现,由于JSON,web API和跨域通信的急需。
什么是JSONP
假设每个人都知道JSON是什么,让我们谈谈一下JSONP。 JSONP来自带有填充的JSON,被创建来绕过常见的限制,例如同源策略。
举个例子。 我们的网上银行应用程序, http://verysecurebank.ro ,实现了一个返回当前用户的交易的API调用。
访问 http://verysecurebank.ro/getAccountTransactions 的HTTP请求向我们提供了当前用户的交易内容,JSON格式:
如果我们的报告应用程序,想访问 http://reports.verysecurebank.ro 获得交易详细信息,由于同源原则生效(不同的主机),将无法通过AJAX调用该页面。
为了解决这个问题,JSONP发挥了作用。 由于跨域脚本包含(主要用于外部加载JavaScript库,如jQuery,AngularJS等)是允许但不推荐的,一个聪明的技巧显然解决了整个问题:在响应前加上回调。
注意:即使它可能是显而易见的,值得提及的是,当包括脚本跨域时,它将在包含应用程序的上下文中运行,而不是在源的上下文中运行。
添加一个回调到API响应,包裹JSON格式的数据,允许我们加载脚本标签之间的API响应,并通过定义我们自己的回调函数来处理它的内容。
怎么使用JSONP
这是你最容易遇到的情况:
- 回调函数在响应中硬编码
- 基本函数调用
- 对象方法调用
2.回调函数是动态的
- 完全可控的URL(GET变量)
- 部分可控的URL(GET变量),但附加一个数字
- 可控的URL(GET变量),但最初不显示在请求中
基本函数调用
一个非常常见的示例,其中myCallback回调在响应中硬编码,包裹在JSON格式的数据上:
我们可以通过首先定义myCallback函数,然后在脚本标签中引用API调用来轻松使用它:
注意:确保在包含响应之前定义函数,否则将调用未定义的函数,并且不会获取任何数据。
当登录的受害者访问我们的恶意页面时,我们抓取他的数据。 为了简洁起见,我们在当前页面中显示整齐格式化了的数据。
对象方法调用
这几乎与第一个示例相同,你可能会在ASP或ASP.NET Web应用程序中遇到它。 在我们的示例中,System.TransactionData.Fetch作为回调围绕JSON格式的数据被添加:
我们只是为已经是System对象一部分的TransactionData对象创建Fetch方法。
结果是相同的,所以没有截图。
完全可控的URL(GET变量)
这是你会遇到的最常见的情况。 回调函数在URL中指定,我们可以完全控制它。 回调URL参数允许我们更改回调的名称,因此我们将设置它来测试,并在响应中看它的改变:
我们基本上可以使用相同的代码,但是不要忘记在包含带有脚本标签的响应时添加回调参数。
部分可控的URL(GET变量),但附加一个数字
在这种情况下,回调函数名称附加了一些东西,通常是一个数字。 在大多数情况下,我们得到的东西像jQuery和一个附加到它的短号,像12345,回调成为jQuery12345。
逻辑上,代码保持不变,我们只需要将12345添加到我们的回调函数名称,而不是包含脚本时。
但如果数字不是硬编码怎么办? 如果是动态的、每个会话都不同怎么办? 如果它是一个相对较短的数字,我们可以用过编程预定义每个可能性的函数。 让我们假设附加的数字高达99999。 我们可以以编程方式创建所有这些函数,所以附加的数字,我们已经有一个回调函数。 这里是示例代码,我使用一个更简单的回调来说明结果:
这里发生了什么:我们有硬编码的回调名称jQuery,我们为函数的数量设置了一个限制。 在第一个循环中,我们在callbackNames数组中生成回调函数名。 然后我们循环遍历数组,并将每个回调名称转换为全局函数。 请注意,为了缩短代码,我只提醒第一笔交易中发送的金额。 让我们看看它是如何工作的:
在我的机器上,花了大约5秒钟显示警报,回调名称为jQuery12345。 这意味着Chrome在5秒内创建了超过10.000个功能,所以我大胆地说,这是一个很可行的方法。
可控的URL(GET变量),但最初不显示在请求中
最后一个场景涉及一个显然没有回调的API调用,因此没有可见的JSONP。 这可能发生在开发人员,为其他软件或代码留下隐藏的向后兼容性只是没有在重构时删除。 因此,当看到没有回调的API调用时,特别是如果JSON格式的数据已经在括号之间,手动添加回调到请求。
如果我们有以下API调用 http://verysecurebank.ro/getAccountTransactions ,我们可能会尝试猜测回调变量:
- http://verysecurebank.ro/getAccountTransactions?callback=test
- http://verysecurebank.ro/getAccountTransactions?cb=test
- http://verysecurebank.ro/getAccountTransactions?jsonp=test
- http://verysecurebank.ro/getAccountTransactions?jsonpcallback=test
- http://verysecurebank.ro/getAccountTransactions?jcb=test
- http://verysecurebank.ro/getAccountTransactions?call=test
这些只是最常见的回调名称,请随意猜测更多。 如果我们的回调被添加到响应,bingo,让我们道德地抓取一些数据。
基本数据抓取
因为我们直到现在才显示数据,让我们看看如何把它发送给我们。 这是JSONP数据抓取的一个小示例,可以将其用作概念验证。
我们发送应用响应(比如用户的交易内容)在data参数中的get请求给我们的数据抓取器。
注意:确保对数据使用了 JSON.stringify() ,因为它是一个对象,我们不希望在我们的文件中只有[object Object]。
注意:如果响应很大,请确保切换到POST,因为HTTP GET的大小限制,可能无法接收完整的数据。
这里是我们的grabData.php代码,我们将接收到的数据追加到data.txt文件中:
常见问题
在寻找JSONP漏洞的Web应用程序时,我们可能会遇到一些问题。 这里我们尝试解决他们。
Content-Type和X-Content-Type-Options
如果在API请求的响应标头中,X-Content-Type-Options设置为nosniff,则必须将Content-Type设置为JavaScript(text/javascript,application/javascript,text/ecmascript等)来在所有浏览器上生效。 这是因为通过在响应中包含回调,响应不再是JSON,而是JavaScript。
如果您想知道浏览器解释为JavaScript的内容类型,请访问 https://mathiasbynens.be/demo/javascript-mime-type 。
在此示例中,Content-Type设置为application / json,X-Content-Type-Options设置为nosniff。
最新版本的Google Chrome,Microsoft Edge和Internet Explorer 11成功阻止了脚本执行。 但是,Firefox 50.1.0(目前是最新版本)没有。
注意:如果X-Content-Type-Options:nosniff头未设置,它将适用于所有上述浏览器。
注意:旧版本的浏览器没有考虑严格的MIME类型检查,因为最近实现了X-Content-Type-Options。 根据Mozilla,这是由于浏览器的兼容性:
响应码
有时我们可能会得到一些其他响应代码,而不是200,特别是当我们搞乱了响应。 我在这些浏览器上进行了几个测试:
- Microsoft Edge 38.14393.0.0
- Internet Explorer 11.0.38
- Google Chrome 55.0.2883.87
- Mozilla Firefox 50.1.0
发现了这些不一致:
因此,即使我们没有获得200 HTTP代码,该漏洞仍然可以在其他浏览器中使用。
绕过referer检查
1.使用data URI scheme
如果有HTTP Referer检查,我们可以尝试不发送它来绕过验证。 我们怎么能做到这一点?通过data URI。 我们可以利用data URI scheme,以便在没有HTTP Referer的情况下发出请求。 因为我们处理的代码,包括引号,双引号和其他语法破坏字符,我们将对base64编码我们的payload(回调定义和脚本包含)。
语法:
data:text/plain;base64,our_base64_encoded_code
以下是允许我们使用data URI scheme的三个主要HTML标签:
- iframe(在src属性中) – 它在Internet Explorer中不起作用
- embed(在src属性中) – 它在Internet Explorer和Microsoft Edge中不起作用
- object(在data属性) – 它在Internet Explorer和Microsoft Edge中不起作用
我们可以看到,API请求中没有发送HTTP Referer。
2.从https到http的请求
如果我们的目标网站可以通过HTTP访问,我们还可以通过在HTTPS页面上托管我们的代码来避免发送HTTP Referer。 如果我们从HTTPS页面发出HTTP请求,则浏览器不发送Referer头以防止信息泄露。
我们所有要做的只是在启用HTTPS的网站上托管我们的恶意代码。
注意:由于混合内容安全机制,这不适用于具有默认设置的现代Web浏览器。 受害者已手动接受浏览器的安全警告。
但是,它在旧版本的浏览器中使用,并且不发送HTTP Referer头,我们可以看到:
我们如何解决这个问题
最后,让我们看看我们如何防止这种情况的发生。 最直接和最现代的方法是CORS(跨源资源共享)。
- 完全删除JSONP功能
- 将Access-Control-Allow-Origin标头添加到API响应中
- 使用跨域AJAX请求
因此, http://reports.verysecurebank.ro 将以下跨域AJAX请求嵌入到 http://verysecurebank.ro/getAccountTransactions :
API响应包括Access-Control-Allow-Origin: http://reports.verysecurebank.ro :
我们得到 http://verysecurebank.ro/getAccountTransactions 的内容:
结论
虽然JSONP使用量在减少,但仍然有大量的网站依然在使用它。 作为最后一个提示,当处理JSONP时,也不要忘记检查反射型文件下载和反射型xss。
*参考: securitycafe ,MottoIN Team成员grt1st编译发布。转载请注明来自MottoIN
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 记一次SQL注入实战
- Angular 4 依赖注入教程之二 组件中注入服务
- 服务端注入之Flask框架中服务端模板注入问题
- 服务器端电子表格注入 - 从公式注入到远程代码执行
- SQL注入测试技巧TIP:再从Mysql注入绕过过滤说起
- 手机抓包+注入黑科技HttpCanary——最强大的Android抓包注入工具
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深入理解LINUX内核(第三版)
(美)博韦,西斯特 / 陈莉君;张琼声;张宏伟 / 中国电力出版社 / 2007-10-01 / 98.00元
为了彻底理解是什么使得Linux能正常运行以及其为何能在各种不同的系统中运行良好,你需要深入研究内核最本质的部分。内核处理CPU与外界间的所有交互,并且决定哪些程序将以什么顺序共享处理器时间。它如此有效地管理有限的内存,以至成百上千的进程能高效地共享系统。它熟练地统筹数据传输,这样CPU 不用为等待速度相对较慢的硬盘而消耗比正常耗时更长的时间。 《深入理解Linux内核,第三版》指导你对内核......一起来看看 《深入理解LINUX内核(第三版)》 这本书的介绍吧!