Сканирование нескольких портов с использованием внешнего инструмента, подпроцесса. Открытие и потоки - PullRequest
1 голос
/ 16 декабря 2010

Я использую сканер портов для сканирования своей подсети.К сожалению, сканер портов может одновременно сканировать только один порт одного хоста.Также у сканера есть тайм-аут на 1 секунду для недоступных хостов.Сканер (будучи сторонней программой) должен запускаться из subprocess.Popen () и ускорять его, чтобы я мог отправлять несколько проб, пока некоторые предыдущие ожидают ответов - я использую потоки.Проблема возникает для полного сканирования / 24 подсети с большим количеством потоков.Некоторые из фактически открытых портов отображаются как закрытые.Я подозреваю, что выходной сигнал искажается.Обратите внимание, что этого не происходит, если я сканирую меньше хостов или одного хоста одновременно

Следующий код - моя попытка создать пул потоков, которые берут IP-адрес и запускают «последовательное» сканирование портов для определенного порта.,Как только все указанные порты проверены, он выбирает следующий IP из списка.

        while True:
            if not thread_queue.empty():
                try:
                    hst = ip_iter.next()
                except StopIteration:
                    break
                m=thread_queue.get()
                l=ThreadWork(self,hst,m)
                l.start()
        while open_threads != 0:
            pass      

Там, где этот фрагмент устанавливает очередь потоков

        thread_list = [x for x in range(num_threads)]
        for t in thread_list:
            thread_queue.put(str(t))
        ip_iter=iter(self.final_target)

В функции ThreadWork я сохраняю вкладку открытых потоков (поскольку thread_queue.empty оказался ненадежным, мне пришлось использоватьэто грубый способ)

class ThreadWork(threading.Thread):
    def __init__(self,i,hst,thread_no):
        global open_threads
        threading.Thread.__init__(self)
        self.host = hst
        self.ptr = i
        self.t = thread_no
        lock.acquire()
        open_threads = open_threads + 1
        lock.release() 

    def run(self):
        global thread_queue
        global open_threads
        global lock
        user_log.info("Executing sinfp for IP Address : %s"%self.host)
        self.ptr.result.append(SinFpRes(self.host,self.ptr.init_ports,self.ptr.all_ports,self.ptr.options,self.ptr.cf))
        lock.acquire()
        open_threads = open_threads - 1
        lock.release()
        thread_queue.put(self.t)

Вызов SinFpRes создает объект результата для одного IP и инициирует последовательное сканирование портов только для этого IP.Фактическое сканирование для каждого порта выглядит следующим образом:

        com_string = '/usr/local/sinfp/bin/sinfp.pl '+self.options+' -ai '+str(self.ip)+' -p '+str(p)
        args = shlex.split(com_string) 
        self.result=subprocess.Popen(args,stdout=subprocess.PIPE).communicate()[0]
        self.parse(p)

Функция анализа затем использует результат, сохраненный в self.result, для сохранения вывода для этого PORT.Совокупность всех портов - это то, что составляет результат сканирования для IP.

Вызов этого кода с использованием 10 потоков дает точное значение o / p (по сравнению с выводом nmap).При предоставлении 15 потоков случайный открытый порт пропущен.При предоставлении 20 потоков, больше открытых портов пропускаются.При выдаче 50 потоков многие порты пропускаются.

PS - в качестве первого таймера этот код очень запутан.Приносим извинения пуританам.

PPS - Даже сканирование многопоточных портов занимает 15 минут для всей подсети класса C с почти 20 отсканированными портами.Мне было интересно, если я должен переместить этот код на другой язык и использовать Python только для анализа результатов.Может ли кто-нибудь предложить мне язык?Примечание. Я изучаю опцию Shell, как показано в S.Lott, но перед выгрузкой в ​​файл требуется ручная обработка.

Ответы [ 3 ]

1 голос
/ 17 декабря 2010

Использовать оболочку

 for h in host1 host2 host3
 do
     scan $h >$h.scan &
 done
 cat *.scan >all.scan

Это позволит одновременно сканировать весь список хостов, каждый в отдельном процессе.Нет потоков.

При каждом сканировании будет получен файл .scan.Затем вы можете объединить все файлы .scan в массивный файл all.scan для дальнейшей обработки или чего бы вы ни делали.

1 голос
/ 16 декабря 2010

Почему бы вам не попробовать?

(Ответ: нет, у них будет своя труба)

0 голосов
/ 21 декабря 2010

Используйте Perl вместо Python.Программа (SinFP) написана на Perl, вы можете изменить код в соответствии с вашими потребностями.

...