Scanneur de port tcp en ligne de commande

Contenu du snippet

Voici un code documenté afin de donner un exemple simple d'utilisation des socket via Tcp. En fournissant un scanneur de port Tcp.

Le code, l'exe et surtout la documentation se trouvent à l'adresse suivante :

_SebF

http://www.frameip.com
Un site pour les spécialistes IP

Source / Exemple :


// ********************************************
// Nom : ScanTcp.cpp
// Auteur : SebF AT frameIP.com
// Date de création : 01 octobre 2004
// version : 1.0
// Licence : Cette executable est libre de toute utilisation.
//           La seule condition existante est de faire référence
//           au site http://www.frameip.com afin de respecter le travail d'autrui.
// ********************************************

// ********************************************************
// Les includes
// ********************************************************
#include <C:\\RepPerso\\Personnel\\Developpement\\Projets\\LibrairieSocket\\LibrairieSocket.h>

// ********************************************************
// Les procédures
// ********************************************************
void initiation_des_variables(void);
void gestion_des_arguments(int argc, char* argv[]);
void Changement_aleatoire_des_valeurs(void);
void envoi_de_la_trame(void);
void reception_de_la_trame(void);
void sortie_avec_erreur(int);

// ********************************************************
// Les variables
// ********************************************************
struct ipv4 entete_ipv4;			// Entete IP
struct ipv4 *entete_ipv4_reception;	// Entete IP receptionnée
struct tcp entete_tcp;				// Entete TCP
struct tcp *entete_tcp_reception;	// Entete TCP receptionnée
char data_a_envoyer[65535];			// Data
size_t longueur_de_data_a_envoyer;	// Longueur du char *, je n'utilise pas strlen car il peux y avoir des 0
char trame_a_envoyer[65535];		// Entete IP + data
int nombre_de_caractere_emis;		// Variable récupérant le nombre de caractères émis
char ip_source_initiale[15];		// Adresse IP Source permettant d'initier entete_ipv4.ip_source
char ip_destination_initiale[15];	// Adresse IP Destination permettant d'initier entete_ipv4.ip_destination
bool port_source_aleatoire;			// Acive ou désactive le mode Port Source Aléatoire
unsigned short port_depart;			// Premier port à scanner
unsigned short port_fin;			// Dernier port à scanner
unsigned short port_en_cours;		// Port en cours de scan
unsigned int timeout;				// Temps d'attente maximum en cas de non réponse

LARGE_INTEGER cpu_frequence;
LARGE_INTEGER temps_de_reponse1;
LARGE_INTEGER temps_de_reponse2;

int main (int argc, char* argv[])
	{
	initiation_des_variables();
	gestion_des_arguments(argc,argv);
	printf("\n");
	for (port_en_cours=port_depart;port_en_cours<=port_fin;port_en_cours++)
		{
		entete_tcp.port_destination=htons(port_en_cours);
		Changement_aleatoire_des_valeurs();
		envoi_de_la_trame();
		reception_de_la_trame();
		}
	printf("\n");
	return(1);
	}

void initiation_des_variables(void)
	{
	structure_ip_local reception_des_ip_locales;

	// ********************************************************
	// Affichage de la banniere
	// ********************************************************
	printf("\nScanTcp -  Scan the Tcp ports - Version 1.0.3.8");
	printf("\nCreate on October 01, 2004, Last compilation on October 01, 2004");
	printf("\nCreated by _sebf@frameip.com - http://www.frameip.com");
	printf("\n");

	// ********************************************************
	// Initiation diverse
	// ********************************************************
	srand(GetTickCount());			// Initialise le Random
	QueryPerformanceFrequency((LARGE_INTEGER *)&cpu_frequence); // Initialisation de la fréquence pour le compteur
	timeout=1;
		
	// ********************************************************
	// Initiation des arguments
	// ********************************************************
	strcpy(ip_destination_initiale,"www.linux.org");
	port_source_aleatoire=TRUE;
	port_depart=135;
	port_fin=139;

	// ********************************************************
	// Initialisation des data
	// ********************************************************
	strcpy(data_a_envoyer,"- My Email is : SebF@FrameIP.com - The web site is  : www.frameip.com ");
	longueur_de_data_a_envoyer=strlen(data_a_envoyer);

	// ********************************************************
	// Initialisation de l'entete TCP
	// ********************************************************
	entete_tcp.port_source=0;			// Il est initialisé plutard
	entete_tcp.port_destination=htons(80);
	entete_tcp.sequence=0;				// Il est initialisé plutard
	entete_tcp.accuse=0;
	entete_tcp.reserved=0;
	entete_tcp.offset=5; // taille de l'entête Tcp
	entete_tcp.flag_fin=0;
	entete_tcp.flag_syn=1;
	entete_tcp.flag_rst=0;
	entete_tcp.flag_psh=0;
	entete_tcp.flag_ack=0;
	entete_tcp.flag_urg=0;
	entete_tcp.reserved2=0;
	entete_tcp.window=htons(16384);		// Valeur relevée dans un Netmon après un "Telnet IP port"
	entete_tcp.checksum=0;
	entete_tcp.pointeur=0;

	// ********************************************************
	// Initialisation de l'entete Ip
	// ********************************************************
	entete_ipv4.ihl=5;
	entete_ipv4.version=4;
	entete_ipv4.tos=0;
	entete_ipv4.length=0;
	entete_ipv4.id=0;					// Il est initialisé plutard
	entete_ipv4.offset=0;
	entete_ipv4.ttl=100;
	entete_ipv4.type=6;
	reception_des_ip_locales=recuperation_ip_local(false);
	strcpy(ip_source_initiale,reception_des_ip_locales.adresse_ip_local[0]);
	entete_ipv4.ip_source=resolution_de_nom(false,ip_source_initiale);
	entete_ipv4.ip_destination=resolution_de_nom(TRUE,ip_destination_initiale);
	}

void gestion_des_arguments(int argc,char* argv[])
	{
	char *caractere_non_convertit;
	int i;

	// ********************************************************
	// Affichage de l'aide
	// ********************************************************
	if ( (argc>1) && (strcmp(argv[1],"-?")==0) || (argc==1) )
		{
		printf("\n");
		printf("\n-?                This help");
		printf("\n-ip_destination   @IP destination                Default value: %s",ip_destination_initiale);
		printf("\n-ip_source        @IP source                     Default value: %s",ip_source_initiale);
		printf("\n-port_source      Port TCP source (0 to random)  Default value: %d",entete_tcp.port_source);
		printf("\n-port1            First Port                     Default value: %d",port_depart);
		printf("\n-port2            Last Port                      Default value: %d",port_fin);
		printf("\n-timeout          Maximum wait (s).              Default value: %d",timeout);
		printf("\n");
		printf("\nsample :\nscantcp -ip_destination www.google.fr -port1 79 -port2 81");
		printf("\n\n");
		exit(0);
		}

	// ********************************************************
	// Récupération des arguments
	// ********************************************************
	for (i=1;i<argc;i=i+1)
		{
		if (strcmp(strlwr(argv[i]),"-ip_source")==0)
			entete_ipv4.ip_source=(unsigned long)resolution_de_nom(FALSE,argv[i+1]);
		if (strcmp(strlwr(argv[i]),"-ip_destination")==0)
			entete_ipv4.ip_destination=(unsigned long)resolution_de_nom(FALSE,argv[i+1]);
		if (strcmp(strlwr(argv[i]),"-port_source")==0)
			if (argv[i+1]==0)
				port_source_aleatoire=TRUE;
			else
				{
				port_source_aleatoire=FALSE;
				entete_tcp.port_source=htons((unsigned short)strtod(argv[i+1],&caractere_non_convertit));
				}
		if (strcmp(strlwr(argv[i]),"-port1")==0)
			port_depart=(unsigned short)strtod(argv[i+1],&caractere_non_convertit);
		if (strcmp(strlwr(argv[i]),"-port2")==0)
			port_fin=(unsigned short)strtod(argv[i+1],&caractere_non_convertit);
		if (strcmp(strlwr(argv[i]),"-port_destination")==0)
			entete_tcp.port_destination=htons((unsigned short)strtod(argv[i+1],&caractere_non_convertit));
		if (strcmp(strlwr(argv[i]),"-timeout")==0)
			timeout=(unsigned int)strtod(argv[i+1],&caractere_non_convertit);
		}
	}

void Changement_aleatoire_des_valeurs()
	{
	// ********************************************************
	// Random de l'ID IP
	// ********************************************************
	entete_ipv4.id=(unsigned short)(rand()%65536);					// Tire entre 0 et 65535
                 
	// ********************************************************
	// Random du Port Source
	// ************************************************* *******
	if (port_source_aleatoire==TRUE)
		entete_tcp.port_source=(unsigned short)(rand()%64511+1+1024);	// Tire entre 1025 et 65535

	// ********************************************************
	// Random de la séquence TCP
	// ********************************************************
	entete_tcp.sequence=(unsigned short)(rand()%65536);				// Tire entre 0 et 65535
	}

void envoi_de_la_trame(void)
	{
	WSADATA initialisation_win32;
	SOCKADDR_IN information_sur_la_destination;
	SOCKET id_de_la_socket_envoi;
	int tampon;
	int error;

	// ********************************************************
	// Initialisation de la Socket
	// ********************************************************
	error=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
	if (error!=0)
		sortie_avec_erreur(1);
	id_de_la_socket_envoi=socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
	if (id_de_la_socket_envoi==INVALID_SOCKET)
		sortie_avec_erreur(2);

	// ********************************************************
	// Activation de l'envoi de l'entete IP
	// ********************************************************
	tampon=1;
	error=setsockopt(id_de_la_socket_envoi,IPPROTO_IP,IP_HDRINCL,(char *)&tampon,sizeof(tampon));
	if (error!=0)
		sortie_avec_erreur(3);

	// ********************************************************
	// Calcul du checksum TCP
	// ********************************************************
	entete_tcp.checksum=calcul_du_checksum_tcp(FALSE,entete_ipv4.ip_source,entete_ipv4.ip_destination,entete_tcp,data_a_envoyer);

	// ********************************************************
	// Préparation de la trame à envoyé
	// ********************************************************
	memcpy(trame_a_envoyer,(unsigned short *)&entete_ipv4,sizeof(struct ipv4));
	memcpy(trame_a_envoyer+sizeof(struct ipv4),(unsigned short *)&entete_tcp,sizeof(struct tcp));
	memcpy(trame_a_envoyer+sizeof(struct ipv4)+sizeof(struct tcp),data_a_envoyer,longueur_de_data_a_envoyer);

	// ********************************************************
	// Paramètre nécessaire au sendto
	// ********************************************************
	information_sur_la_destination.sin_family=AF_INET;
	information_sur_la_destination.sin_addr.s_addr=entete_ipv4.ip_destination;

	// ********************************************************
	// Démarrage du chrono
	// ********************************************************
	QueryPerformanceCounter((LARGE_INTEGER *) &temps_de_reponse1);

	// ********************************************************
	// Envoi de la trame
	// ********************************************************
	nombre_de_caractere_emis=sendto(id_de_la_socket_envoi,trame_a_envoyer,sizeof(struct ipv4)+sizeof(struct tcp)+longueur_de_data_a_envoyer,0,(struct sockaddr*)&information_sur_la_destination,sizeof(information_sur_la_destination));
	if (nombre_de_caractere_emis<1)
		sortie_avec_erreur(4);
	
	// ********************************************************
	// Fermeture de la socket correspondant à la commande socket()
	// ********************************************************
	closesocket(id_de_la_socket_envoi);

	// ********************************************************
	// quite propement le winsock ouvert avec la commande WSAStartup
	// ********************************************************
	WSACleanup(); //  (A appeller autant de fois qu'il a été ouvert)
	}

void reception_de_la_trame()
	{
	WSADATA initialisation_win32;
	SOCKADDR_IN information_sur_la_source;
	SOCKET id_de_la_socket_ecoute;
	DWORD  lpcbBytesReturned;
	int tampon; // Variable temporaire
	int error; // Permet de récuupérer le numéro d'erreur des fonctions
	int duree_de_la_boucle;
	unsigned int sortie_de_la_boucle; // 0="ne pas sortir" 1="sortir avec port ouvert" 2="sortir avec port fermé"
	int nombre_de_caractere_recu;
	char buffer_de_reception[65535];
	double temps_de_reponse; // Variable indiquant le temps écoulé entre l'envoi et la reception

	// ********************************************************
	// Initialisation de la Socket
	// ********************************************************
	error=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
	if (error!=0)
		sortie_avec_erreur(1);
	id_de_la_socket_ecoute=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
	if (id_de_la_socket_ecoute==INVALID_SOCKET)
		sortie_avec_erreur(5);

	// ********************************************************
	// Lien entre la socket et l'IP d'écoute
	// ********************************************************
	information_sur_la_source.sin_family=AF_INET;
	information_sur_la_source.sin_addr.S_un.S_addr=entete_ipv4.ip_source;
	error=bind(id_de_la_socket_ecoute,(SOCKADDR *)&information_sur_la_source, sizeof(information_sur_la_source));
	if (error==SOCKET_ERROR)
		sortie_avec_erreur(6);

	// ********************************************************
	// Choix du mode de la socket
	// ********************************************************
	tampon=1;
	error=WSAIoctl(id_de_la_socket_ecoute,SIO_RCVALL,&tampon,sizeof(tampon),NULL,0,&lpcbBytesReturned,NULL,NULL);
	if (error==SOCKET_ERROR)
		sortie_avec_erreur(7);

	// ********************************************************
	// Passage de la socket en mode non bloquant
	// ********************************************************
	tampon=1;
	error=setsockopt(id_de_la_socket_ecoute,SOL_SOCKET,SO_RCVTIMEO,(char *)&tampon,sizeof(tampon)); // La commande recv attend 1 (on) ms avant de rendre la main
	if (error!=0)
		sortie_avec_erreur(8);

	// ********************************************************
	// Création de la boucle d'attente
	// ********************************************************
	QueryPerformanceFrequency((LARGE_INTEGER *)&cpu_frequence);
	duree_de_la_boucle=GetTickCount();
	sortie_de_la_boucle=0;
	while (sortie_de_la_boucle==0)
		{
		nombre_de_caractere_recu=recv(id_de_la_socket_ecoute,buffer_de_reception,65535,0);
		if (GetTickCount()-duree_de_la_boucle>(unsigned)(timeout*1000))
			sortie_de_la_boucle=2;
		else if (nombre_de_caractere_recu!=-1)
			{
			// ********************************************************
			// Extraction et  des valeurs recues
			// ********************************************************
			entete_ipv4_reception=(struct ipv4 *)buffer_de_reception;
			entete_tcp_reception=(struct tcp *)(buffer_de_reception+20);
						
			// ********************************************************
			// Validation de la conformité de la reception
			// ********************************************************
			if (entete_ipv4_reception->ip_source==entete_ipv4.ip_destination)
			if (entete_ipv4_reception->ip_destination==entete_ipv4.ip_source)
			if (entete_ipv4_reception->type==6)
			if (entete_tcp_reception->port_source==entete_tcp.port_destination)
			if (entete_tcp_reception->port_destination==entete_tcp.port_source)
			if (entete_tcp_reception->flag_syn==1)
			if (entete_tcp_reception->flag_ack==1)
				sortie_de_la_boucle=1;
			}
		}

	// ********************************************************
	// Affichage du résultat
	// ********************************************************
	if (sortie_de_la_boucle==1)
		printf("Le port Tcp %d pour l'Ip %s est ouvert.\n",port_en_cours,convertion_ip(entete_ipv4.ip_destination));
	else
		printf("Le port Tcp %d pour l'Ip %s est ferme.\n",port_en_cours,convertion_ip(entete_ipv4.ip_destination));
	}

void sortie_avec_erreur(int error)
	{
	if (error==1)
		printf("\nSorry, I can't initialize WSAStartup - www.frameip.com.");
	if (error==2)
		printf("\nSorry, I can't initialize Socket - www.frameip.com.");
	if (error==3)
		printf("\nSorry, I can't initialize SetSockOpt - www.frameip.com.");
	if (error==4)
		printf("\nSorry, I can't send the frame - www.frameip.com.");
	if (error==5)
		printf("\nSorry, I can't initialize the Socket to listen the answer - www.frameip.com.");
	if (error==6)
		printf("\nSorry, I can't bind the Socket - www.frameip.com.");
	if (error==7)
		printf("\nSorry, I can't set the Socket's mode - www.frameip.com.");
	if (error==8)
		printf("\nSorry, I can't initialize SetSockOpt - www.frameip.com.");

	printf("\nError code      : %d",error);
	printf("\nWSAGetLastError : %d",WSAGetLastError());
	printf("\n\n");
	exit(0);
	}

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.