Як приховати порт від сканування

У статті розглядається питання приховування портів, що використовуються якими-небудь програмами або демонами. Мається на увазі протокол tcp, хоча деякі викладки можна застосувати і до udp (навіть ще й простіше). В принципі, приховування трояна і робота з ним може здійснюватися і через icmp, але метою даної статті було розгляд приховування саме портів.

Припустимо, ми поставили на хост-жертву руткіт — начебто все круто, система затроянена, і, перебуваючи на цій машині, ми вже важко зможемо виявити цього трояна, а якщо ще й сам кернел затроєний, то це досить не тривіальне завдання. Але адмін додумався просканувати цю машину з інших хостів та визначити, що відкритий порт, який раніше не використовувався на цій машині. Упевнившись щодо того, що даний порт не повинен бути тут відкритий, він проводить аналіз системи і виявляє ваш руткіт, патчить систему і все більше у вас цього шла немає.

Тепер розглянемо, як можна обдурити сканер, щоб нас не можна було виявити. Як відомо установка з'єднання відбувається в 3 етапи - це так зване three-way hand shake (rfc793).

Для початку розглянемо стандартне встановлення з'єднання. На першому етапі ми отримуємо запит на з'єднання у формі SYN.

Далі ми надсилаємо свій запит на з'єднання та підтверджуємо прийом послідовності – SYN, ACK. І нарешті ми отримуємо підтвердження прийому нашої послідовності.

Таким чином, з'єднання успішно встановлено.

Тепер подивимося, що відбувається у разі відмови сервера від з'єднання (тобто якщо, наприклад, у нас порт не відкритий).

Ми отримали запит на з'єднання SYN.

Т.к. порт не слухається, то ядро ​​відповідає відповіддю – RST, ACK. Тобто. з'єднання невстановлено — у загальному випадку це означає, що порт не слухається, або там встановлений та грамотно налаштований міжмережевий екран.

Для покращення системи захисту нашого порту можна додати ще й аутентифікацію (перевірка користувача на відповідність). Тобто, припустимо, з'єднання здійснюється лише за умови, що рядок ідентифікований. Для автентифікації клієнта можна використовувати криптографію з відкритим ключем. У клієнта є секретний ключ, яким він зашифровує рядок для ідентифікації та деяку випадкову послідовність. рядок, що вийшов, відправляємо серверу разом з випадковою послідовністю. На стороні сервера знаходиться публічний ключ (ну не будемо ми в тилу ворога залишати секретний ключ) яким відбувається розшифрування рядка, який потім розбивається для перевірки з внутрішньою рядком і отриманою випадковою послідовністю. Таким чином, ми знижуємо ймовірність виявлення нашого трояна — навіть якщо з'явиться спеціалізований сканер (хоча за умови застосування криптографії це зробити важко) нашого руткіту, та й у трафіку не буде видно реального рядка для ідентифікації. В принципі, можна взагалі весь трафік між клієнтом та сервером шифрувати.

Отже, за відповідного рівня «невидимості» нашого руткіту на хосте-жертві (приховування процесів, відкритих портів тощо) — шляхом приховування порту ми можемо підвищити його прозорість і для стороннього погляду ззовні — отримуємо практично довічний йшов (поки кому-нитка) не заманеться переставити систему), або нас не видасть якийсь IDS, який виявив підозрілий трафік на невідомий порт з умовою того, що він ще й закритий.