[TOOL] Scan6 - IPv4/IPv6 Port Scanner for Windows

From: SecuriTeam (support_at_securiteam.com)
Date: 05/29/05

  • Next message: SecuriTeam: "[TOOL] Dissembler - Polymorphs Bytecode to a Printable ASCII String"
    To: list@securiteam.com
    Date: 29 May 2005 18:43:02 +0200
    
    

    The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
    - - promotion

    The SecuriTeam alerts list - Free, Accurate, Independent.

    Get your security news from a reliable source.
    http://www.securiteam.com/mailinglist.html

    - - - - - - - - -

      Scan6 - IPv4/IPv6 Port Scanner for Windows
    ------------------------------------------------------------------------

    SUMMARY

    DETAILS

    Scan6 is a simple high multi-threading console application IPv4/IPv6
    single host port scanner for Microsoft Windows 2000 and XP. It can check
    for ANY open port on a single IPv4/IPv6 host or you can specify a port
    range. Scan6 requires a mandatory option in order to specify if you are
    going to scan an IPv4 or an IPv6 address.

    Code:
    /*
     scan6
     written by Marco Del Percio
     09/11/2004

     DESCRIPTION: Scan6 is a simple IPv4/IPv6 single host portscanner.
     It can check for ANY open port on a single IPv4/IPv6 host or you
     can specify a startport and an endport if you don't want to check
     all the 65535 ports. Scan6 requires a mandatory option in order
     to specify if you are going to scan an IPv4 or an IPv6 address.
     Scan6 is a high-multithreading console application.

     REQUIRES: This application is designed to work on Windows 2000/XP however
     it was only tested on Windows XP SP1. To use it with IPv6 addresses you
     MUST have an IPv6 address (so you should have Microsoft IPv6 Tech.
    Preview
     if you are using Windows 2k).
     To compile this you need:
     1)Platform SDK (updated)
     2)Microsoft VC++6.0
     3)IPv6 installed

     NOTE: This application was only tested on Windows XP SP1!
     This application uses a lot of threads if you specify "big" port-range.
     So checking all 65535 ports will take much time, DO NOT TERMINATE the
    program ;-P
     just wait ;)
     IMPORTANT: If you don't specify startport and endport (65535 ports), I
    have decided
     to use 257 threads with every thread checking for 255 ports using a
    single socket.
     On the other side, if you specify a startport and an endport (smaller
    range) I have
     decided to use X thread (where X can be max 1285) with every thread
    checking for
     51 ports using a single socket, this way if the range is small there are
    more threads
     that means more sockets and "generally" means more speed in small port
    ranges.

    */
    #define WIN32_LEAN_AND_MEAN
    #include <winsock2.h>
    #ifndef IPPROTO_IPV6
    #include <tpipv6.h> // For IPv6 Tech Preview.
    #endif
    #include <ws2tcpip.h>
    #include <stdio.h>
    #include <process.h>

    #pragma comment(lib, "ws2_32")

    //Global Variables
    HANDLE TID[257];
    HANDLE *TIARRAY;
    WSADATA wsaData;
    char *server;
    int stport, edport, avanzo, totalthreads;
    short family;

    //Threads declaration
    void Scan(void *p);
    void ScanPort(void *q);

    int main(int argc, char *argv[]) {

    int RetVal, i, q, totalports;

    if(!(argc == 3 || argc == 5)) {
     printf("\nERROR! Usage: %s <-4|-6> <ipv4/ipv6_host_to_scan> [startport]
    [endport]\n\nNOTE: If you want to check \"not so big\" port range\nspecify
    a startport and an endport, the scanner will go faster\n\n", argv[0]);
     exit(-1);
    }
    //family protocol (mandatory)
    if((RetVal = atoi(argv[1])) == -4) {
     family = AF_INET;
    }
    else if((RetVal = atoi(argv[1])) == -6) {
     family = AF_INET6;
    }
    else {
     fprintf(stderr, "\nERROR! The first option must be -4 or -6\n");
     exit(-1);
    }
    //IPv4/IPv6 host or IP address (mandatory)
    server = argv[2];

    if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0) {
            fprintf(stderr, "\nWSAStartup failed with error %d\n", RetVal);
            WSACleanup();
            exit(-1);
    }

    //we are checking a specific port range from a startport to an endport
    if(argc == 5) {
     stport = atoi(argv[3]);
     edport = atoi(argv[4]);
     if(stport >= edport) {
      fprintf(stderr, "\nERROR! Endport must be higher than startport...\n");
      WSACleanup();
      exit(-1);
     }
     if(stport < 1 || stport > 65535 || edport < 1 || edport > 65535) {
      fprintf(stderr, "\nERROR! Ports must be values between 1 and 65535\n");
      WSACleanup();
      exit(-1);
     }
     //1 single thread will check 51 open ports
     totalports = edport - stport + 1; //total number of ports
     totalthreads = (int)(totalports / 51); //total number of necessary
    threads
     avanzo = totalports % 51; //missing ports to be added to the last
    thread
     if(avanzo > 0) {
      totalthreads++;
     }
     printf("\n\n----IPv4/IPv6 PortScanner for Windows 2k/XP----\n\nBy
    LeVante^\n\n----Scan6----\nHost/IP Address: %s\nStart Port: %d\nEnd Port:
    %d\n----PortScanning just started. Please wait----\n\n", server, stport,
    edport);
     TIARRAY = (HANDLE) malloc(totalthreads*sizeof(HANDLE));
     
     for(i=0;i<totalthreads;i++) {
      TIARRAY[i] = CreateMutex(NULL, FALSE, NULL);
      _beginthread( ScanPort, 0, (void *) i);
     }
     Sleep(100);
     //waits for all threads to end
     WaitForMultipleObjects(totalthreads, TIARRAY, TRUE, INFINITE);

     for(q=0;q<totalthreads;q++)
      CloseHandle(TIARRAY[q]);

    }
    //we are checking ALL the 65535 ports
    else {
     stport = 1;
     edport = 65535;

     printf("\n\n----IPv4/IPv6 PortScanner for Windows 2k/XP----\n\nBy
    LeVante^\n\n----Scan6----\nHost/IP Address: %s\nStart Port: %d\nEnd Port:
    %d\n\nNOTE: If you want to check \"not so big\" port range\nspecify a
    startport and an endport, the scanner will go faster\n\n----PortScanning
    just started. Please wait----\n\n", server, stport, edport);
     //1 single thread uses 1 socket to check 255 ports. I use 257 threads. So
    255*257 = 65535 ports
     for(i=0;i<257;i++) {
      TID[i] = CreateMutex(NULL, FALSE, NULL);
      _beginthread( Scan, 0, (void *) i);
     }
     Sleep(100);
     //waits for all threads to end
     WaitForMultipleObjects(257, TID, TRUE, INFINITE);

     for(q=0;q<257;q++)
      CloseHandle(TID[q]);
    }

    printf("\n\n----Port Scan terminated----\n");
    WSACleanup();
    exit(0);
    }

    void Scan(void *p) {

    int id = (int) p;
    int connfd, Ret, startport, endport, r;
    ADDRINFO Hints, *AddrInfo;
    char portstr[6];
    SOCKET sock;
    struct sockaddr_in servaddr;
    struct sockaddr_in6 *servaddr6 = NULL;

    WaitForSingleObject(TID[id], INFINITE);

    startport = id * 255 + 1;
    endport = startport + 255 - 1;

    //one socket per thread
    if((sock = socket(family, SOCK_STREAM, 0)) == INVALID_SOCKET) {
      fprintf(stderr, "Thread with id: %d couldn't create Socket\n", id);
      ReleaseMutex(TID[id]);
      _endthread();
    }
    if(family == AF_INET) {
     memset(&servaddr, 0, sizeof(servaddr));
     servaddr.sin_addr.s_addr = inet_addr(server);
     servaddr.sin_family = family;

     for(r=startport;r<=endport;r++) {
      servaddr.sin_port = htons(r); //we only change the port, this way struct
    reuse is maximized

      if((connfd = connect(sock, (struct sockaddr *)&servaddr,
    sizeof(servaddr))) == 0) {
       printf("Port %d OPEN\n", r);
      }
     
     }
    }
    else if(family == AF_INET6) {
     memset(&Hints, 0, sizeof(Hints));
     Hints.ai_family = (int) family;
     Hints.ai_socktype = SOCK_STREAM;
     sprintf(portstr, "%d", startport);
     //getaddrinfo is called only once just to fill the AddrInfo->ai_addr
    structure
     if((Ret = getaddrinfo(server, portstr, &Hints, &AddrInfo)) < 0) {
      fprintf(stderr, "Unable to resolve %s\n", server);
      fflush(stderr);
      ReleaseMutex(TID[id]);
      _endthread();
     }

     servaddr6 = (struct sockaddr_in6 *)AddrInfo->ai_addr;
     
     
     for(r=startport;r<=endport;r++) {
      servaddr6->sin6_port = htons(r); //we only change the port, this way
    struct reuse is maximized

      if((connfd = connect(sock, (struct sockaddr *) servaddr6, sizeof(struct
    sockaddr_in6))) == 0) {
       printf("Port %d OPEN\n", r);
      }
     
     }
    }

    closesocket(sock);
    ReleaseMutex(TID[id]);
    _endthread();
    }

    void ScanPort(void *q) {

    int id = (int) q;
    int connfd, Ret, startport, endport, r;
    ADDRINFO Hints, *AddrInfo;
    char portstr[6];
    SOCKET sock;
    struct sockaddr_in servaddr;
    struct sockaddr_in6 *servaddr6 = NULL;

    WaitForSingleObject(TIARRAY[id], INFINITE);

    startport = id * 51 + stport;
    if(id == (totalthreads - 1) && avanzo > 0) {
     endport = startport + (avanzo - 1);
    }
    else {
     endport = startport + 50;
    }
    //one socket per thread
    if((sock = socket(family, SOCK_STREAM, 0)) == INVALID_SOCKET) {
      fprintf(stderr, "Thread with id: %d couldn't create Socket\n", id);
      ReleaseMutex(TIARRAY[id]);
      _endthread();
    }

    if(family == AF_INET) {
     memset(&servaddr, 0, sizeof(servaddr));
     servaddr.sin_addr.s_addr = inet_addr(server);
     servaddr.sin_family = family;

     for(r=startport;r<=endport;r++) {
      servaddr.sin_port = htons(r); //we only change the port, this way struct
    reuse is maximized

      if((connfd = connect(sock, (struct sockaddr *)&servaddr,
    sizeof(servaddr))) == 0) {
       printf("Port %d OPEN\n", r);
      }
     
     }
    }
    else if(family == AF_INET6) {
     memset(&Hints, 0, sizeof(Hints));
     Hints.ai_family = (int) family;
     Hints.ai_socktype = SOCK_STREAM;
     sprintf(portstr, "%d", startport);
     //getaddrinfo is called only once just to fill the AddrInfo->ai_addr
    structure
     if((Ret = getaddrinfo(server, portstr, &Hints, &AddrInfo)) < 0) {
      fprintf(stderr, "Unable to resolve %s\n", server);
      fflush(stderr);
      ReleaseMutex(TIARRAY[id]);
      _endthread();
     }

     servaddr6 = (struct sockaddr_in6 *)AddrInfo->ai_addr;
     
     
     for(r=startport;r<=endport;r++) {
      servaddr6->sin6_port = htons(r); //we only change the port, this way
    struct reuse is maximized

      if((connfd = connect(sock, (struct sockaddr *) servaddr6, sizeof(struct
    sockaddr_in6))) == 0) {
       printf("Port %d OPEN\n", r);
      }
     
     }
    }

    closesocket(sock);
    ReleaseMutex(TIARRAY[id]);
    _endthread();
    }

    /* EOF */

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:levante@manicomio.org> Marco
    Del Percio.

    ========================================

    This bulletin is sent to members of the SecuriTeam mailing list.
    To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
    In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

    ====================
    ====================

    DISCLAIMER:
    The information in this bulletin is provided "AS IS" without warranty of any kind.
    In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.


  • Next message: SecuriTeam: "[TOOL] Dissembler - Polymorphs Bytecode to a Printable ASCII String"

    Relevant Pages

    • [UNIX] Solaris Socket Hijack Vulnerability
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... By binding a socket with an already binded port number of specific IP ... attackers can hijack an already binded sockets in Solaris. ... A bug with Solaris Kernel flag of SO_REUSEADDR cause the Kernel to accept ...
      (Securiteam)
    • [EXPL] Quake 3 Buffer Overflow (Exploit)
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... port and exit cleanly with an unsuspicious error message. ... unsigned char ipx; ... int hooklen; // for both sendservercommand and directconnect ...
      (Securiteam)
    • [TOOL] IRC DCC Connect() Blind Port Scanner
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... IRC DCC ConnectBlind Port Scanner ... After waiting a short while for the mIRC client ...
      (Securiteam)
    • [NT] SLMail Pro Multiple Denial of Service
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... The SLMail Pro Web Service running on port 801 is ... int main{ ...
      (Securiteam)
    • [EXPL] TCP Window Size RST
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... (IP addresses of the peers and port numbers). ... be used to reset any TCP connection once the range of sequence numbers is ... irssi's window size was larger so I figured ...
      (Securiteam)