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

SecuriTeam <[email protected]>
Newsgroups gmane.comp.security.securiteam
Message-ID <[email protected]>
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:[email protected]> 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: [email protected] 
In order to subscribe to the mailing list, simply forward this email to: [email protected] 


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

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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.