map.gif распределение интенсивности атак на различные порты по регионам
Но забросить shell-код на вражескую территорию это только половина дела. Как минимум еще требуется протащить через все межсетевые заслоны основное тело червя (то есть хвост), а как максимум – установить терминальный backdoor shell, предоставляющий атакующему возможность удаленного управления захваченной системой.
Может ли брандмаузер этому противостоять? Если он находится на одном узле с атакуемым сервером и shell-код исполняется с наивысшими привилегиями, то атакующий может делать с брандмауэров все, что ему только заблагорассудится, в том числе и изменять его конфигурацию на более демократическую. Это случай настолько прост, что его даже неинтересно рассматривать. Давайте лучше исходить из того, что брандмаузер и атакуемый сервис расположены на различных узлах, причем сам брандмаузер правильно сконфигурирован и лишен каких бы то ни было уязвимостей.
Самое простое (и самое естественное) – поручить shell-коду открыть на атакованном узле новый, заведомо никем не использованный порт (например, порт 666), и терпеливо ждать подключений с удаленного узла, осуществляющего засылку основного вирусного кода. Правда, если администратор системы не полный лох, все входящие соединения на все непубличные порты будут безжалостно отсекаться брандмауэром. Однако, атакующий может схитрить и перенести серверную часть червя на удаленный узел, ожидающий подключений со стороны shell-кода. Исходящие соединения блокируются далеко не на всех брандмауэрах, хотя в принципе такая возможность у администратора есть. Но грамотно спроектированный червь не может позволить себе закладываться на разгильдяйство и попустительство администраторов. Вместо установки нового TCP/IP-соединения он должен уметь пользоваться уже существующим – тем, через которое и была осуществлена засылка головы червя. В этом случае брандмаузер будет бессилен что-либо сделать, т. к. с его точки зрения все будет выглядеть вполне нормально. Откуда же ему, бедолаге, знать, что вполне безобидное с виду и легальным образом установленное TCP/IP соединение обрабатывает не отнюдь сервер, а непосредственно сам shell-код, поселившийся в адресном пространстве последнего.
Существует несколько путей захвата ранее установленного TCP/IP-соединения (если кто раньше читал мои статьи, датированные годом эдак 1998, то там я называл это "передачей данных в потоке уже существующего TCP/IP соединения", но этот термин не прижился). Первое и самое глупое – обратиться к переменной дескриптора сокета по фиксированным адресам, специфичным для данного сервера, которые атакующий может получить путем его дизассемблирования. Но такой способ не выдерживает никакой критики, здесь он не рассматривается (тем не менее, знать о его существовании будет все-таки полезно).
Уж лучше прибегнуть к грубой силе, перебирая все возможные дескрипторы сокетов один за другим и тем или иным образом определяя какой из них заведует "нашим" TCP/IP-соединением. Поскольку, в операционных системах семейства UNIX и Windows 9x/NT, дескрипторы сокетов представляют собой вполне упорядоченные и небольшие по величине целочисленные значения (обычно заключенные в интервале от 0 до 255), их перебор займет совсем немного времени. Как вариант, можно воспользоваться возможностью повторного использования адресов, сделав re-bind на открытый уязвимым сервером порт. Тогда, все последующие подключения к атакованному узлу, будут обрабатываться отнюдь не прежним владельцем порта, а непосредственно самим shell-кодом (неплохое средство перехвата секретного трафика, а?). Наконец, shell-код может просто "прибить" уязвимый процесс, и открыть публичный порт заново.
Как вариант – червь может умертвить атакуемый процесс, автоматически освобождая все отрытые им порты и дескрипторы. Тогда повторное открытие уязвимого порта не вызовет никаких протестов со стороны операционных системы. Менее агрессивный червь не будет ничего захватывать, никого убивать и вообще что либо трогать. Он просто переведет систему в неразборчивый режим, прослушивая весь проходящий трафик с которым атакующий должен передать оставшийся хвост.
И на закуску: если ICMP-протокол хотя бы частично разрешен (чтобы пользователи внешней сети не доставали администратора глупыми вопросами почему умирает ping), то shell-код может запросто обернуть свой хвост ICMP-пакетами! В самом крайнем случае, червь может послать свое тело и в обычном электронном письме (конечно, при условии, что он сможет зарегистрировать на почтовом сервере новый ящик или похитить пароли одного или нескольких пользователей, что при наличии snffer'а не является проблемой).
Таким образом, никакой, даже самый совершенный и правильно сконфигурированный брандмаузер, не защитит вашу сеть (и уж тем более – домашний компьютер) ни от червей, ни от опытных хакеров. Это, разумеется, не обозначает, что брандмаузер совершенно бесполезен, но убедительно доказывает тот факт, что приобретение брандмауэра еще не отменяет необходимость регулярной установки свежих заплаток.