تمرین هفته ۳

در این تمرین یک فایل باینری کامپایل‌شده برای لینوکس به نام mysterious-client در اختیارتان قرار می‌گیرد. هنگام اجرای این برنامه، داده‌ای محرمانه (Secret) به مقصدی نامشخص روی شبکه ارسال می‌شود و برنامه در ترمینال تنها خروجی زیر را چاپ می‌کند:

1Something was sent somewhere you don't know about. Figure it out yourself!

اگرچه این سناریو در ابتدا شبیه به یک چالش سبک CTF (Capture The Flag) به نظر می‌رسد تا یک تسک روتین DevOps، اما مهم ان است که به شما کمک می‌کند مفاهیم شبکه (تفکیک لایه‌ها، پروتکل‌های DNS و TCP، فرآیند TLS Handshake، ساختار درخواست‌های HTTP و سازوکار مخزن گواهی‌های معتبر سیستم‌عامل) را به‌صورت عملی و عمیق درک کنید.

هشدار امنیتی مهم: اجرای باینری‌های ناشناس

یک قاعده‌ی طلایی و همیشگی در امنیت سیستم: هرگز فایل‌های باینری ناشناس و غیرقابل اعتماد را مستقیماً روی سیستم اصلی (Host) خود اجرا نکنید! حتی برای این تمرین و با وجود اینکه (احتمالاً!) به طراح تمرین اعتماد دارید، حتماً این برنامه را داخل یک ماشین مجازی ایزوله (همان VM آزمایشی که در هفته‌ی دوم راه‌اندازی کردید) اجرا کنید، نه روی سیستم شخصی‌تان.

استفاده از هوش مصنوعی در این تمرین

در این تمرین استفاده از هوش مصنوعی برای ابزارسازی (Tooling) — مانند کمک در نوشتن کدهای اسکریپت سرور یا یافتن سوئیچ‌های دستوراتی مثل openssl — مجاز است؛ اما تحلیل ترافیک، درک لایه‌های درگیر، تصمیم‌گیری درباره‌ی معماری راهکار و هدایت فرآیند باید توسط خود شما درک و پیاده‌سازی شود. در مستندات تحویلی باید دلایل اقدامات و تحلیل خود را به زبان خودتان بنویسید.

گام ۱ — دریافت فایل و کشف نام دامنه با tcpdump

فایل باینری را در ماشین مجازی خود دانلود کرده و مجوز اجرای آن را تنظیم کنید:

1mkdir -p ~/week-3-lab && cd ~/week-3-lab
2
3# دریافت باینری
4wget https://iut-cessa.github.io/techstack-1405-devops-docs/bin/week-3/mysterious-client
5
6# تنظیم دسترسی اجرایی
7chmod +x mysterious-client

و یا آن را مستقیماً از طریق پیوند mysterious-client دریافت کنید.

پرسش نخست: این برنامه داده‌ها را به چه مقصدی می‌فرستد؟

تقریبا هر برنامه‌ای پیش از برقراری ارتباط روی وب، ناچار است نام دامنه‌ی سرور مقصد را از طریق پرس‌وجوی DNS به آدرس IP ترجمه کند. شما باید هنگام اجرای برنامه، ترافیک شبکه را زیر نظر بگیرید.

  • با استفاده از ابزار tcpdump (که در درس عیب‌یابی شبکه با آن آشنا شدید)، ترافیک کارت شبکه‌ی خود را شنود و فیلتر کنید تا ببینید برنامه چه نام دامنه‌ای (DNS Query) و چه پورت و پروتکلی را برای ارتباط هدف گرفته است.

یافته‌های خود را در 01-discovery.md ثبت کنید:

  1. دستور دقیق tcpdump که اجرا کردید و فیلتری که به کار بردید.
  2. بخشی از خروجی بسته‌های شنودشده که نام دامنه و پورت مقصد را نشان می‌دهد.
  3. نام دامنه‌ی کشف‌شده، شماره پورت و پروتکل مورد استفاده.

گام ۲ — هدایت ترافیک به سمت سرور خودی (Traffic Redirection)

اکنون که می‌دانید کلاینت به چه دامنه‌ای متصل می‌شود، هدف این است که جریان داده را در اختیار خود بگیرید: کاری کنید که بسته‌های این باینری به جای رفتن به اینترنت، به ماشین خودتان (مثلاً 127.0.0.1) هدایت شوند.

با توجه به اینکه در درس‌های قبلی به جزئیات فایل /etc/hosts پرداخته نشد، پیش از ادامه، این مقاله را بخوانید:

یکی از روش‌های سرراست برای در دست گرفتن ترافیک، استفاده از همین فایل /etc/hosts است (هرچند روش‌های دیگری مانند پیکربندی DNS محلی نیز وجود دارند).

  1. ترافیک دامنه‌ی کشف‌شده را طوری هدایت کنید که به سیستم خودتان اشاره کند.
  2. با ابزارهای تست شبکه تأیید کنید که Resolver سیستم، آن دامنه را به آدرس محلی شما بازمی‌گرداند.
  3. کلاینت را دوباره اجرا کنید:
    1./mysterious-client
    چه اتفاقی می‌افتد؟ چه پیام یا خطایی مشاهده می‌کنید؟ با توجه به آموخته‌های لایه‌های شبکه، دلیل این رفتار چیست؟

مستندات این بخش را در 02-dns-routing.md قرار دهید: روش هدایت، خروجی تست‌های تغییر مقصد و تحلیل چرایی خطای دریافت‌شده هنگام اجرای کلاینت.

گام ۳ — سد اعتبارسنجی TLS و اعتمادسازی گواهی

هدایت ترافیک در لایه‌ی شبکه اولین گام بود، اما با مانع بعدی مواجه می‌شوید: ترافیک این کلاینت با TLS/HTTPS رمزگذاری شده است.

همان‌طور که در درس TLS و HTTPS آموختید، کلاینت در شروع ارتباط یک Handshake امن برقرار می‌کند و گواهی ارائه‌شده توسط سرور را با فهرست مراجع معتبر خود (Trusted CA Store) مطابقت می‌دهد. اگر به سادگی یک سرور با گواهی نامعتبر بالا بیاورید، کلاینت متوجه می‌شود و بلافاصله ارتباط را با خطای اعتبارسنجی گواهی قطع می‌کند.

برای عبور از این مرحله باید خودتان جست‌وجو و تحقیق کنید:

  1. صدور گواهی معتبر برای دامنه: چگونه می‌توان با ابزار openssl یک گواهی Self-Signed (یا یک CA محلی و گواهی امضا‌شده توسط آن) برای دامنه‌ی کشف‌شده صادر کرد؟
    • نکته‌ی مهم: کلاینت‌های امروزی علاوه بر Common Name، بررسی مشخصه‌ی Subject Alternative Name (SAN) را الزامی می‌دانند. جست‌وجو کنید که چطور در دستورات openssl مشخصه‌ی SAN را برای دامنه‌ی مورد نظر تنظیم کنید.
  2. اعتمادسازی در لینوکس: گواهی‌های صادرکننده‌ی معتبر در لینوکس (توزیع اوبونتو/دبیان) در کجا نگهداری می‌شوند و سیستم‌عامل چگونه آن‌ها را به مخزن گواهی‌های معتبر سیستمی اضافه می‌کند؟ (دستور update-ca-certificates را بررسی کنید).
  3. راستی‌آزمایی: پس از اضافه کردن گواهی به سیستم، با دستوری مانند curl یا openssl s_client، اتصال امن به آن دامنه را بدون استفاده از گزینه‌های نادیده‌گرفتن خطا (مانند -k یا --insecure) امتحان کنید تا مطمئن شوید سیستم‌عامل بدون هشدار به گواهی اعتماد می‌کند.

مراحل کار، دستورات صادر کردن گواهی و SAN، شیوه‌ی اعتمادسازی در سیستم‌عامل و نتیجه‌ی راستی‌آزمایی را در 03-tls-ca.md بنویسید.

گام ۴ — راه‌اندازی سرور SSL و شنود پیام محرمانه

اکنون همه مقدمات چیده شده است:

  • ترافیک دامنه‌ی مقصد به ماشین شما می‌آید.
  • سیستم‌عامل به گواهی دست‌ساز شما کاملاً اعتماد دارد.

حالا باید یک وب‌سرور روی پورت مقصد (که در گام اول پیدا کردید) بالا بیاورید که از کلید خصوصی و گواهی صادرشده استفاده کند. این سرور باید درخواست رسیده از سوی mysterious-client را بپذیرد و محتوای بدنه‌ی درخواست (Request Body) و هدرهای آن را نمایش دهد.

انتخاب فناوری و شیوه‌ی راه‌اندازی سرور بر عهده‌ی شماست؛ می‌توانید از هر راهکاری استفاده کنید:

  • نوشتن یک اسکریپت ساده (مثلاً با پایتون، Go یا Node.js)
  • پیکربندی NGINX با فعال‌سازی لاگ برای $request_body
  • استفاده از قابلیت‌های ابزارهای شبکه‌ای دیگر
Privileged Ports

برای گوش‌دادن روی پورت‌های کمتر از 1024 (مانند 443) در لینوکس، اجرای برنامه با دسترسی root الزامی است.

پس از راه‌اندازی سرور:

  1. در ترمینال دیگر، mysterious-client را اجرا کنید.
  2. به خروجی سرور نگاه کنید: چه متدی ارسال شده؟ چه هدرهایی وجود دارد؟ در بدنه (Body) چه پیامی نهفته است؟
  3. کلید یا پیام محرمانه (Secret) چیست؟
پاک‌سازی پس از تمرین

پس از دستیابی به پیام، تنظیمات سیستم را به حالت پیش‌فرض بازگردانید: تغییرات /etc/hosts را حذف کنید و گواهی آزمایشی اضافه شده را پاک کرده و مخزن گواهی‌ها را به‌روز کنید تا تغییرات تمرین روی عملکرد عادی ماشین باقی نماند.

سورس یا کانفیگ سرور، نحوه اجرای آن، لاگ درخواست دریافت‌شده و مقدار Secret را در 04-interception.md قرار دهید.

گام ۵ — ساختار تحویل و Pull Request

مستندات و فایل‌های مربوط به این تمرین را در فورک مخزن تمرین دوره، روی شاخه‌ی week-3 و با ساختار زیر تحویل دهید:

1<your-github-username>/
2└── 3/
3    ├── 01-discovery.md
4    ├── 02-dns-routing.md
5    ├── 03-tls-ca.md
6    ├── 04-interception.md
7    └── assets/
8        ├── server.* (کد سرور یا فایل کانفیگ شما)
9        └── my-ca.crt (فقط فایل گواهی عمومی)
عدم ثبت کلید خصوصی

فایل کلید خصوصی (*.key) را در مخزن کامیت نکنید! تنها فایل عمومی گواهی (.crt) و کدهای سرور باید در پوشه‌ی assets/ باشند.

پیام کامیت خود را بر اساس استاندارد Conventional Commits بنویسید، branch را push کرده و Pull Request خود را ثبت کنید.

چک‌لیست - نمایشی

  • دامنه‌ی مقصد، پورت و پروتکل برنامه را با tcpdump پیدا کرده‌ام.
  • ترافیک دامنه را به سیستم خودی هدایت کرده‌ام.
  • مقاله‌ی ارائه‌شده درباره‌ی /etc/hosts را مطالعه کرده‌ام.
  • درباره‌ی صدور گواهی دارای SAN و اعتمادسازی در لینوکس تحقیق کرده و گواهی معتبر ساخته‌ام.
  • اعتمادسازی گواهی را با curl بدون فلگ ناامن تأیید کرده‌ام.
  • سرور SSL را اجرا کرده و محتوای Body درخواست را شنود کرده‌ام.
  • مقدار Secret را استخراج و در گزارش ثبت کرده‌ام.
  • تغییرات سیستم‌عامل (/etc/hosts و گواهی‌ها) را پس از پایان کار پاک‌سازی کرده‌ام.
  • Pull Request هفته‌ی سوم را باز کرده‌ام.