یکی از چالشهایی که همه هکرها بعد از نفوذ به یک سیستم با آن مواجهاند این است که چگونه در دراز مدت کنترل خود را روی سیستم قربانی بهطور مخفی حفظ کنند. ابزارهای «دربپشتی» (backdoor) که منتظر اتصالهای خارجی هستند به وسیله پویش پورت یا فهرست کردن سوکتهای باز به راحتی شناسایی میشوند. ابزارهایی هم که به صورت دورهای به یک سرور خارجی اتصال برقرار میکنند، معمولا به تعداد آدرسهای کم یا الگوریتمهای تولید دامنه قابل پیشبینی، محدود میشوند. دربپشتی مورد بررسی در این مقاله با استفاده از یک روش جدید برای شناسایی بستههای ورودی خاص، از این مشکلات اجتناب میکند، دیوارههای آتش (firewall) معمولی میزبان را دور میزند و به هکر امکان تغییر آدرس IP بدون از دست دادن اتصال را میدهد.
مکانیزم عمل
دربپشتی مورد بحث، مولفههایی دارد که به نفوذگر امکاناتی از قبیل دسترسی روت به شل یا دسترسی از راه دور هر فایلی را میدهد. با این حال جالبترین ویژگی آن امکان به کار انداختن آن با بستههای magic TCP است که شامل ترکیب خاصی از مقادیر سرآمد (Header) است.
مجموعه این دربپشتی روی سرور:
- یک ماژول هسته که به بستههای مجیک گوش میدهد و user-mode helper را به کار میاندازد.
- user-mode helper که به سرور خارجی متصل شده شامل کدهای دسترسی به فایل یا شل از راه دور است.
- یک اسکریپت برای اطمینان از بارگذاری کامل هنگام بوت.
- مد کاربری باینری برای نگهداری عملیات.
مرور کلی
یک تعامل موفق با سیستم قربانی در زیر به تصویر کشیده شده است. برای به کار انداختن دربپشتی به سه بسته مجیک نیاز است تا اتصال سیستم به فرستنده بستههای مجیک برقرار شود. سه تک بسته پورت ناکینگ (knocking) برای به کار انداختن کافی است و نیازی به برقراری اتصال کامل TCP نیست.
دادههای منتقل شده بین هکر و قربانی در تمام مدت با RC4 رمزگذاری میشود. در نمونه مورد بررسی توسط گروه NCC، رشته ثابت یکسانی برای مقداردهی اولیه RC4، برای ارسال و دریافت استفاده شده بود. یعنی رمزنگاری اتصال نفوذگر هنگامی که کلید RC4 از سیستم قربانی دریافت شود، میسر میگردد. هر چند ممکن است کلید RC4 در هر بار قرار گرفتن دربپشتی روی یک سرور، متفاوت باشد.
به کار انداختن دربپشتی
سرآمدهای تمام بستههای دریافتی برای بررسی ترکیب خاصی از مقادیر در بستههای مجیک، تحلیل میشوند. اگر بخواهیم به طور مشخص بگوییم، راهانداز هسته (kernel driver)، پورت مبدا و شماره توالی را با یک مقدار ثابت مقایسه میکند. در حال حاضر برای دادن زمان بیشتر به فرینود برای ادامه تحقیقاتشان، این مقدار ثابت را فاش نمیکنیم. هنگامی که سه بسته TCP با ترکیب درست پورت مبدا و شماره توالی دریافت شد، مد کاربری باینری با آدرس IP مبدا (از بسته مجیک) و یک پورت مقصد فرا خوانده میشود. این شماره پورت از سایز پنجره در بسته سوم استخراج شده و منهای ۸۱۹۲ میشود.
نمای کلی سرآمد TCP در زیر نمایش داده شده است.
تداوم
روی سرور مورد بررسی توسط گروه NCC تداوم روت کیت با اضافه کردن اسکریپت lib/lsb/init-functions/ بهدست آمد. این فایل به وسیله هر لینوکس پایه استاندارد سازگار با اسکریپت اولیه، گنجانده شده و شماری از عملکردهای ضروری را فراهم میکند. این افزونهها مسئول اجرای اسکریپت شل نفوذگر هستند که در ادامه بیان میشود.
- اجزای اصلی
- راهانداز کرنل
نام ماژول کرنل اضافه شده بعد از بارگذاری، ipt_ip_udp است. این راهانداز هسته، از یک قلاب دیوارهآتش «نتفیلتر» برای بازرسی بستهها در سیستم قربانی استفاده میکند. این قلاب در زنجیره قبل از مسیریابی با بیشترین اولویت تنظیم میشود تا از فیلترینگ بسته در ورودی زنجیره اجتناب کند. این بدان معنی است که حتی اگر دستور یک دیواره آتش معمولی، متوقف کردن بسته مجیک باشد، این بسته از دید راهانداز هسته دربپشتی، پنهان نخواهد ماند.
پورتهای مقصد در راهانداز هسته بررسی نمیشوند، بنابرابن بستههای مجیک به هر پورتی میتوانند ارسال شوند. نیازی نیست سه بسته مجیک دقیقا یکی باشند، پورت مبدا و شماره توالی میتوانند تصادفی انتخاب شوند ولی مجموع آنها میبایست با مقدار مورد نظر یکی باشد. همین طور میتوان سه بسته را بسیار کند و با فاصله زمانی زیاد فرستاد. تلفیق این سه ویژگی باعث میشود پیادهسازی یک شناسه سیستم تشخیص نفوذ برای این نوع ترافیک بسیار مشکل شود.
در زیر یک کد نمونه نشان داده شده که از ابزار اسکپی (Scapy) برای پیشگیری از سیستم تشخیص نفوذ در آن استفاده شده است. دقت کنید که به دلیلی که قبلا بدان اشاره شد، مقدار مجیک ذکر نشده است.
#! /usr/bin/env python import random from scapy.all import IP,TCP,send import argparse ######## # Author: NCC Group, Cyber Defence Operations (CDO) # Date: September 2014 # # Sends three TCP packets with the correct header values to trigger # a connect back on the specified port. # # This script implements simple randomness for the "magic" header # values to demonstrate how difficult it would be to signature in IDS. ######## parser = argparse.ArgumentParser(description='Trigger the backdoor') parser.add_argument('TARGET_IP', metavar='TARGET_IP', type=str, help='IP to send magic packets to') args = parser.parse_args() # Target port can be any valid port. iptables filtering does not apply # if it's in the normal INPUT chain. This could be randomised per-packet. TARGET_PORT = 80 CALLBACK_PORT = 1234 for n in range(1, 4): # To trigger backdoor the source port + sequence must add up to # Backdoor will connect to us on window - 8192 source_port = random.randint(1024, 2048) sequence = - source_port # Value not disclosed at this time packet = IP(dst=args.TARGET_IP)/TCP(dport=TARGET_PORT,sport=source_port,seq=sequence,window=8192 + CALLBACK_PORT) print "[+] Sending magic packet {} of 3 to {}:{} (sport: {}, seq: {})".format(n, args.TARGET_IP, TARGET_PORT, source_port, sequence) send(packet)
هنگامی که سه بسته مجیک دریافت شد، ماژول هسته user-mode helper را به کار میاندازد.
user-mode helper
این باینری با ایجاد ارتباط با نفوذگر، دسترسی او را به سیستم فراهم میکند و عملکردهای دربپشتی با ویژگیهای زیر و دسترسی روت را برای او مهیا میکند:
- اجرای شل – ورودی و خروجی به سوکت شبکه
- خواندن فایل – خروجی به سوکت شبکه
- نوشتن فایل – ورودی از سوکت شبکه
این فایل در سیستم در آدرس bin/dh/ واقع شده است. این آدرس در ماژول هسته کد شده ولی به راحتی قابل تغییر است. هر چند این نام نمایش داده شده در فهرست فرآیندها را با بازنویسی مقدار [argv[0 به hald-runner تغییر میدهد.
هلپر یک ارتباط با آدرس نفوذگر برقرار میکند، چون اکثر دیوارهآتشها محدودیت زیادی برای ارتباط خارجی ندارند، این اتصال معمولا موفقیتآمیز خواهد بود. بعد از برقراری ارتباط، هلپر یک رمز را که با DES هَش شده، از نفوذگر دریافت و با مقدار از قبل تعیین شده مقایسه میکند. بعد از دریافت رمز درست، هلپر یک مقدار چهار بایتی را میفرستد که بیانگر موفقیت است. سپس نفوذگر چهار بایت مربوط به دستور مورد نظر را که مفیدترین آن، روت شل است، میفرستد. این شل با متغیرهای محیطی اجرا میشود که میزان ذخیره اطلاعات سوابق (log) را کاهش میدهد.
قوانین شناسایی
میتوان از قانون زیر در سیستمهای تشخیص نفوذی که از شناسههای قالب Snort پشتیبانی میکنند، استفاده کرد. با توجه به ساختار بستههای مجیک، ایجاد یک قانون پایه سیستم تشخیص نفوذ غیرممکن است، با این حال با اسکریپتهای Suricta یا Bro میتوان به آن دست پیدا کرد. قانون ارایه شده رشتههای ثابت ماژول هسته را بعد از رمزنگاری با RC4 بررسی میکند، که مربوط به بسته hello و بسته بعد ازاحراز هویت است.
alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg: "Unknown Linux Backdoor"; content: "|b5a46fce2166|"; depth: 6;flow:established, to_server; sid:1;)
با توجه به اینکه فقط شش بایت از یک جریان TCP بررسی میشوند، امکان نتیجهگیری اشتباه وجود دارد. قابل ذکر است که کد نمایش داده شده در بالا برای این مورد کاربرد داشته و تغییر جزییات رمزنگاری RC4، برای نفوذگران آسان خواهد بود. بنابراین ما استفاده از پویش مبتنی بر میزبان را توصیه میکنیم.
نتیجه
در حالی که مکانیزمهای دست دادن (handshake) و امنیت داده خوب طراحی شدهاند، مکانیزم تداوم به هیچ وجه پنهانی نبوده و این روتکیت به وسیله ابزارهایی مثل Tripwire و Rootkit Hunter قابل کشف است. در حالی که تکنیکهای به کار رفته به خوبی مهندسی شدهاند اما منحصربهفرد نیستند. به عنوان مثال قلابهای netfilter در مقاله «تجربههای روتکیت هسته» در سال ۲۰۰۳ مورد بررسی قرار گرفته بود. همین طور پورت ناکینگ و رمزنگاری RC4 برای پنهانکاری و ارتباط امن به عنوان رویکردهای توسعه روتکیت، چندان پیچیده نیستند.