PDA

Visualizza la versione completa : [C] Half open scanning with raw sockets


Sciedi
28-05-2008, 18:40
Volevo creare uno scanner di porte che utilizza la tecnica half open, ovvero che, per verificare se una porta su un dato host č aperta, non compie tutti i passaggi del 3way handshaking del TCP (come avverrebbe utilizzando una connect) ma soltanto i primi 2:

A -> SYN -> B
A <- SYN+ACK <- B

Per farlo sto utilizzando le raw socket ma sono uno scarsone e quindi ho dei problemi.
La mia struct che rappresenta il pacchetto da inviare č cosė formata:


struct packet
{
struct ip iph;
struct tcphdr tcph;
char c[200];
} tcp_p;

Inizializzo l'indirizzo dell'host a cui inviare il pacchetto in questa maniera:


struct sockaddr_in server_addr;
struct hostent *host;

host = gethostbyname(argv[1]);
server_addr.sin_port = htons((u_short) atoi(argv[2]));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = *((unsigned long *) host->h_addr_list[0]);

Il socket lo creo di tipo RAW e indico al sistema operativo che voglio compilare manualmente l'header ip:


if((sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
{
perror("socket(): ");
exit(-1);
}

if(setsockopt(sd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(int)) == -1)
{
perror("setsockopt(): ");
exit(-1);
}

E la struct tcp_p la riempio cosė:


/* riempimento della struct tcp_p (parte IP)*/

tcp_p.iph.ip_hl = 5;
tcp_p.iph.ip_v = 4;
tcp_p.iph.ip_tos = 0;
tcp_p.iph.ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr));
tcp_p.iph.ip_id = htons(242);
tcp_p.iph.ip_off = htons(IP_DF);
tcp_p.iph.ip_ttl = 255;
tcp_p.iph.ip_p = IPPROTO_TCP;
tcp_p.iph.ip_sum = 0;
tcp_p.iph.ip_src.s_addr = mio_addr.sin_addr.s_addr;
tcp_p.iph.ip_dst.s_addr = server_addr.sin_addr.s_addr;

/* riempimento della struct tcp_p (parte TCP) */

tcp_p.tcph.source = mio_addr.sin_port;
tcp_p.tcph.dest = server_addr.sin_port;
tcp_p.tcph.seq = htonl(0x12345678);
tcp_p.tcph.ack_seq = 0;
tcp_p.tcph.doff = 0;
tcp_p.tcph.syn = 1;
tcp_p.tcph.ack = 0;
tcp_p.tcph.fin = 0;
tcp_p.tcph.window = htons(1024);
tcp_p.tcph.check = 0;
tcp_p.tcph.urg_ptr = 0;

Infine invio il pacchetto utilizzando la sendto (dal momento che da quel che ho capito send e recv non vanno bene con socket di tipo raw):


if(sendto(sd, &tcp_p, sizeof(tcp_p), 0, (struct sockaddr *) & server_addr, sizeof(server_addr)) == -1)
{
perror("sendto");
exit(-1);
}

Peccato che non funzioni! Infatti se provo in seguito all'inzio a mettermi in ascolto sul socket con una recvfrom o con una read sul socket non ricevo nulla... e anche attivando uno sniffer mi rendo conto che non mi arriva nessun pacchetto... quindi presumo che:

1. Sbaglio qualcosa nell'invio e quindi l'host non riceve nessun pacchetto con flag SYN attivo
2. Non ho capito niente del meccaniscmo dell'half open o delle raw sockets

Aiutatemi XD

Loading