Проблема с проброской 80 порта в прошивке от 21.05.2014

Дорогие пользователи! У нас появился новый форум на платформе tp-link.community (Сообщество)

Форум доступен по ссылке https://community.tp-link.com/ru
Просим Вас отнестись с пониманием к новому форуму, он находится в стадии доработки и в скором времени будет полностью завершен.

Если при регистрации в Сообществе Вы укажете адрес электронный почты, который используете на данном форуме, то Ваши данные будут перенесены на форум Сообщества автоматически.
Также, если на форуме Сообщества Ваш никнейм будет занят, то Вам предложат сменить его или оставить, но с приставкой “_RU”.

Подробнее Вы можете прочитать тут: https://community.tp-link.com/ru/home/f … pic/501542

Убедительная просьба не дублировать темы на старом/новом форуме.

schetilin

Сообщения: 2
Зарегистрирован: 28 июл 2014, 03:56
Страна: Украина

Проблема с проброской 80 порта в прошивке от 21. 2014

Аппаратная версия устройства: Ver.4
Версия прошивки: build 140521_RU
После обновления TL-WR741ND v4 прошивкой от 21.05.2014 не получается пробросить 80 порт.
“Код ошибки: 14007 Ошибка: Порт удалённого управления через веб-интерфейс конфликтует с портом виртуального сервера.”
Пришлось вернуться на прошивку от 18.06.2013


Ame

Модератор
Модератор
Сообщения: 686
Зарегистрирован: 07 апр 2014, 11:41
Страна: Москва

Re: Проблема с проброской 80 порта в прошивке от 21. 2014

Сообщение

Ame » 28 июл 2014, 12:05

Вы изменяли порт удаленного управления роутера с стандартного 80го? Скорее всего нет, тогда вам нужно зайти в настройки роутера, далее Безопасность, там удаленное управление. В этом разделе меняете 80й порт на 8080 например. После перезагружаете роутер и все заработает.


schetilin

Сообщения: 2
Зарегистрирован: 28 июл 2014, 03:56
Страна: Украина

Re: Проблема с проброской 80 порта в прошивке от 21. 2014

Сообщение

schetilin » 28 июл 2014, 18:31

Спасибо, попробую. Просто в предыдущей прошивке все работало без изменения порта web-интерфейса.


Rolis

Сообщения: 544
Зарегистрирован: 25 фев 2014, 20:02
Страна: Россия
Откуда: Moscow
Контактная информация:

Re: Проблема с проброской 80 порта в прошивке от 21. 2014

Сообщение

Rolis » 28 июл 2014, 23:48

schetilin писал(а):Спасибо, попробую. Просто в предыдущей прошивке все работало без изменения порта web-интерфейса.

Скорее всего потому, что удаленное управление роутером через 80-й порт не было разрешено.

TL-ER6120 | TL-ER6020 | TL-R600VPN | TL-ER604W | TL-WA5210G | TL-WA5110G | TL-WR941ND | TL-WR842ND | TL-WA750RE | TL-WA901ND | TL-MR3420 | TL-MR3020 | TL-SG3210 | TL-SG1024DE | TL-SL5428E | TL-SL3428 | TL-WA860RE | TL-WA855RE | Archer C2300 | TL-ER7206



Старый
05.06.2010, 20:53

 

#1
 

Участник

Аватар для propeller

Запись уже существует!?


Из одной компании выгрузил файл (dat) с клиентами. В другой компании пытаюсь загрузить, выдает ошибку:

Невозможно создать запись в Клиенты (CustTable). Счет клиента: АБРИКОС, ООО “АБРИКОС”.
Запись уже существует.

НО такого клиента нет в этой компании со счетом клиента “АБРИКОС”. Проверял всеми способами и в аксапте запросы писал, и фильтром, и на SQL посмотрел.

Такое ощущение что проблема в RecId, буд-то он его из файла грузит.
Запускал реиндексацию – не помогла

Как исправить эту ошибку?


Старый
05.06.2010, 21:14

 

#2
 

Участник

Аватар для Geo

Очевидный вопрос, но тем не менее: все варианты написания “АБРИКОС” проверили?


Старый
05.06.2010, 22:10

 

#3
 

Участник

 

Регистрация: 21.03.2005

Адрес: Москва-Петушки

Что если в параметрах загрузки установить флаг “Обновлять существующие записи” (или как он там называется в вашей версии – кстати, неплохо бы привести версию).
Ну и обычные шаманские пляски:

  • Может быть справочник клиентов включен в виртуальную компанию?
  • Перед загрузкой рестартовали AOS?
  • Чистили кэш?


Старый
05.06.2010, 22:54

 

#4
 

Участник

Аватар для propeller

АБРИКОС искал во всех вариантах. “абрикос” это условный пример. на самом деле там несколько записей, и на всех ошибка.
Таблица не в виртуальной компании, аос перестартовывал – не помогло.
Кэш, если имеется ввиду пользовательский – чистил.
версия – AX 2009 sp1.
причем база SQL обновленная с AX 4. в 4-ке такой прием работал, нормально загружалось.
Проверял по RecID в таблице (на SQL) с таким записей нет , кроме оригинальной.

Так же код на трансляцию справочников выдает туже ошибку

X++:

changecompany("k3")
{    
   _newrecord = new DictTable(_record.tableId).makeRecord()
....
                if (!_newrecord)
                {
                     buf2buf(_record,_newrecord);
                     _newrecord.doinsert();

                }
                else
                {
                     buf2buf(_record,_newrecord);
                     _newrecord.doupdate();
                }
}

Причем doinsert() или doupdate() – ошибка все таже


Последний раз редактировалось propeller; 05.06.2010 в 23:01.


Старый
05.06.2010, 23:00

 

#5
 

Участник

 

Регистрация: 29.09.2005

Адрес: Санкт-Петербург

Проверьте счетчик RecID. Вполне возможно, что из-за прямых вмешательств в БД он не актуален.

Ага, БД из 4.0 – все больше шансов что это именно счетчик RecId. Он хранится в таблице, на память не скажу, но название достаточно интуитивное. Таблицу надо смотреть в компании DAT.

__________________
Ivanhoe as is..


Последний раз редактировалось Ivanhoe; 05.06.2010 в 23:03.


Старый
05.06.2010, 23:08

 

#6
 

Участник

 

Регистрация: 29.09.2005

Адрес: Санкт-Петербург

Таблица – SystemSequences, посмотреть можно через AOT – System Documentation.

__________________
Ivanhoe as is..


Старый
05.06.2010, 23:12

 

#7
 

Участник

Аватар для propeller

Цитата:

Сообщение от Ivanhoe
Посмотреть сообщение

Ага, БД из 4.0 – все больше шансов что это именно счетчик RecId. Он хранится в таблице, на память не скажу, но название достаточно интуитивное. Таблицу надо смотреть в компании DAT.

Уже пробовал – В таблице SYSTEMSEQUENCES на скле нашел запись для этой таблицы (tableId = 77) для компании дат. и в поле NEXTVAL подставил единичку в начало. Перестартанул AOS все равно не помогло.

Вот запись об этой таблице
id nextVal minVal maxVal cycle name tabId dataAreaId recVersion RecId
-1 5637168173 1 9223372036854775807 false SEQNO 77 dat 801014967 -1

Причем, если я добавляю новую запись в справочник то она нормально транслируется в другую компанию. Если же делаю update() существующих записей то такая ошибка.
Опять же, если я в консолидирующей компании, руками создаю клиента – все нормально никаких ошибок.


Последний раз редактировалось propeller; 05.06.2010 в 23:30.


Старый
06.06.2010, 11:38

 

#8
 

Участник

propeller, поставьте для начала брейкпойнт в инфологе и посмотрите в этой точке, какая конкретно запись находится: с каким рекидом, в какой компании, и т.д. По-моему, это первое, что надо было сделать, чтобы начать разбирательство.


Старый
06.06.2010, 12:35

 

#9
 

Участник

Аватар для propeller

Цитата:

Сообщение от Bober
Посмотреть сообщение

propeller, поставьте для начала брейкпойнт в инфологе и посмотрите в этой точке, какая конкретно запись находится: с каким рекидом, в какой компании, и т.д. По-моему, это первое, что надо было сделать, чтобы начать разбирательство.

Это я и делал в первую очередь.
в info\add попадает из
[s]\Classes\xRecord\doinsert Запись эта находится в консолидирующей компании.
С каким RecId неизвестно. в info такой информации не нашел.
а до вызова
_newrecord.doinsert(); RecId у записи еще равен 0

Еcли _newrecord.doupdate() ([s]\Classes\xRecord\doupdate) ошибка:
Невозможно отредактировать запись в Клиенты (CustTable). Счет клиента: АНАНАС, ООО “АНАНАС”.
Запись уже существует. (Причем RecId у записи какой и должен быть)

Не понимаю причем тут update() и запись уже существует… Существует и надо ее обновить..


Последний раз редактировалось propeller; 06.06.2010 в 13:06.


Старый
06.06.2010, 13:55

 

#10
 

Участник

 

Регистрация: 21.03.2005

Адрес: Москва-Петушки

Цитата:

Сообщение от propeller
Посмотреть сообщение

Запись эта находится в консолидирующей компании.

Ну вот и ответ. В консолидирующей компании можно создавать очень ограниченный набор записей. Клиенты к ним не относятся.


Старый
06.06.2010, 14:02

 

#11
 

Участник

Аватар для propeller

Цитата:

Сообщение от Raven Melancholic
Посмотреть сообщение

Ну вот и ответ. В консолидирующей компании можно создавать очень ограниченный набор записей. Клиенты к ним не относятся.

Что вы имеете ввиду?
Это собственная доработка, трансляция клиента в другую компанию.
в 4-ке все это работало на отлично.


Старый
06.06.2010, 14:55

 

#12
 

Участник

 

Регистрация: 21.03.2005

Адрес: Москва-Петушки

Я имею ввиду, что если в компании в параметрах главной книги стоит флаг “Консолидирующая компания”, то создать там запись клиента не особенно получится.
Попробуйте создать запись не программно, в вручную.


Старый
06.06.2010, 17:54

 

#13
 

Участник

Аватар для propeller

Цитата:

Сообщение от Raven Melancholic
Посмотреть сообщение

Я имею ввиду, что если в компании в параметрах главной книги стоит флаг “Консолидирующая компания”, то создать там запись клиента не особенно получится.
Попробуйте создать запись не программно, в вручную.

Нет, флаг не стоит.
Руками запись создается нормально.


Старый
06.06.2010, 18:51

 

#14
 

Участник

 

Регистрация: 21.03.2005

Адрес: Москва-Петушки

Цитата:

Сообщение от propeller
Посмотреть сообщение

Нет, флаг не стоит

Цитата:

Сообщение от propeller

Запись эта находится в консолидирующей компании.

В Аксе есть четкое определение консолидирующей компании, если флаг не стоит, то это с точки зрения Аксы не является консолидирующей компанией, поэтому расскажи ,что значит консолидирующая компания с вашей точки зрения – стандарт, судя по всему, к вам не относится.
Ну и “код в студию”. Подробности опусти, начни с места changeCompany, заполение полей, за исключением ключевых опусти, приведи только ключевые поля и места, где заполняются ключевые поля. При этом покажи как обнуляются переменные при смене компании (то есть, есть ли конструкции типа custVend = null и т.п.)


Старый
06.06.2010, 19:10

 

#15
 

Участник

 

Регистрация: 21.03.2005

Адрес: Москва-Петушки

Кстати. Для Ax30 была рекомендация при смене компании обнулять переменную, то есть, делать что-то подобное:

X++:

changeCompany('XXX') {
{
    custTable = null;
}

В DAX4 часто этого недостаточно. Если только что искали запись по коду и после этого переключились в другую компанию и ищем по тому же коду, то обнуление переменной может не сработать!!! Как-то странно работает кэш. Не знаю как в 2009, но в DAX4 кроме обнуления переменной нужно еще запретить кеширование, то есть делать что-то подобное:

X++:

changeCompany('XXX') {
{
    custTable = null;
    custTable.disabeCash(true);
}

Причем, обнаружил эту особенность на таблице InventTrans, которая вообще не кэшируется! Получилось так, что в результате работы механизма Интеркомпани – получлось так, что лот в одной компании (по которому только что был произведен поиск, совпал с лотом в другой компании, для которой ищем лот). Если в одной компании нашли лот, то после переключения на другую компанию этот лот не ищется, а возвращается запись из первой компании!!!
После этого взял в привычку после переключения компаний запрещать кеширование. В нашем коде нет проблем, а в стандартном делам это по мере обнаружения проблем. Так что, залезь в код импорта и вставиь в нужные места для переменной записи перед её заполнением .disableCash(true).


Старый
06.06.2010, 19:25

 

#16
 

Участник

 

Регистрация: 21.03.2005

Адрес: Москва-Петушки

Для примера, работал примерно такой код:

X++:

InventTrans inventTrans;
InvenTrans inventTransNew;
InventTransId transId = 'Скл000001';

// Работеем в компании AAA

X++:

select firstOnly inventTrans where inventTrans.InventTransId == transId;
if (inventTrans )
{
    changeCompany('BBB')
    {
        inventTransNew = null; 
        select firstOnly inventTransNew where inventTransNew.InventTransId == transId;
    }
}

Лот с номером ”Скл000001′ есть как в компании AAA, так и в компании BBB. В вышеприведеном коде в inventTransNew попадала та же запись, что и в inventTrans!!!
Если же запретить кэш:

X++:

select firstOnly inventTrans where inventTrans.InventTransId == transId;
if (inventTrans )
{
    changeCompany('BBB')
    {
        inventTransNew = null; 
        inventTransNew .disableCach(true);
        select firstOnly inventTransNew where inventTransNew rans.InventTransId == transId;
    }
}

то в компании BBB находилась запись именно этой компании, а не AAA.
Так что начиная с DAX4.0 затим нужно следить не только в своем коде, но и в стандартнм.


Последний раз редактировалось Raven Melancholic; 06.06.2010 в 19:28.


Старый
07.06.2010, 09:36

 

#17
 

Участник

Лучший по профессии 2015

Лучший по профессии 2014

 

Регистрация: 12.10.2004

Адрес: Москва

Записей в блоге: 2

Цитата:

Сообщение от Raven Melancholic
Посмотреть сообщение

Причем, обнаружил эту особенность на таблице InventTrans, которая вообще не кэшируется! Получилось так, что в результате работы механизма Интеркомпани – получлось так, что лот в одной компании (по которому только что был произведен поиск, совпал с лотом в другой компании, для которой ищем лот). Если в одной компании нашли лот, то после переключения на другую компанию этот лот не ищется, а возвращается запись из первой компании!!!
После этого взял в привычку после переключения компаний запрещать кеширование. В нашем коде нет проблем, а в стандартном делам это по мере обнаружения проблем. Так что, залезь в код импорта и вставиь в нужные места для переменной записи перед её заполнением .disableCash(true).

Судя по описанным симптомам, могло повлиять вот это :
Глюки RecordViewCache

Правда у меня все это воспроизводилось в Ax 3.0
Для 4-ки не проверял.

Интернет уже видел множество сканеров портов разного функционала, скорости и информативности. Не обошел и я данную тему стороной. Но, попытался дополнить ее небольшим, хоть и не секретным, но, почему-то очень редко встречающимися функционалом, а именно, захватом баннеров. Конечно же, делать так не нужно, и вся информация в статье только лишь для ознакомления. А поможет нам в создании сканера портов, конечно же, Python.

full_c9rmCudI.jpg

Дисклеймер: Все данные, предоставленные в данной статье, взяты из открытых источников, не призывают к действию и являются только лишь данными для ознакомления, и изучения механизмов используемых технологий.

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

Из посторонних библиотек – ничего. Из тех, что идут в комплекте с python, импортируем socket и threading. Давайте выполним импорт библиотек в скрипт.

import socket
import threading

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

Создание класса для сканирования портов

    def __init__(self, target: str, port_counts: int):
        """
        При инициализации класса требуется передать ему адрес для сканирования и кол-во портов,
        которые требуется просканировать.
        :ip - обработанный адрес для сканирования, в котором,
        в случае невозможности получения адреса содержится None.
        :banners_port - словарь, в котором содержаться все открытые ip-порты и баннеры
        полученные от сервисов запущенных на них.
        :open_port - словарь, содержащий все открытые порты без баннеров.
        :param target: Полученный от пользователя адрес для сканирования. Тип: строка.
        :param port_counts: Полученное от пользователя кол-во портов для сканирования. Тип: целое число.
        """
        self.target = target
        self.ip = self.check_target()
        self.port_counts = int(port_counts)
        self.banners_port = dict()
        self.open_port = dict()
    def check_target(self):
        """
        Производится обработка поступившего от пользователя адреса.
        Удаление http(https) для дальнейшего получения ip домена.
        Запрашивается ip-адрес, который возвращается из функции,
        если его удалось получить. Если нет, возвращается None.
        :return: Если не возникает исключения, возвращается ip-адрес,
        иначе возвращается None
        """
        if self.target.startswith("http"):
            self.target = self.target.split("/")[2]
        try:
            ip_domain = socket.gethostbyname(self.target)
            return ip_domain
        except socket.gaierror:
            return

Создадим функцию для сканирования порта, scan_port(self, port: int). На вход она принимает порт. Адрес цели у нас глобален в пределах класса. Создаем объект сокета с соединением по TCP.

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

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

        s.settimeout(5)
        if self.ip is None:
            return

Создаем соединение на полученный ранее ip и полученный на входе порт. Получаем баннер. Обернем функцию получения баннера в блок try – except. Для начала проверяем, не является ли ответ полученный от сервиса пустым. Если да, обновляем словарь открытых портов без баннеров, пытаемся получить с помощью вспомогательной функции название сервиса работающего на данном порту.

Если баннер получен, добавляем информацию в словарь открытых портов с баннерами. В случае ошибки получения баннера и возникновения исключения, также добавляем информацию об открытом порте в словарь отрытых портов без баннеров. Если возникает ошибка декодирования, добавляем в словарь портов с баннерами не декодированную информацию.

Ну и если возникают ошибки соединения, просто выходим из функции.

    def scan_port(self, port: int):
        """
        В функции выполняется подключение к ip-адресу на полученный
        порт. Если подключение удалось, значит порт открыт. Производится
        попытка получить баннер. Если баннер не получен, обрабатывается
        исключение, в котором идет запрос службы на порту у функции за
        пределами класса. Если получить службу не удалось, возвращается
        unassigned. Полученные значения добавляются в словари для
        последующей обработки. В словарь с баннерами добавляются значения,
        если баннер получен. В остальных случаях, в словарь открытых портов.
        :param port: Номер порта для сканирования. Целое число
        :return: Возвращается None. Служит для выхода из функции
        """
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(5)
        if self.ip is None:
            return
        try:
            s.connect((self.ip, port))
            try:
                banner = s.recv(1024).decode().strip()
                if banner == '':
                    self.open_port.update({port: get_serv(port).upper()})
                else:
                    self.banners_port.update({port: banner})
            except OSError:
                self.open_port.update({port: get_serv(port).upper()})
            except UnicodeDecodeError:
                banner = s.recv(1024).strip()
                self.banners_port.update({port: banner})
        except (socket.timeout, ConnectionRefusedError, OSError):
            return

Запуск потоков для сканирования портов

Создадим функцию для запуска потоков сканирования портов port_rotate(self). Создадим список, в который будем добавлять запущенные потоки. Запускаем цикл по диапазону портов от 1 до полученного от пользователя. Создаем экземпляр потока с целевой функцией и параметрами для передачи, в данном случае, передать нужно порт. Указываем, что поток запустится как демон, стартуем поток и добавляем в список.

    def port_rotate(self):
        """
        Служит для перебора в цикле полученных от пользователя
        портов и передачи их в функцию сканирования, где производится
        их обработка.
        :return: Ничего не возвращает.
        """
        threads = []
        for port in range(1, self.port_counts+1):
            t = threading.Thread(target=self.scan_port, kwargs={'port': port})
            t.daemon = True
            t.start()
            threads.append(t)
            time.sleep(0.02)
        for thread in threads:
            thread.join()

Вспомогательная функция для получения названия сервиса на порту

Создадим вспомогательную функцию get_serv(port). На вход она принимает порт, информацию о котором нужно получить. С помощью функции сокетов getservbyport выполняется попытка получения названия сервиса. Если она не удается, возвращается ‘unassigned’, если же название сервиса получено, возвращается название сервиса.

def get_serv(port):
    """
    Запрашивается название сервиса по порту. Если название получено,
    оно возвращается в функцию сканирования портов. Если нет, обрабатывается
    исключение и возвращается 'unassigned'.
    :param port: Порт для запроса имени сервиса. Целое число.
    :return: Возвращается сервис, если получен. В противном случае
    возвращается 'unassigned'.
    """
    try:
        return socket.getservbyport(port)
    except OSError:
        return 'unassigned'

import socket
import threading
import time


def get_serv(port):
    """
    Запрашивается название сервиса по порту. Если название получено,
    оно возвращается в функцию сканирования портов. Если нет, обрабатывается
    исключение и возвращается 'unassigned'.
    :param port: Порт для запроса имени сервиса. Целое число.
    :return: Возвращается сервис, если получен. В противном случае
    возвращается 'unassigned'.
    """
    try:
        return socket.getservbyport(port)
    except OSError:
        return 'unassigned'


class PortScan:
    """
    Класс для сканирования портов локального или удаленного компьютера.
    Из зависимостей требует библиотеку socket, а также наличие интернета,
    так как некоторые запросы обрабатываются с его помощью.
    """
    def __init__(self, target: str, port_counts: int):
        """
        При инициализации класса требуется передать ему адрес для сканирования и кол-во портов,
        которые требуется просканировать.
        :ip - обработанный адрес для сканирования, в котором,
        в случае невозможности получения адреса содержится None.
        :banners_port - словарь, в котором содержатся все открытые ip-порты и баннеры
        полученные от сервисов запущенных на них.
        :open_port - словарь, содержащий все открытые порты без баннеров.
        :param target: Полученный от пользователя адрес для сканирования. Тип: строка.
        :param port_counts: Полученное от пользователя кол-во портов для сканирования. Тип: целое число.
        """
        self.target = target
        self.ip = self.check_target()
        self.port_counts = int(port_counts)
        self.banners_port = dict()
        self.open_port = dict()

    def check_target(self):
        """
        Производится обработка поступившего от пользователя адреса.
        Удаление http(https) для дальнейшего получения ip домена.
        Запрашивается ip-адрес, который возвращается из функции,
        если его удалось получить. Если нет, возвращается None.
        :return: Если не возникает исключения, возвращается ip-адрес,
        иначе возвращается None
        """
        if self.target.startswith("http"):
            self.target = self.target.split("/")[2]
        try:
            ip_domain = socket.gethostbyname(self.target)
            return ip_domain
        except socket.gaierror:
            return

    def scan_port(self, port: int):
        """
        В функции выполняется подключение к ip-адресу на полученный
        порт. Если подключение удалось, значит порт открыт. Производится
        попытка получить баннер. Если баннер не получен, обрабатывается
        исключение, в котором идет запрос службы на порту у функции за
        пределами класса. Если получить службу не удалось, возвращается
        unassigned. Полученные значения добавляются в словари для
        последующей обработки. В словарь с баннерами добавляются значения,
        если баннер получен. В остальных случаях, в словарь открытых портов.
        :param port: Номер порта для сканирования. Целое число
        :return: Возвращается None. Служит для выхода из функции
        """
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(5)
        if self.ip is None:
            return
        try:
            s.connect((self.ip, port))
            try:
                banner = s.recv(1024).decode().strip()
                if banner == '':
                    self.open_port.update({port: get_serv(port).upper()})
                else:
                    self.banners_port.update({port: banner})
            except OSError:
                self.open_port.update({port: get_serv(port).upper()})
            except UnicodeDecodeError:
                banner = s.recv(1024).strip()
                self.banners_port.update({port: banner})
        except (socket.timeout, ConnectionRefusedError, OSError):
            return

    def port_rotate(self):
        """
        Служит для перебора в цикле полученных от пользователя
        портов и передачи их в функцию сканирования, где производится
        их обработка.
        :return: Ничего не возвращает.
        """
        threads = []
        for port in range(1, self.port_counts+1):
            t = threading.Thread(target=self.scan_port, kwargs={'port': port})
            t.daemon = True
            t.start()
            threads.append(t)
            time.sleep(0.02)
        for thread in threads:
            thread.join()

Использование созданного класса
Функция для сканирования портов

Теперь давайте используем созданный класс в деле. Создадим новый файл main.py. В него импортируем из модуля с созданным нами классом, собственно класс.

from portscan_v import PortScan

    target = input('\n[*] Введите домен или IP-адрес для сканирования >>> ')
    port_count = int(input('[*] Введите количество портов для сканирования (1000 по умолчанию) >>> ') or 1000)
    print('\n- Сканирую...', end='')
    scan = PortScan(target, port_count)
    scan.port_rotate()
    print('\r- Выполнено', end='')

Дальше идут проверки. Если функция сканирования вернула нам оба пустых словаря, пишем, что ничего не найдено и выходим из функции. Если же не пустой хоть один словарь, перебираем и выводим информацию в терминал.

    if len(banners) == 0 and len(o_port) == 0:
        print('Открытых портов не найдено.')
        return
    else:
        if target.startswith("http"):
            target_print = target.split("/")[2]
            print(f'\n\nСВОДНАЯ ИНФОРМАЦИЯ ПО ДОМЕНУ (IP): {target_print}\n{"*"*50}')
        else:
            print(f'\n\nСВОДНАЯ ИНФОРМАЦИЯ ПО ДОМЕНУ (IP): {target}\n{"*"*50}')
        for bann in banners:
            print(f'  Порт: {bann:5}  Баннер: {banners[bann]}')
        for o in o_port:
            print(f'  Порт: {o:5}  Сервис: {o_port[o]}')

from portscan_v import PortScan


def main():
    target = input('\n[*] Введите домен или IP-адрес для сканирования >>> ')
    port_count = int(input('[*] Введите количество портов для сканирования (1000 по умолчанию) >>> ') or 1000)
    print('\n- Сканирую...', end='')
    scan = PortScan(target, port_count)
    scan.port_rotate()
    print('\r- Выполнено', end='')

    banners = scan.banners_port
    o_port = scan.open_port

    if len(banners) == 0 and len(o_port) == 0:
        print('Открытых портов не найдено.')
        return
    else:
        if target.startswith("http"):
            target_print = target.split("/")[2]
            print(f'\n\nСВОДНАЯ ИНФОРМАЦИЯ ПО ДОМЕНУ (IP): {target_print}\n{"*"*50}')
        else:
            print(f'\n\nСВОДНАЯ ИНФОРМАЦИЯ ПО ДОМЕНУ (IP): {target}\n{"*"*50}')
        for bann in banners:
            print(f'  Порт: {bann:5}  Баннер: {banners[bann]}')
        for o in o_port:
            print(f'  Порт: {o:5}  Сервис: {o_port[o]}')


if __name__ == "__main__":
    main()

Для примера, ниже показан результат работы функции сканирования портов на тестовой машине Metasploitable2.

screenshot12.png

Таким образом, из полученной информации можно сделать вывод как об операционной системе, на которой работает данная машина, так и о сервисах, которые на ней запущены. Это, скажем так, простое сканирование с захватом баннеров. Надо сказать, что далеко не на всех доменах вам удастся получить столь подробную информацию, но, если данная информация будет получена, вы уже можете ее использовать по назначению. К примеру, по полученному баннеру сервиса можно попытаться узнать, существует ли уязвимость для данной версии, а также эксплоит к ней.

А на этом, пожалуй, все.

Спасибо за внимание. Надеюсь, что данная информация будет вам полезна

Читайте также:  В папке назначения movefile произошел сбой кода 225

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *