Задать вопрос
zergon321
@zergon321

Почему сканер портов подключается всего к одному порту?

Написал простой сканер портов на асинхронных сокетах. Соединение при сканировании mail.ru и диапазоне [1; 1024] удается установить только на порт 25, на остальные - безуспешно. Кусок main():

port_range range; //structure for saving range of ports

(std::cin >> range.from >> range.to).get();

con_list cons; //std::vector of structures with sockets
sockaddr_in server_data;
u_long cmd = 1;
fd_set write;
timeval wait_time = { 0, 0 };
USHORT port = range.from;

server_data.sin_family = AF_INET;
tmp.s_addr = *(u_long*)remote_host_info->h_addr;
inet_pton(AF_INET, (PCSTR)inet_ntoa(tmp), &server_data.sin_addr);

while (true)
{
    //CONNECTION PHASE
    if (port <= range.to)
    {
        SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        server_data.sin_port = htons(port);

        if (sock == INVALID_SOCKET)
        {
            output_error("Couldn't create scan socket");
            finalize(); //WSACleanup(), system("pause")

            return EXIT_FAILURE;
        }
        //else
            //std::cout << "Created" << std::endl;

        if (ioctlsocket(sock, FIONBIO, &cmd) == SOCKET_ERROR)
        {
            error_to_close_cons("Couldn't put the socket in asynchronous mode", cons); //closes all created sockets, clears con_list container
            error_to_close_socket("", sock);
            finalize();

            return EXIT_FAILURE;
        }
        //else
            //std::cout << "Async" << std::endl;

        cons.push_back({ sock, 0, con_mode::write, port, 0, clock() });

        if (connect(sock, (SOCKADDR*)&server_data, sizeof(server_data)) == SOCKET_ERROR)
            if (WSAGetLastError() != WSAEWOULDBLOCK)
            {
                error_to_close_cons("Couldn't connect", cons);
                error_to_close_socket("", sock);
                finalize();

                return EXIT_FAILURE;
            }
        //else
            //std::cout << "Connected" << std::endl;
    }

    port++;

    //SCAN PHASE
    delete_invalid_cons(cons); //deletes structures with INVALID_SOCKET
    FD_ZERO(&write);

    if (cons.empty())
        break;

    for (u_int i = 0; i < cons.size(); i++)
        FD_SET(cons[i].sock, &write);

    if (select(0, NULL, &write, NULL, &wait_time) == SOCKET_ERROR)
    {
        error_to_close_cons("Couldn't perform client loop", cons);
        finalize();

        return EXIT_FAILURE;
    }
    //else
        //std::cout << "Selected" << std::endl;

    for (u_int i = 0; i < cons.size(); i++)
        if (FD_ISSET(cons[i].sock, &write))
        {
            std::cout << "Connection established on port " << cons[i].con_port << " in " << (clock() - cons[i].con_time) / CLOCKS_PER_SEC << " seconds" << std::endl;

            close_socket(cons[i].sock);
            cons[i].sock = INVALID_SOCKET;
        }
        else
        {
            std::cout << "Waiting time exceeded" << std::endl;
            close_socket(cons[i].sock);
            cons[i].sock = INVALID_SOCKET;
        }
        //else
            //std::cout << "Couldn't scan" << std::endl;
}

finalize();

return EXIT_SUCCESS;
}


Кусок заголовочника:

#pragma once
#ifndef WINSOCK_ERROR
#define WINSOCK_ERROR

#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <cstring>
#include <ctime>

#define ECHO_PORT 32768
#define WSA_VERSION 0x0202
#define LOCALHOST "127.0.0.1"
#define BUFF_SIZE 8192
#define BACKLOG 4
#define WAIT_TIME 10
#define INPUT_BUFF 16


namespace con_mode
{
    enum mode
    {
        write,
        read,
        input //for client
    };
}

typedef struct async_connection
{
    SOCKET sock;
    int buffer_pos; //position in buffer
    con_mode::mode c_mode; //defines in which mode (recv/send) a socket works (for single-channel applications)
    //char* buffer; //for message from client
    USHORT con_port;
    int address_num; //address number in HOSTENT struct
    clock_t con_time;
} async_connection;

typedef struct port_range
{
    USHORT from;
    USHORT to;
    bool error_flag;
    char* error_message;
} port_range;

typedef std::vector<async_connection> con_list;


Другой сканер при тех же условиях устанавливал соединение на большее число портов.
  • Вопрос задан
  • 363 просмотра
Подписаться 1 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 2
dio4
@dio4
team leader, system engineer, master of sports
nmap -O mail.ru

Starting Nmap 6.40 ( nmap.org ) at 2017-08-14 14:08 MSK
Nmap scan report for mail.ru (94.100.180.200)
Host is up (0.13s latency).
Other addresses for mail.ru (not scanned): 217.69.139.201 217.69.139.200 94.100.180.201
Not shown: 986 filtered ports
PORT STATE SERVICE
25/tcp closed smtp
53/tcp open domain
80/tcp open http
и тд....
а ping mail.ru дает
PING mail.ru (94.100.180.201) 56(84) bytes of data.
64 bytes from mail.ru (94.100.180.201): icmp_seq=1 ttl=49 time=483 ms
разницу в ip видите?
Кроме этого
$ nslookup mail.ru
Server: 127.0.1.1
Address: 127.0.1.1#53

Non-authoritative answer:
Name: mail.ru
Address: 217.69.139.200
Name: mail.ru
Address: 94.100.180.201
Name: mail.ru
Address: 94.100.180.200
Name: mail.ru
Address: 217.69.139.201
Кроме этого, строка Other addresses for mail.ru (not scanned): 217.69.139.201 217.69.139.200 94.100.180.201
те есть еще адреса....
так вы о каком mail.ru ??? Кстати, другие ИП дают другой резалт, я проверил (но не все...).
Ответ написан
Комментировать
Если вы запускаете сканирование под Windows, то соединения на порты 25, 80 и т.д. обычно перехватываются антивирусом или службами типа alg (application layer gateway). На mail.ru порт 25 закрыт. То что вы смогли на него подключиться просто означает что у вас какое-то приложение перехватило коннект.

Здесь неправильно примерно все. Из того что сразу в глаза бросается:
1. server_data перед использованием надо занулить
2. FD_SET по умолчанию поддерживает только 64 сокета (на Windows, в *nix так же ограниченное количество). Соответственно вы сканируете только первые 64 порта
3. connect() не даст вам ошибки подключения, т.к. вы перевели сокет в асинхронный режим, соответственно в большинстве случаев у вас будет waiting time exceeded, хотя на самом деле ошибка будет другая.
4. там такое ощущение что кусок кода вырезан, т.к проверка сокетов попала в тот же цикл где идут коннекты.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы