
یکی از آسیبپذیریهای رایج که در محیطهای مبتنی بر کانتینر که به دلیل اشتباهات پیکربندی و نبود سازوکار احراز هویت اتفاق میافتد و امکان دسترسی از راه دور به کانتینرهای موجود یک سیستم را برای هکر فراهم میکند در چنین شرایطی، هکر میتواند کنترل کانتینرها را بدون احرازهویت در اختیار بگیرد.
پیش از نگارش این مطلب، حدود یک سال پیش این موضوع را بهصورت مختصر در صفحه لینکدین خودم منتشر کرده بودم؛ اما در اینجا بهصورت جامعتر به بررسی این آسیبپذیری پرداختهام.

برای درک دقیقتر این آسیبپذیری، بهتر است ابتدا به صورت مختصر با مفهوم Docker بهعنوان یکی از پرکاربردترین پلتفرمهای ساخت و اجرای کانتینر آشنا شویم.
داکر یک پلتفرم متنباز و قدرتمند برای Containerize کردن اپلیکیشنها میباشد.منظور از Containerize کردن اپلیکیشن یعنی استفاده از یک تکنولوژی که طی آن اپلیکیشنها با تمامی وابستگیها، کتابخانهها و تنظیمات مورد نیاز خود، در قالب یک Image بستهبندی میشوند تا بتوان از روی آن،کانتینرهای ایزوله و قابل حمل ایجاد و اجرا کرد.
این ساختار باعث میشود اپلیکیشنها در محیطهای مختلف،بدون وابستگی به تفاوتهای زیرساختی،قابل اجرا باشند.استفاده از داکر فرآیندهای ساخت (Build)، استقرار (Deploy) و انتقال اپلیکیشنها را سادهتر، سریعتر و قابلاعتمادتر میکند.به همین دلیل ابزاری بسیار کاربردی و محبوب برای توسعه دهندگان محسوب میشود زیرا این امکان را فراهم میسازد که برنامههایی که در حال توسعه هستند در محیطهای مختلف، از محیط توسعه و آزمایش گرفته تا تولید، بدون نگرانی از ناسازگاری اجرا گردند.
اکنون که به صورت مختصر با داکر و کاربرد آن آشنا شدیم به بررسی این آسیبپذیری می پردازیم.
Docker Remote API یکی از قابلیتهای داکر میباشد که امکان برقراری ارتباط با Docker daemon (Dockerd) را از طریق شبکه فراهم میسازد.این قابلیت به کاربران و سرویسها اجازه میدهد بدون نیاز به دسترسی مستقیم به صورت محلی، کانتینرها، ایمیجها، و سایر منابع داکر را از راه دور مدیریت کنند.Docker daemon (Dockerd) بهعنوان مؤلفه اصلی داکر، درخواستهای دریافتی را از طریق API پردازش کرده و برای اجرای عملیات مربوط به کانتینرها با runtimeهای مانند containerd و runc تعامل میکند.
نکته:معماری اجرای کانتینر در Docker به صورت زیر می باشد.
docker CLI → Docker API → dockerd → containerd → runc → container
داکر برای ارتباط بین Docker CLI (خط فرمان داکر) و (Dockerd) Docker deamon به صورت پیشفرض از Unix Socket استفاده میکند معمولا از Unix Socketها برای ارتباط داخلی اپلیکیشنها توی لینوکس استفاده میگردد.در صورتی که نیاز به مدیریت داکر از طریق شبکه وجود داشته باشد، (Dockerd) Docker daemon باید بهصورت دستی روی یک TCP socket پیکربندی گردد.که در این حالت معمولاً از پورت 2375 برای ارتباطات بدون TLS و از پورت 2376 برای ارتباطات مبتنی بر TLS استفاده میشود.هرچند این پورتها صرفاً بهصورت رایج در نظر گرفته شده و قابل تغییر میباشند.لازم به ذکر است که Docker بهصورت پیشفرض هیچگونه TCP socketای را فعال نمیکند و فعالسازی TLS و مکانیزمهای احرازهویت بر عهده مدیر سیستم میباشد.
معمولا پیکربندی Docker برای فعالسازی ارتباط از طریق TCP میتواند به دو روش انجام شود. روش اول از طریق فایل تنظیمات داکر در مسیر etc/docker/daemon.json/ است که در آن میتوان با مشخص کردن گزینه hosts، آدرسهای مورد نظر (مانند Unix socket یا TCP socket) را تعریف کرد.
روش دوم اجرای مستقیم (Dockerd) Docker daemon بهصورت دستی است، بهطوریکه با استفاده از پارامتر H-میتوان مشخص کرد که daemon روی چه آدرسی گوش دهد. بهعنوان مثال:
dockerd -H tcp://0.0.0.0:2375
نکته: استفاده از آدرس 0.0.0.0 به این معناست که (Dockerd) Docker daemon روی تمامی اینترفیسهای شبکه در دسترس قرار میگیرد. این موضوع از نظر امنیتی بسیار خطرناک میباشد.
حالا به بررسی دقیقتر این آسیبپذیری، نحوه شکلگیری آن و ریسکهای امنیتی مرتبط با آن میپردازیم.
مشکل امنیتی زمانی بهوجود میآید که پورت 2375، که غالباً در اکثر مواقع بدون استفاده از گواهی TLS یا هرگونه احراز هویت است، روی شبکه Expose میشود. از این طریق میتوان به Docker daemon از راه دور متصل شد و عملیات مدیریتی مختلفی را روی کانتینرها انجام داد. این سطح از دسترسی میتواند پیامدهای امنیتی گستردهای برای یک سازمان بههمراه داشته باشد. هکر میتواند از این دسترسی برای اجرای دستورات دلخواه بر روی کانتینرها استفاده کند. در بسیاری از موارد، این دسترسی میتواند منجر به دسترسی به سیستمعامل میزبان گردد، بهویژه اگر کانتینرها با دسترسیهای بالا مانند (privileged-- یا mount کردن دایرکتوریهای حساس) اجرا شده باشند.
معماری حمله در این سناریو به این صورت است که پس از پیکربندی ناامن Docker (مانند فعالسازی API بدون TLS و احراز و استفاده از آدرس 0.0.0.0)، هکر میتواند مستقیماً از راه دور به Docker API متصل شود:
attacker → Docker API → dockerd → containerd → runc → container
این وضعیت از نظر امنیتی بسیار خطرناک است، زیرا در صورت عدم استفاده از TLS و مکانیزمهای احراز هویت، Docker API هیچگونه محدودیتی در پذیرش درخواستها نخواهد داشت. همچنین در صورتی که سرویس روی آدرس 0.0.0.0 در دسترس باشد، تمامی سیستمهایی که به شبکه دسترسی دارند یا از راه دور میتوانند درخواستهای خود را به آن ارسال کنند.در چنین شرایطی، هکر میتواند با ارسال درخواستهای مخرب، اقدام به ایجاد کانتینرهای دلخواه کرده یا با mount کردن root filesystem سیستم میزبان در داخل یک container، به سطح دسترسی بسیار بالایی (حتی معادل root) دست پیدا کند.
بنابراین، یک پیکربندی اشتباه در فعالسازی قابلیت Docker Remote API میتواند منجر به نفوذ کامل به سیستم گردد، حتی اگر سازمان آسیبپذیریهای Server-Side نداشته باشد. تنها یک Misconfiguration ساده میتواند دسترسی اولیه را در اختیار هکر قرار دهد.
برای تشخیص اینکه یک سیستم در برابر این آسیبپذیری Vulnerable است یا خیر، پس از شناسایی باز بودن پورت 2375 میتوان با ارسال یک درخواست ساده به Docker API از راه دور، در دسترس بودن آن را بررسی کرد. این کار معمولاً با استفاده از ابزار curl یا حتی از طریق مرورگر وب قابل انجام است.

مطابق شکل زیر، در صورتی که با اجرای درخواست مربوطه در مرورگر اطلاعاتی از Docker (مانند لیست کانتینرها یا مشخصات سیستم) افشاء گردد، میتوان نتیجه گرفت که در گام نخست Docker API از راه دور در دسترس بوده و سیستم در معرض این آسیبپذیری و Vulnerable است.

لازم به ذکر است که این روش صرفاً برای بررسی اولیه (Proof of Concept) و تأیید در دسترس بودن API کاربرد دارد؛ در حالی که برای مدیریت کامل کانتینرها و اجرای دستورات پیشرفته و مدیریتی ، معمولاً از Docker CLI بهصورت remote استفاده میشود.
جهت رفع این آسیبپذیری یا امن سازی، توصیه میشود اقدامات زیر انجام گردد:
در صورت نیاز به فعالسازی Docker Remote API، از پورت 2376 بههمراه TLS و مکانیزمهای احراز هویت برای مدیریت از راه دور استفاده شود.
محدودسازی دسترسی به پورت 2376 صرفاً به IPهای مشخص و مورد اعتماد
اجتناب از اجرای کانتینرها با سطح دسترسی بالا (مانند استفاده از privileged--) و خودداری از mount کردن دایرکتوریهای حساس سیستم میزبان در داخل کانتینرها