/*
Simply Win Port-Scanner v0.3
Autore: __GiReX__
Linguaggio: C++
Descrizione: Windows Port-Scanner with timeout parameter
Changelog: Aggiunta la possibilità di risolvere l'host
E' quindi possibile passare al programma un DNS per lo scan!
Site: www.girex.altervista.org
*/
#include <iostream>
#include <winsock.h>
#include <cstdlib>
#include <cstring>
#include <ctime>
using namespace std;
bool scan(SOCKET *sock, sockaddr_in *sock_addr, u_int port, u_long *enabled, timeval *time);
int check_host(char *host, sockaddr_in *sock_addr);
int check_port(u_int start, u_int end);
void usage(char *prog);
int main(int argc, char *argv[])
{
u_int start_port, end_port;
SOCKET sock;
WSADATA info;
SOCKADDR_IN sock_addr;
u_long enabled = 1;
timeval timeout;
bool noth = true;
if(argc < 4) {
usage(argv[0]);
return 1;
}
if(argc!=5) {
timeout.tv_sec = 0;
timeout.tv_usec = 500000; // 500 millisceondi di default
} else {
timeout.tv_sec = 0;
timeout.tv_usec = atoi(argv[4])*1000; // Timeout da riga di comando
}
cout << "Simply Win Port-Scanner v0.3 by __GiReX__\n\n"
<< "Opened ports list:\n\n";
start_port = atoi(argv[2]); // Range di porte
end_port = atoi(argv[3]); // da riga di comando
if(check_port(start_port, end_port)) return 1; // Controllo se il range di porte è valido
WSAStartup(MAKEWORD(2, 2), &info); // Inizializzo la procedura per i socket
sock_addr.sin_family = AF_INET; // Struttura sockaddr_in : Protocollo
if(check_host(argv[1], &sock_addr)) return 1; // Controllo se l'input dell'host è regolare
for(int i = start_port; i <= end_port; i++)
{
cout << "Scanning: " << i << "\r";
sock = socket(AF_INET, SOCK_STREAM, 0);
if(scan(&sock, &sock_addr, i, &enabled, &timeout)) { // Se scan ritorna true la porta è aperta
cout << "Scanning: " << i << "\t opened\n";
noth = false;
}
}
if(noth) cout << "No port seems is open\n";
cout << "Scanning: //\tfinished\n\nElapsed time: " << clock() / CLOCKS_PER_SEC << " s\n";
closesocket(sock); // Chiudo socket
WSACleanup(); // Pulisco e termino procedura socket
return 0;
}
bool scan(SOCKET *sock, sockaddr_in *sock_addr, u_int port, u_long *enabled, timeval *timeout)
{
FD_SET fds;
sock_addr->sin_port = htons(port); // Setto la porta
ioctlsocket(*sock, FIONBIO, enabled); // Abilito le socket non-blocking
FD_ZERO(&fds); // Pulisco il set
FD_SET(*sock, &fds); // Aggiungo il socket al SET della select
connect(*sock,(struct sockaddr*)sock_addr,sizeof(struct sockaddr)); // Ritorna sempre errore
if(select(*sock, 0, &fds, 0, timeout)>0) return true; // Individuo il socket con la select
// Se ritorna 1 valore > 0 la porta è aperta
return false;
}
int check_host(char *chost, sockaddr_in *sock_addr)
{
u_long host;
LPHOSTENT site;
if(!strstr(chost, "www")) { // Se non trovo www allora viene specificato un IP
host = inet_addr(chost);
if(host == INADDR_NONE) { // Se ritorna INADDR_NONE l'IP non è valido
cout << "Invalid IP format! Unable to resolve the host!\n";
return 1;
} else
sock_addr->sin_addr.s_addr = host; // Se invece trovo www si tratta di un DNS
} else {
site = gethostbyname(chost); // Risolvo il DNS..
if(!site) {
cout << "Invalid www address! Unable to resolve the host!\n";
return 1;
} else
sock_addr->sin_addr = *((LPIN_ADDR)*site->h_addr_list); }
return 0;
}
int check_port(u_int start, u_int end)
{
if(start > 65535 || start < 0 || end > 65535 || end < 0 || start > end) {
cout << "Invalid port range! Re-insert it!\n";
return 1;
}
return 0;
}
void usage(char *prog)
{
cout << "\nUsage: " << prog << " <ip/host> <porta_iniziale> <porta_finale> [time-out]\n\n"
<< "Example: scan.exe www.google.com 1 100\n"
<< " scan.exe 127.0.0.1 1 500 80\n\n"
<< "[time-out] is optional and must be expressed in milliseconds\n"
<< "default is 500 milliseconds, more is lower more the scan faster!\n";
}