Масштабное сканирование за две минуты!

Пишем сканер дырявых сервисов

Дмитрий Докучаев aka Forb

Xakep, номер #055, стр. 055-056-2


$ipk = $k;

if ($n4 ne '*') { $k = 254,$ipi = $n2 } ## Повторяем все для последней части

my($ipaddr) = "$n1\.$ipi\.$ipj\.$ipk"; ## Формируем полноценный ip-

адрес

chomp($ipaddr);

push(@ipz, $ipaddr); ## И заносим его в массив-базу

}

}

}

}

XXXXXXXXXXXXXXXXXXXXXXXXX

Как видно, процедура довольно большая. Она позволяет создавать огромные базы ip-адресов (вроде таких - XXX.*.*.*). Это нам только на руку, так как изначальная моя задумка сводилась к написанию сканера для обработки больших подсетей.

ХХХ ЗАГОЛОВОК ХХХ

Создание сокетов - проще не бывает

Я полагаю, ты уже умеешь создавать соединение, а также считывать с него данные (на эту тему было написано множество статей в Х). В противном случае - читай старые номера Хакера.

Как сказано выше, наша задача - прочитать баннер сервиса и сравнить его с шаблоном. Бинарных данных у нас не наблюдается, поэтому при работе будем использовать простой оператор "<>" для чтения сокета.

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Таблица 2: Тонкая работа с сокетами

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

while (<$socket>) { ## в $socket хранится идентификатор уникального соединения

chomp(); ## Обрезаем конец строки

$yes=$_ if ($_ =~/$routine/); ## В $routine - шаблон для проверки

баннера. Если баннер удовлетворяет шаблону - устанавливаем значение переменной

$yes равное приветствию

close ($socket); ## И закрываем сокет, чтобы корректно выйти из цикла

}

}

$yes=0 if ($yes=~/INET\=GLOB/); ## Игнорируем пустой указатель

return $yes; ## Возвращаем значение процедуры

exit unless ($socket); ## Выходим из процедуры, если создание сокета было неудачным

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Перед тобой не что иное, как фрагмент процедуры connectIP. На первый взгляд он содержит в себе несколько непонятных вещей. В них ты разберешься по ходу дальнейшего описания сканера.

Термин "Пустой указатель" означает поинтер на несуществующую строку. Он имеет формат INET=GLOB(ADDR) и формируется в том случае, если удаленный сервер не захотел показывать баннер (фильтрация фаерволом, неправильная работа сервиса и т.п.). Чтобы не засорять логи ненужными данными - просто исключим этот указатель.

ХХХ ЗАГОЛОВОК ХХХ

Ускоряемся по полной программе

Как ты понимаешь, последовательная обработка нескольких тысяч ip-адресов займет у тебя до фига времени. В голову лезет резонный вопрос - ну и зачем мне тогда такой медленный сканер? Спокойно! На помощь придут широкие возможности Perl, а именно создание новых процессов. Если ты не в курсе, Perl позволяет создавать несколько параллельных процессов, которые будут выполнять схожие задачи. Функция порождения нового процесса имеет название fork(), что переводится как "вилка". Если ты знаком с си, то знаешь, что функция "форк" присутствует и там (кто у кого содрал название - остается тайной и по сей день, если учитывать, что сам перл появился гораздо позже).

Использовать функцию fork() будем у себя в цикле. Новые процессы будут порождаться до тех пор, пока в массиве есть элементы ip-адресов. И ошибки тут недопустимы вообще. Порождение потомков в цикле аналогично ядерной реакции - если вовремя не убить процессы, то произойдет переполнение таблицы процессов, огромная утечка памяти, и, в конце концов, сервер накроется медным тазом :). У меня, например, при написании сканера пострадало два сервера (и все из-за неправильного завершения процессов), поэтому мой тебе совет на будущее - тестируй все многопроцессные проекты на локальной машине, иначе потом получишь по башке от админов.

Назад на стр. 055-056-1  Содержание  Вперед на стр. 055-056-3