Техника сокрытия портов от сетевых сканеров
В статье рассматривается вопрос сокрытия портов используемых
какими-либо программами или демонами. Подразумевается протокол tcp,
хотя некоторые выкладки применимы и к udp (даже еще и проще). В
принципе, сокрытие трояна и работа с ним может также осуществляться
и через icmp, но целью данной статьи было рассмотрение сокрытия
именно портов.
Предположим, мы поставили на хост-жертву руткит - вроде все
круто, система затроянена, и, находясь на данной машине, мы уже с
трудом сможем обнаружить этого трояна, а если еще и сам кернел
затроянен, то это достаточно не тривиальная задача. Но админ
додумался просканировать данную машину с других хостов и определить,
что открыт порт, который ранее не использовался на данной машине.
Удостоверившись в отношении того, что данный порт не должен быть
здесь открыт, - он проводит анализ системы и обнаруживает ваш
руткит, патчит систему и все больше у вас этого шела нет.
Теперь рассмотрим, как нам можно обмануть сканер, чтобы нас
нельзя было обнаружить. Как известно установка соединения происходит
в 3 этапа - это так называемое "three-way hand
shake" (rfc793).
Для начала рассмотрим стандартную установку соединения.
На первом этапе мы получаем запрос на соединения в форме -
SYN.
Далее мы отправляем свой запрос на соединение и подтверждаем
прием последовательности - SYN, ACK.
И, наконец, мы получаем подтверждение приема нашей
последовательности.
Таким образом, соединение успешно установлено.
Теперь посмотрим, что происходит в случае отказа сервера от
соединения (т.е. если, например, у нас порт не открыт).
Мы получили запрос на соединение - SYN.
Т.к. порт не слушается, то ядро отвечает ответом -
RST, ACK.
Т.е. соединение не установлено - в общем случае это означает, что
порт не слушается, либо там установлен и грамотно настроен
межсетевой экран.
По спецификации TCP не оговаривается передача данных именно после
установления соединения, т.е. при желании можно подкрутить клиент и
сервер, чтоб первый отправлял данные в 1-ом SYN пакете, а второй
считал данные из этого SYN пакета. Т.е. таким образом, мы можем
произвести идентификацию (проверка доступности пользователю данного
ресурса) клиента. В случае если клиент не прошел идентификацию - не
верная строка или вообще данные отсутствуют, то сервер должен
послать ему RST. При таком раскладе, простой порт сканер не сможет
определить реально открытый порт, а специально подкрученный сканер
уязвимостей не сможет пройти идентификацию - что позволит нам
сохрани тмммь невид имость. Идентификация по адресу и порту не
рассматривается, в связи с возможностью компрометации - хотя бы тем
же самым spoofing'ом.
Для улучшения системы защиты нашего порта можно добавить еще и
аутентификацию (проверка пользователя на соответствие). Т.е.,
предположим, соединение осуществляется только при условии, что
строка идентифицирована. Для аутентификации клиента можно
использовать криптографию с открытым ключом. У клиента находится
секретный ключ, которым он зашифровывает строку для идентификации и
некоторую случайную последовательность. Получившуюся строку
отправляем серверу вместе со случайной последовательностью. На
стороне сервера находится публичный ключ (ну не будем же мы в тылу
врага оставлять секретный ключ) которым происходит расшифровка
строки, которая затем разбивается для проверки с внутренней строкой
и полученной случайной последовательностью. Таким образом, мы
снижаем вероятность обнаружения нашего трояна - даже если появится
специализированный сканер (хотя в при условии применения
криптографии это сделать затруднительно) нашего руткита, да и в
трафике не будет видно реальной строки для идентификации. В
принципе, можно вообще весь трафик между клиентом и сервером
шифровать.
Итак, при соответствующем уровне "невидимости" нашего руткита на
хосте-жертве (сокрытие процессов, открытых портов и т.п.) - путем
сокрытия порта мы можем повысить его прозрачность и для постороннего
взгляда извне - получаем практически пожизненный шел (пока кому-нить
не вздумается переставить систему), или нас не выдаст какой-нибудь
IDS, обнаруживший подозрительный трафик на неизвестный порт с
условием того что он еще и закрыт.