Теперь небольшой пример из практики: Представим что ваш компьютер пингует мальчик Вася с компутера А (с IP-адресом 192.168.0.21), то запустив сниффер на вашей машине получите примерно следующую картину: Как видите адрес отправителя и получателя вам видны, и протокол обмена не нарушен. Удаленный компьютер послал запрос, и получил ответ, в результате мальчик Вася убедился, что ваш компьютер в сети и отвечает на ICMP запросы. Сделаю небольшой акцент на размере пакета - 74 байта. Исходя из этого можно судить что мальчик Вася под виндой, так как например ping запущенный с FreeBSD будет слать по 98 байт. И еще замечу, что ответ будет содержать также 98 байт, даже если с FreeBSD пингуют WinXp машину. Эти акценты я не зря здесь расставил, позже мы к этому факту еще вернемся. А пока возвращаемся к мальчику Васе. Представьте себе если бы запрос приходил от мальчика Васи (на самом деле), а ответ отправлялся мальчику Пете, или вообще неизвестно куда? Думаете такое невозможно? Давайте в качестве примера такой ужасной атаки рассмотрим работу флудера от команды CyberLords (см. аттач к статье). Итак, мальчик Вася запускает его на наш бедный маленький компьютер, под управлением Windows XP SP2. Вася вводит в своей FreeBSD заветные строчки команды: [root@vasya]# perl cl_flooder.txt -i192.168.18.1 -n 50 -t 1 И….. Но Вася не знает что мы включили логгирование на нашем маленьком и кривоватом фаерволе, и видим его жестокие попытки нас завалить открытыми соединениями: #Version: 1.5 #Software: Microsoft Windows Firewall #Time Format: Local #Fields: date time action protocol src-ip dst-ip src-port dst-port size tcpflags tcpsyn tcpack tcpwin icmptype icmpcode info path 2006-03-24 20:26:20 DROP TCP 78.63.228.55 192.168.18.1 65215 3312 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:20 DROP TCP 124.180.5.243 192.168.18.1 14253 28382 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:20 DROP TCP 186.166.83.23 192.168.18.1 5781 55993 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:20 DROP TCP 102.31.17.5 192.168.18.1 14278 14159 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:20 DROP TCP 11.98.55.58 192.168.18.1 26363 28340 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:20 DROP TCP 33.37.169.107 192.168.18.1 49215 10299 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:20 DROP TCP 204.132.94.88 192.168.18.1 27113 13657 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:20 DROP TCP 203.13.172.109 192.168.18.1 31545 5255 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:20 DROP TCP 244.141.83.29 192.168.18.1 53252 56631 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:20 DROP TCP 93.186.117.82 192.168.18.1 15382 4503 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:20 DROP TCP 123.55.71.123 192.168.18.1 12178 61434 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:20 DROP TCP 12.153.85.79 192.168.18.1 54151 184 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:53 DROP TCP 216.102.118.75 192.168.18.1 43072 52427 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:53 DROP TCP 167.52.113.157 192.168.18.1 39581 7435 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:53 DROP TCP 197.219.56.124 192.168.18.1 3623 8465 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:53 DROP TCP 244.53.153.142 192.168.18.1 61792 53492 40 S 0 0 65535 - - - RECEIVE 2006-03-24 20:26:53 DROP TCP 29.67.43.18 192.168.18.1 47416 6889 40 S 0 0 65535 - - - RECEIVE Наш скромный фаэрволл отрезал негодяя. Но посмотрите, что он пишет в поле src-ip (то есть откуда идет запрос)??? Какая-то абракадабра! Хотя запросы поступают все от того же пресловутого Васи, IP-адрес каждый раз разный, и даже близко не похожий на Васин. Вся шутка заключается в том, что в данном скрипте используется ручная сборка пакета IP, хотя и значительно облегченная за счет модуля Net::RawIP (этот модуль существует только для Nix'ов). Что мы видим в коде: ##########SEND PACKET######### $a = new Net::RawIP; $opt_s=int(rand(255)).".".int(rand(255)).".".int(rand(255)).".".int(rand(255)); #$flag=@flags[int(rand(@flags))]; $a->set({ ip => {saddr => $opt_s, daddr => $opt_i }, tcp => {dest => int(rand(65536)), source => int(rand(65536)), urg => 0, fin => 0, syn => 1, psh => 0} }); $a->send; Адрес отправителя генерится рандомно… А теперь вернеся к нашему примеру с пингом. Представим себе такую же ситуацию. Компьютер Васи отправляет запрос (размером 74 байта), и получает ответ - такой же пакет размером 74 байта. Трафик в обеих направлениях одинаковый. А теперь представьте что заместо своего IP-адреса Вася подставил адрес мальчика Пети, и запрос хоть и исходит от Васи, ответ приходит к Пете. Теперь все это помножим на кол-во компьютеров затрояненных Васей, и представим что все ответы на запросы приходят к Пете… Не позавидуешь Пете… Но тут всего лишь 74 байта, или чуть больше (98 байт) не в этом суть. Суть в равной порции трафика, от клиента и к нему. Чем же примечателен протокол DNS? Протокол DNS примечателен именно тем что работает на ненадежном протоколе UDP. Что упрощает процесс отправления запроса (минуя так называемый TCP хэндшейк). И помимо этого этот протокол интересен тем, что запрос к серверу может содержать около 60 байт информации, а ответ от него - 512 байт (это максимум, и это касается спецификации RFC 1035, которая касается IPv4, протокол IPv6 имеет значительно больший объем пакета), в этом и суть усиливающего эффекта протокола DNS.
Усиливающий эффект. Посмотрите небольшой рисунок, на котором запечатлен процесс запроса через nslookup домена Slashdot.org: Как видите небольшие пакеты с запросом к DNS серверу, генерят значительно большие по размеру пакеты ответов к клиенту (на рисунке IP: 192.168.0.21 - клиент, IP: 192.168.0.101 - сервер DNS). В последнем запросе - пакет размером 72 байта, порождает ответ сервера размером 277 байт, коэффициент усиления 277/72=3,84. И это далеко не предел, как я сказал, если минимальный запрос к серверу может составлять где-то 60 байт, а ответ 512, то коэффициент усиления составит 8,5, а по спецификации IPv6, где ответ сервера может содержать до 4000 байт: коэффициент усиления = 67!. В общем - масштаб катастрофы увеличивается, если принять во внимание то, что все DNS сервера (в основном конечно) сидят на широких каналах. Но вернемся к нашему IPv4 и коэффициенту 8,5. Идея, я думаю, уже прояснилась до понимания, и пора перейти к реализации. А как оно на практике делается? Итак, задача - сформировать запрос к DNS службе, и отправить его с целевым IP адресом (под целевым понимается IP адрес жертвы, которую мы решили атаковать). Также мы должны знать Named сервер (DNS) к которому адресовать наш запрос, ну и естественно мы должны представлять какой запрос мы будем делать. Для всего этого нам понадобиться perl и модуль Win32::NetPacket, а также установленный winpcap, или же все это можно написать на С, что естественно значительно более жизнеспособно в WIN32 среде.