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

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

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

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


Начнем с главного - с порождения нового процесса. Эту процедуру принято выполнять в условии, чтобы разграничить действия родителя и потомка. Для нас важно запомнить PID (Process ID) в родителе и выполнить процедуру создания сокета в потомке. Эту операцию нужно совершить N раз (число N задается в начальных параметрах сканера). Затем идет перезаполнение массива ip-адресов (количество элементов которого равно N) и все повторяется заново. Таким образом, мы получаем ряд независимых процессов, протекающих почти одновременно, тем самым ускоряя работу сканера в N раз.

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Таблица 3: Аккуратное порождение подпроцессов

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

while(1) { ## Заводим бесконечный цикл

@ips=@ipz[$once..$once+$pids]; ## Перезаполняем массив @ips, делая его равным

определенному срезу массива ip-адресов (количество элементов = $pids)

for ($i=0; $i<=$pids; $i++) { ## Создаем цикл for для каждого подпроцесса

unless($ips[$i]) { ## Если элемента не существует, то сканирование должно быть завершено

killpidz(); ## Переходим к убийству ВСЕХ порожденных ранее процессов

exit print "Scan is complete\n"; ## И лишь затем корректно выходим из программы

}

if ($pid=fork()) { ## Создаем новый процесс

push(@forked, $pid); ## В теле родителя заполняем массив идентификаторов

} else {

$res=connectIP($ips[$i]); ## В теле потомка создаем сокет

logg($ips[$i],$res) if ($res ne 0); ## Логируем результат, если возврат отличен от нуля

exit; ## Завершаем потомок! (очень важно)

}

}

$once+=$pids; ## Увеличиваем начальное значение элементов на $pids раз

killpidz(); ## Убиваем все потомки, чтобы не допустить переполнения

}

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Этот важный фрагмент кода показывает гибкую работу Perl с процессами. Что мы имеем? Во-первых, массив @forked, который содержит идентификаторы порожденных процессов. Во-вторых, $pids независимых процессов, выполняющих свое черное дело - чтение баннера с сокета. На этот момент для нас важны две задачи:

1. Не допустить переполнения процессов, поддерживая _постоянное_ число рабочих потомков.

2. Дожидаться корректного завершения потомка, не убивая его раньше времени.

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

Я тебя породил, я тебя и убью!

Удовлетворить наши запросы поможет следующая, не менее важная процедура killpidz(), в которой происходит убийство всех процессов, хранящихся в массиве @forked.

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Таблица 4: Убийство процессов

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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