Gidroponika
Exploit Developer
		- Joined
 - Aug 17, 2016
 
- Messages
 - 1,783
 
- Reaction score
 - 826
 
Начну с того, а зачем изобретать велосипед, если их уже куча написана? Все мы понимаем, что велосипеды разные - чёрные, белые, красные )))
Когда я посмотрел примеры многопоточных сканеров, то понял, что большая часть из них имеет диапазон типа for port in range(1,100): , значит перебор портов будет с 1 по 99. Если мне понадобится порт например 20000, то при попытке записи ]for port in range(1,20001): сканер загнётся от переполнения памяти и невозможности создания нового потока.
Сканеры же, имеющий подобранные порты типа [21, 22, 23, 25, 38, 43, и т.д. были однопоточными, и работали весьма медленно...
В итоге я решил собрать новый велосипед из старых запчастей. Я хотел следующее:
1) Простой короткий код
2) Многопоточность
3) Указания нужных портов
Погнали:
Подключаем модуль threading для работы с потоками. Подключаем модуль socket для работы с сокетами (интерфейс для обеспечения обмена данными между процессами)
	
	
	
		
Вводим хост для сканирования
	
	
	
		
Создаём функцию сканирования портов, в которой создаём сокет, и выставляем таймаут
	
	
	
		
Продолжаем функцию, добавляем в блоке обработки исключений попытку приконнектиться к хосту, и в случае соединения, пишем что порт открыт. Открытое соединение закрываем. Ставим оператор-заглушку pass, в случае отсутствия соединения, ничего не выполняем.
	
	
	
		
Пишем список портов (можете добавить любые по желанию).
	
	
	
		
Ну вот и подошли к самому главному и интересному.
Делаем следующую запись, в которой мы запускаем перебор в цикле портов, создаём и запускаем потоки.
	
	
	
		
Рассмотрим подробнее, что происходит в этом блоке
Для этого я пошагово запустил скрипт в Pycharm. Хост взял наобум из сети, поэтому я его закрасил. Смотрим внимательнее на скрин - когда у нас шаг прошёл создание потока, появилась надпись, в которой мы видим инициализацию нового потока. Значит всё работает как надо.
	
	
	
		
		
		
			
		
		
	
	
		
	
На следующем шаге поток запустился.
	
	
	
		
		
		
		
	
	
		
	
Если в потоке поставленная задача выполнена, то он останавливается
	
	
	
		
		
		
		
	
	
		
	
Результат работы программы наглядно показывает, что потоки закрываются не в том порядке, что открывались. То есть они действительно работают параллельно. На каждый порт запускается отдельный поток. В процессе сканирования, количество потоков разное, взависимости от количества уже отработанных потоков.
	
	
	
		
		
		
		
	
	
		
	
На моём стареньком компе 2010 года и модемной связи от сотового оператора, скрипт выполняется за мгновенье.
Получилось всё как было задумано.
	
	
	
		
		
		
		
	
	
		
	
Исходный код с подробными комментариями
	
	
	
		
			
			Когда я посмотрел примеры многопоточных сканеров, то понял, что большая часть из них имеет диапазон типа for port in range(1,100): , значит перебор портов будет с 1 по 99. Если мне понадобится порт например 20000, то при попытке записи ]for port in range(1,20001): сканер загнётся от переполнения памяти и невозможности создания нового потока.
Сканеры же, имеющий подобранные порты типа [21, 22, 23, 25, 38, 43, и т.д. были однопоточными, и работали весьма медленно...
В итоге я решил собрать новый велосипед из старых запчастей. Я хотел следующее:
1) Простой короткий код
2) Многопоточность
3) Указания нужных портов
Погнали:
Подключаем модуль threading для работы с потоками. Подключаем модуль socket для работы с сокетами (интерфейс для обеспечения обмена данными между процессами)
		Code:
	
	import threading
import socket
	Вводим хост для сканирования
		Code:
	
	print('-' * 35)
target = input('Enter host:\n\n')
print('-' * 35)
	
		Code:
	
	def portscan(port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(0.5)
	Продолжаем функцию, добавляем в блоке обработки исключений попытку приконнектиться к хосту, и в случае соединения, пишем что порт открыт. Открытое соединение закрываем. Ставим оператор-заглушку pass, в случае отсутствия соединения, ничего не выполняем.
		Code:
	
	try:
        connection = s.connect((target, port))
        print('Port :', port, "is open.")
        connection.close()   
    except:
        pass
	Пишем список портов (можете добавить любые по желанию).
		Code:
	
	ports = [21, 22, 23, 25, 38, 43, 80, 109, 110, 115, 118, 119, 143,  # Список портов
194, 220, 443, 540, 585, 591, 1112, 1433, 1443, 3128, 3197,
3306, 4000, 4333, 5100, 5432, 6669, 8000, 8080, 9014, 9200]
	Ну вот и подошли к самому главному и интересному.
Делаем следующую запись, в которой мы запускаем перебор в цикле портов, создаём и запускаем потоки.
		Code:
	
	for element in ports:
    t = threading.Thread(target=portscan, kwargs={'port': element})
    t.start()
input()
	Рассмотрим подробнее, что происходит в этом блоке
Для этого я пошагово запустил скрипт в Pycharm. Хост взял наобум из сети, поэтому я его закрасил. Смотрим внимательнее на скрин - когда у нас шаг прошёл создание потока, появилась надпись, в которой мы видим инициализацию нового потока. Значит всё работает как надо.
	На следующем шаге поток запустился.
	Если в потоке поставленная задача выполнена, то он останавливается
	Результат работы программы наглядно показывает, что потоки закрываются не в том порядке, что открывались. То есть они действительно работают параллельно. На каждый порт запускается отдельный поток. В процессе сканирования, количество потоков разное, взависимости от количества уже отработанных потоков.
	На моём стареньком компе 2010 года и модемной связи от сотового оператора, скрипт выполняется за мгновенье.
Получилось всё как было задумано.
	Исходный код с подробными комментариями
		Code:
	
	import threading  # Подключаем модуль threading для работы с потоками
import socket  # Подключаем модуль socket для работы с сокетами (интерфейс для обеспечения обмена данными между процессами)
print('-' * 35)
target = input('Enter host:\n\n')  # Ввод хоста для сканирования
print('-' * 35)
def portscan(port):  # Создаём функцию сканирования портов
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # Создаём сокет
    s.settimeout(0.5)   # Выставляем таймаут
    try:
        connection = s.connect((target, port))  # Пытаемся приконнектиться к хосту
        print('Port :', port, "is open.")   # В случае соединения, пишем что порт открыт
        connection.close()   # Закрываем соединение
    except:
        pass   # Оператор-заглушка, в случае отсутствия соединения, ничего не выполняем
ports = [21, 22, 23, 25, 38, 43, 80, 109, 110, 115, 118, 119, 143,  # Список портов
194, 220, 443, 540, 585, 591, 1112, 1433, 1443, 3128, 3197,
3306, 4000, 4333, 5100, 5432, 6669, 8000, 8080, 9014, 9200]
for element in ports:   # Перебор в цикле портов
    t = threading.Thread(target=portscan, kwargs={'port': element})  # Создаём поток
    t.start()   # Запуск потока
input()