SSRF؛ وقتی سرور به جای تو درخواست می‌فرستد

SSRF: When the server sends requests on your behalf
0 دیدگاه
۱۴۰۵-۰۷-۱۳ ۱۱:۲۳:۵۳

نویسنده: SINISTER | رضا فروزان
برند: صفر و یک سایبر
سطح: متوسط تا پیشرفته
حوزه: Web Application Security
محیط تمرین: آزمایشگاه محلی و مجاز


۱. SSRF چیست؟

تصور کن یک وب‌سایت قابلیتی دارد که یک URL از کاربر دریافت می‌کند و سپس سرور آن URL را باز می‌کند.

برای مثال:

User
  ↓
Web Application
  ↓
Server
  ↓
Requested URL

در حالت عادی شاید برنامه برای دریافت یک تصویر، بررسی یک لینک یا اتصال به یک سرویس خارجی از این قابلیت استفاده کند.

اما یک سؤال مهم وجود دارد:

اگر کاربر بتواند مقصد درخواست سرور را کنترل کند، سرور دقیقاً به چه مقصدهایی می‌تواند دسترسی داشته باشد؟

اینجا مفهوم Server-Side Request Forgery یا SSRF مطرح می‌شود.

در SSRF، برنامه به شکلی ناامن اجازه می‌دهد درخواست سمت سرور تحت تأثیر ورودی کاربر قرار بگیرد.


۲. تفاوت SSRF با درخواست معمولی

در یک درخواست معمولی:

Browser → Web Server → Internet

کاربر مستقیماً درخواست را ارسال می‌کند.

اما در یک قابلیت آسیب‌پذیر:

Browser
   ↓
Web Application
   ↓
Server-Side Request
   ↓
Destination

درخواست دوم را سرور ارسال می‌کند.

این تفاوت بسیار مهم است.

چون سرور ممکن است:

  • شبکه متفاوتی داشته باشد؛
  • به سرویس‌های داخلی دسترسی داشته باشد؛
  • DNS متفاوتی استفاده کند؛
  • مجوزهایی داشته باشد که مرورگر کاربر ندارد؛
  • به منابعی دسترسی داشته باشد که از اینترنت عمومی قابل مشاهده نیستند.

بنابراین SSRF فقط مسئله «ارسال یک HTTP Request» نیست؛ مسئله مرز اعتماد شبکه و دسترسی سرور است.


۳. یک مثال معماری

فرض کن برنامه چنین قابلیتی دارد:

GET /fetch?url=https://example.com/image.png

برنامه URL را دریافت می‌کند و سرور آن را درخواست می‌کند.

معماری:

          Internet
             │
             ▼
        ┌──────────┐
        │  Browser │
        └────┬─────┘
             │
             ▼
      ┌──────────────┐
      │ Web Server   │
      │ Application  │
      └──────┬───────┘
             │
             ▼
       External URL

اگر برنامه فقط مقصدهای موردنیاز را اجازه ندهد، سطح حمله ایجاد می‌شود.


۴. چرا SSRF خطرناک است؟

شدت SSRF کاملاً به معماری سیستم بستگی دارد.

در یک سناریوی ساده ممکن است برنامه فقط بتواند به منابع عمومی دسترسی پیدا کند.

اما در معماری‌های پیچیده‌تر، سرور ممکن است به:

  • سرویس‌های داخلی؛
  • APIهای خصوصی؛
  • پنل‌های مدیریتی؛
  • سرویس‌های توسعه؛
  • سرویس‌های ابری؛
  • سیستم‌های موجود در شبکه داخلی

دسترسی داشته باشد.

بنابراین هنگام تست SSRF، سؤال اصلی فقط این نیست که:

«آیا سرور درخواست من را ارسال می‌کند؟»

بلکه باید بپرسی:

«این سرور از نظر شبکه‌ای به چه منابعی دسترسی دارد؟»


۵. SSRF و اعتماد اشتباه به URL

یکی از اشتباهات رایج این است که برنامه فقط URL را از نظر ظاهری بررسی کند.

مثلاً:

https://trusted.example/resource

ممکن است ظاهراً معتبر باشد.

اما امنیت واقعی باید درباره مقصد نهایی درخواست تصمیم بگیرد.

مواردی که در طراحی باید مورد توجه قرار بگیرند:

  • Scheme
  • Host
  • Port
  • DNS resolution
  • Redirect
  • IP address
  • IPv4 / IPv6
  • Proxy behavior
  • Network segmentation

۶. SSRF و Redirect

یک نکته مهم:

حتی اگر URL اولیه مجاز باشد، ممکن است سرور بعداً آن را دنبال کند.

مثلاً:

Allowed URL
     ↓
HTTP Redirect
     ↓
Different Destination

بنابراین اگر برنامه Redirect را دنبال می‌کند، سیاست امنیتی باید مقصد نهایی را نیز در نظر بگیرد.

URL اولیه مجاز ≠ مقصد نهایی مجاز


۷. SSRF در برابر CSRF

این دو نام شبیه‌اند اما مفهوم متفاوتی دارند.

CSRF

مهاجم تلاش می‌کند مرورگر قربانی عملیاتی را در یک برنامه انجام دهد.

Attacker → Victim Browser → Target

SSRF

مهاجم تلاش می‌کند سرور برنامه را وادار کند درخواست ایجاد کند.

Attacker → Web Server → Destination

پس:

CSRF = سوءاستفاده از اعتماد سرور به مرورگر

SSRF = سوءاستفاده از اعتماد شبکه/سرور به مقصد


۸. شناسایی نقاط احتمالی SSRF

در Recon فقط دنبال Endpointهایی با نام ssrf نگرد.

به قابلیت‌هایی توجه کن که URL یا مقصد شبکه دریافت می‌کنند.

مثلاً:

url=
uri=
link=
target=
callback=
webhook=
image=
source=
redirect=
fetch=
proxy=

همچنین قابلیت‌هایی مانند:

  • Import از URL
  • دریافت تصویر از URL
  • Webhook
  • Link Preview
  • PDF/Document Fetcher
  • URL Validator
  • External API Integration

ممکن است نیازمند بررسی باشند.

البته وجود چنین پارامتری به‌تنهایی به معنی SSRF نیست.


۹. سناریوی عملی امن — Zero SSRF Lab

برای اینکه این مفهوم را بدون هدف گرفتن هیچ سیستم واقعی یاد بگیریم، یک آزمایشگاه کوچک محلی می‌سازیم.

معماری:

┌─────────────────────┐
│ Browser              │
└──────────┬──────────┘
           │
           ▼
┌─────────────────────┐
│ SSRF Demo App       │
│ localhost:8000      │
└──────────┬──────────┘
           │
           ▼
┌─────────────────────┐
│ Internal Test Server │
│ localhost:9000      │
└─────────────────────┘

هر دو سرویس متعلق به خودت هستند.

هدف فقط این است که ببینیم آیا برنامه می‌تواند به یک سرویس داخلی آزمایشگاهی درخواست ارسال کند یا خیر.


۱۰. ساخت سرویس داخلی آزمایشگاه

در یک ترمینال، یک سرویس HTTP ساده و بی‌خطر اجرا کن:

python -m http.server 9000 --bind 127.0.0.1

اکنون یک HTTP Server روی:

127.0.0.1:9000

در حال اجراست.

این سرویس فقط برای آزمایشگاه توست.


۱۱. ساخت سناریوی Fetch

فرض کن برنامه آزمایشگاهی یک Endpoint مفهومی دارد:

GET /fetch?url=<URL>

و وظیفه آن این است که URL دریافت‌شده را از طرف سرور درخواست کند.

برای یک مقصد عمومی آزمایشگاهی یا سرویس خودت، رفتار عادی را بررسی کن.

در Burp Suite درخواست را مشاهده کن:

GET /fetch?url=http://127.0.0.1:9000/

اگر برنامه آسیب‌پذیر باشد، سرور ممکن است بتواند سرویس داخلی آزمایشگاهی خودت را درخواست کند.

این تست فقط روی سرویس‌هایی انجام می‌شود که خودت ساخته‌ای.


۱۲. چه چیزی را باید مشاهده کنیم؟

هدف ما اجرای کد یا دسترسی به اطلاعات حساس نیست.

فقط این موارد را بررسی کن:

سؤال اول

آیا سرور درخواست را ارسال می‌کند؟

سؤال دوم

آیا پاسخ سرویس داخلی به برنامه برمی‌گردد؟

سؤال سوم

آیا برنامه مقصد را محدود می‌کند؟

سؤال چهارم

آیا Redirect دنبال می‌شود؟

سؤال پنجم

آیا خطاهای شبکه اطلاعات داخلی را افشا می‌کنند؟

نتیجه را در Recon Notebook ثبت کن.


۱۳. سناریوی امن دوم؛ مقایسه دسترسی

حالا دو سرویس محلی داشته باش:

127.0.0.1:9000
127.0.0.1:9001

یکی را به‌عنوان مقصد مجاز و دیگری را به‌عنوان مقصدی که سیاست برنامه باید رد کند تعریف کن.

برای هر درخواست این موارد را ثبت کن:

مقصد انتظار نتیجه
سرویس مجاز آزمایشگاه Allow ؟
سرویس غیرمجاز آزمایشگاه Deny ؟
URL خارجی مجاز Allow ؟
Redirect به مقصد غیرمجاز Deny ؟

این جدول کمک می‌کند به جای تست تصادفی، سیاست دسترسی شبکه را بررسی کنی.


۱۴. چیزی که Pentester باید به آن توجه کند

فرض کن برنامه می‌گوید:

فقط URLهای HTTPS مجاز هستند.

این قانون به‌تنهایی کافی نیست.

یک Pentester باید بپرسد:

  • آیا فقط Scheme بررسی شده؟
  • Host چگونه اعتبارسنجی می‌شود؟
  • DNS چگونه Resolve می‌شود؟
  • آیا Redirect دنبال می‌شود؟
  • آیا مقصد نهایی دوباره بررسی می‌شود؟
  • آیا IPv6 نیز مدیریت شده؟
  • آیا Port محدود شده؟
  • آیا Proxy مسیر درخواست را تغییر می‌دهد؟

این دقیقاً همان تفاوت بین اسکنر بودن و تحلیل‌گر امنیتی بودن است.


۱۵. راهکارهای دفاعی SSRF

۱. Allowlist

اگر امکان دارد، مقصدهای مجاز را به‌صورت Allowlist تعریف کن.

به‌جای:

هر URL به جز چند مورد ممنوع

ترجیحاً:

فقط مقصدهای مشخص و موردنیاز

را مجاز کن.

۲. محدود کردن Scheme

فقط Schemeهایی را اجازه بده که برنامه واقعاً نیاز دارد.

مثلاً اگر برنامه فقط HTTPS نیاز دارد، سایر Schemeها را غیرضروری باز نگذار.

۳. کنترل مقصد نهایی

در صورت وجود Redirect، مقصد نهایی نیز باید مجدداً با سیاست امنیتی بررسی شود.

۴. جلوگیری از دسترسی غیرضروری شبکه

حتی اگر برنامه اشتباه کند، معماری شبکه باید اثر آن را محدود کند.

Web Server نباید بدون دلیل به تمام سرویس‌های داخلی دسترسی داشته باشد.

۵. محدود کردن DNS و IP

حل نام دامنه و بررسی مقصد باید بخشی از سیاست امنیتی باشد.

۶. Network Segmentation

سرویس‌های حساس را در شبکه‌های جداگانه قرار بده و دسترسی بین آن‌ها را حداقل کن.

۷. لاگ و Monitoring

درخواست‌های خروجی غیرعادی را ثبت و پایش کن.


۱۶. چالش قسمت دوازدهم

یک آزمایشگاه محلی SSRF بساز و یک نقشه معماری رسم کن:

Client
  ↓
Web Application
  ↓
URL Fetcher
  ↓
Network
  ↓
Internal Test Service

سپس برای هر مرحله مشخص کن:

  1. ورودی کجاست؟
  2. اعتبارسنجی کجا انجام می‌شود؟
  3. مقصد چگونه انتخاب می‌شود؟
  4. Redirect چگونه مدیریت می‌شود؟
  5. دسترسی شبکه‌ای سرور چیست؟
  6. چه کنترل‌هایی باید وجود داشته باشد؟
  7. اگر کنترل حذف شود، چه ریسکی ایجاد می‌شود؟

در پایان یک گزارش یک‌صفحه‌ای بنویس.


۱۷. چک‌لیست Pentester

  • قابلیت‌های دریافت URL را شناسایی می‌کنم.

  • می‌دانم درخواست Server-Side با درخواست مرورگر متفاوت است.

  • مقصد نهایی را بررسی می‌کنم، نه فقط URL اولیه را.

  • Redirect را در تحلیل لحاظ می‌کنم.

  • Scheme و Port را در نظر می‌گیرم.

  • DNS Resolution را جزئی از تحلیل می‌دانم.

  • معماری شبکه را بررسی می‌کنم.

  • دسترسی سرور به شبکه داخلی را ارزیابی می‌کنم.

  • نتیجه را فقط با شواهد قابل تکرار گزارش می‌کنم.


جمع‌بندی

SSRF یک درس مهم درباره اعتماد است.

گاهی برنامه به کاربر اعتماد می‌کند که مقصد درخواست را درست انتخاب کند؛ در حالی که سرور ممکن است دسترسی‌هایی داشته باشد که کاربر مستقیم ندارد.

یک Pentester حرفه‌ای فقط نمی‌پرسد:

«آیا سرور درخواست می‌فرستد؟»

بلکه می‌پرسد:

«سرور به کجا می‌تواند درخواست بفرستد و چه چیزی بعد از آن در معرض خطر قرار می‌گیرد؟»

در این قسمت یاد گرفتیم که SSRF را باید از سه زاویه بررسی کرد:

Application → Network → Destination

و بهترین دفاع نیز ترکیبی از اعتبارسنجی مقصد، Allowlist، کنترل Redirect، محدودسازی شبکه و معماری امن است.


قسمت بعدی

قسمت ۱۳ — Security Misconfiguration

وقتی یک برنامه از نظر کدنویسی نسبتاً امن است، اما یک تنظیم اشتباه می‌تواند کل زنجیره امنیتی را تضعیف کند.

از Headerهای امنیتی و خطاهای افشاگر گرفته تا سرویس‌های غیرضروری و تنظیمات اشتباه محیط Production.

صفر و یک سایبر | آموزش امنیت سایبری و هک قانونمند

دسته بندی‌ها:

دیدگاه شما

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *