نگاره‌هایی پیرامون امنیت، شبکه و رمزنگاری

10 مارس 2021

چالش Anonymous Playground از CTF های tryhackme.com است که قراره حلش کنیم .

شکل 1

خوب مقدمه دیگه ای نیاز نیست بزن بریم 🙂

خوب بعد از روشن کردن ماشین اولین کاری که میکنیم پورت اسکن هست که ببینیم چه پورت هایی با چه سرویسی ران هستش :

شکل 2 – port scan
شکل 3 – port scan result

خوب یه وب سرور آپاچی (ورژنشم به دردمون نمیخوره) داریم که روی پورت 80 هستش و OpenSSH 7.6p1 رو هم داریم که روی پورت 22 داره اجرا میشه  .
بریم سراغ وب سرور ببینیم چی داره :

شکل 4 – home page

بریم یه view source بگیریم شاید اونجا چیزی بود :

شکل 5 – home page HTML source

خوب اینجا رو هم من برسی کردم چیز خاصی نبود ، بریم ببینیم Operatives و Contact چی دارن ، Contact که چیزی نداشت ولی Operatives یسری یوزرنیم به ما میده :

شکل 6 – Operatives content

اینارو یه جا مینویسم که شاید بعدا به درد بخوره .

خوب بریم یه سرچ بکنیم ببنیم با OpenSSH ورژن 7.6p1 میتونیم کاری بکنیم یا نه :

شکل 7- OpenSSH 7.6p1 Vulnerabilites

همونطور که میبنید ما میتونیم روی این ورژن user enumeration انجام بدیم و یوزر هایی که مجاز به SSH هستن رو پیدا کنیم ، خوب من میام اون یوزر هایی که تو Operatives پیدا کردم رو اینجا تست میکنم که ببینم کدوماشون valid هستند :

شکل 8 – SSH user enumeration result

خوب این یوزرا رو داشته باشید ، بریم ببینیم دیگه چی میتونیم پیدا کنیم ، خوب میریم ببینم فایل robots.txt وجود داره یا نه و اگه داره چیا توشه :

شکل 9 – robots.txt content

جالبه ?

 بریم ببنیم اینجا چی داریم zYdHuAKjP/

شکل 10 – zYdHuAKjP content/

خوب میگه که شما نمیتونید به این صفحه دسترسی داشته باشید ، بریم ریکوئست ارسالی رو با برپ برسی کنیم:

شکل 11 – request for accessing to /zYdHuAKjP

مقدار کوکی access که تو ریکوئست ارسال میشه برابر denied هست و احتمالا سطح دسترسی ما هم بر اساس مقدار همین کوکی مشخص میشه ، خوب کوکی رو کاربر میتونه به سادگی تغییر بده ، منم با تغییر مقدار کوکی access و فرستادن مجدد درخواست سعی میکنم ، سطح دسترسی ام رو تغییر بدم ، بعد از یکم بازی کردم با مقدار کوکی (allow , allowed , true, … ) مقدار granted رو ست کردم و این همون چیزی بود که میخواستم :

شکل 12 – access=granted

خوب الان یه ciphertext داریم (hEzAdCfHzA::hEzAdCfHzAhAiJzAeIaDjBcBhHgAzAfHfN) که باید سعی کنم decose اش کنم ، با یسری مکانزیم شناخته شده سعی کردم decode اش کنم که نتیجه ای در بر نداشت ، و با گفتن “جهنم و ضرر” رفتم سراغ هینت :

شکل 13 – Hint

خوب ساده شد ، اگه zA = a هست ، z آخرین حرف آلفبا یعنی 26 امیش و a هم 1 ، (26+1 برابر با 27 هست که به پیمانه 26 میشه 1 ، یک هم همون a هست .)
خوب براش با پایتون یه اسکریپت ساده مینوسیم :

شکل 14 – decoder code

توضیح کد : خوب اول میاییم دو تا کاراکتر دو تا کاراکتر ciphertext رو میخونیم کاراکتر اول رو به اسکی تبدیل میکنیم بعدش اونو منهای 96 میکنیم که مکان اون کاراکتر رو تو آلفابت پیدا کنیم ، با کاراکتر دوم هم همین کارو میکنیم با این تفاوت که کد اسکی کاراکتر های بزرگ با کوچیک باهم فرق میکنه ولی در نهایت مکانشون فرقی نمیکنه ما قبل اینه که به اسکی تبدیلش کنیم حرف دوم که بزرگ هست رو تبدیل به کاراکتر کوچیکش میکنیم که تفاوتی تو مکانش ایجاد نشه (پس از تبدیل شدن به اسکی کد) و بعدش باقی مانده تقسیم مجموع هر دو رو به 26 رو حساب میکنیم که مکان plaintext رو تو آلفابت پیدا کنیم ، بعدش اونو به علاوه 96 میکنیم که بتونیم اسکی کدشو پیدا کنیم که بعد بتونیم اونو با متود chr به استرینگ تبدیل کنیم و نتیجه اش رو ببنیم 🙂

خوب همین کارو با بخش دوم cipher انجام میدیم :

شکل 15- Second part of ciphertext

خیله خوب پس شد magna::magnaisanelephant ، یادتون باشه magna یکی از یوزر هایی که تو ssh user enumeration به دست آوردیم (شکل 8) و magnaisanelephant هم احتمالا پسوردشه .
بریم تست کنیم ببینیم 🙂

شکل 16- ssh with magna credential

موفق شدیم و اولین فلگ رو هم به دست آوردیم ، بریم ببنیم note_from_spooky.txt چی داره :

شکل 17

خوب note_from_spooky.txt یه Hint بود که بریم سراغ فایل hacktheworld همونطور که میبینید یه فایل باینری هست که از همه مهم تر ما میتونیم اجراش کنیم و SUID یوزر روت رو هم داره یعنی با دسترسی های روت اجرا میشه ، خوب بریم ببینیم چیکار میکنه :

شکل 18

خوب به نظر کار خاصی نمیکنه ازمون یه ورودی میگیره و بعدش terminate میشه 🙁
ولی ما ناامید نمیشیم و میریم که دیباگش کنیم : ( با همون radare2 که تو فایل هینتی که داشت نوشته بود. )

شکل 19- functions list

خوب همونطور که میدونید برنامه از تابع main شروع به اجرا شدن میکنه ،بریم ببنیم تو main چه خبره :

شکل 20- disassembly of main function

خوب برنامه روال عادیشو طی میکنه “Who do you want to hack” رو چاپ میکنه ، بعدش با استفاده از تابع gets از کاربر یه string میگیره و خارج میشه ، ولی مشکلی که هست تابع gets به buffer overflow آسیب پذیر هست و طول ورودی تابع چک نمیشه ، و اگه طول ورودی از buffer بیشتر باشه اصطلاحا buffer سریز میشه و برنامه کرش میکنه ، و در واقع ورودی ما خارج از محدوده buffer مشخص شده نوشته میشه ، خوب ما یه ورودی میدیم که باعث بشه اون چیزی که میخواییم تو EIP نوشته بشه و EIP در واقع یه Pointer هست به دستور العمل بعدی ای که قراره اجرا بشه ، اگه ما بتونیم اون رو بازنویسی کنیم میتونیم روال اجرا برنامه رو به کنترل خودمون دربیاریم ، ولی خوب حالا چیکار کنیم ، یه نگاه به توابع دیگه که در برنامه هست بندازید :

شکل 21

خوب این تابع جالب به نظر میرسه ، بریم ببنیم چیکار میکنه :

شکل 22 – disassembly of call_bash function

اول یه سری پیغام چاپ میکنه ، بعد از اجرا هر پیغام با صدا زدن تابع sleep ، یک ثانیه روال اجرا برنامه متوقف میشه ، و در آخر تابع setuid رو صدا میزنه و دسترسی برنامه (که روت بود) به یوزر آیدی 1337 تغییر میکنه ، بعدشم تابع system و مقدار /bin/bash به عنوان ورودیش ، الان ما اگه بتونیم یه کاری کنیم که تابع 0x00400657 اجرا بشه یه شل داریم ، خوب اول باید بفهمیم که سایز بافر دقیقا چقدره :

شکل 23

خوب میبنید که برنامه به ازا ورودی به طول 72 کرش میکنه ، خوب حالا بعد از سریز شدن مقدار EIP رو هم بازنویسی کنیم که به ادرسی که ما میخواییم اشاره کنه (0x00400657) :

شکل 24 – (0x00400657) EIP = call_bash function

دلیل اینکه آدرس تابع به صورت برعکس نوشته شده است این است که به خاطر معماری stack که LIFO هست ، آخرین ورودی به عنوان اولین خروجی است که در stack نوشته میشود و ما برای نوشته شدن 0x00400657 در stack باید آن را برعکس بنویسم که بعد از برعکس شدن دوباره به حالت درست دربیایید.

خوب پیغام ها چاپ شدن یعنی تابعی که ما میخواستیم اجرا شد ولی چرا bin/bash/ بهمون شل نداد ؟
در واقع /bin/bash هم اجرا شد ولی ما بهش ورودی ای ندادیم که بخواد چیزی نشون بده ، بهش یه ورودی میدیم :

شکل 25

خوب الان cat به عنوان ورودی /bin/bash/ اجرا شد و ما یه شل داریم ، دیگه چی داریم :

شکل 26 – user flag

خوب فلگ دوم رو هم به دست آوریم که مربوط به یوزر spooky هست، حالا باید فلگ root رو به دست بیاریم. برای این کار باید سطح دسترسی خود را به یوزر root ارتقا بدیم ، بیایید ورژن sudo رو ببنیم :

شکل 27 – Sudo version
Sudo Heap-Based Buffer Overflow Vulnerability — CVE-2021-3156

خوب بنظر میرسه که به آسیب‌پذیری که همین چند وقت پیش پیدا شده آسیب پذیر باشه، بریم اکسپلویتش کنیم :


(The exploit used is available here )

شکل 29 – root flag
🙂

پ.ن: شاید بپرسید چرا از همون اول sudo رو اکسپلویت نکردی، باید بگم که اینجوری مزه‌اش از بین میرفت.
یکی از لذت بخش ترین قسمت چالش همون buffer overflow اش بود.

1 پست نوشته شده
دوستدار امنیت، ریاضی و هر چیزی که باعث بشه از حل کردن مسائلش لذت ببرم.