Quando si usano socket per inviare pacchetti, si ha la possibilità di controllare solo alcuni campi dell'header. Per esempio, se si vuole inviare un pacchetto IP, possiamo scegliere l'IP di destinazione, ma non quello del mittente. Quando il pacchetto viene spedito esso viene riempito in automatico dal computer che piazza nel source address l'indirizzo della macchina da cui il pacchetto sta partendo.
In molti attacchi di rete i pacchetti inviati alla vittima gli header sono costruiti con informazioni false, non realistiche, ma che abbiamo senso per le informazioni presenti negli header.
Ci sono diversi tool che consentono di fare packet spoofing, per esempio Netwox e Scapy.
Come abbiamo detto, normalmente non è possibile, attraverso l'uso di socket normali controllare alcuni campi di intestazione interessanti.
Esistono però, nella maggior parte dei sistemi operativi, alcune socket speciali chiamate raw socket.
Le raw socket consentono di avere maggior controllo sui pacchetti, tutto ciò che serve è costruire l'intero pacchetto in un buffer, includere le intestazioni IP e tutte le sue intestazioni successive, poi darlo alla socket per inviarlo. Usare questo tipo di socket è come dire al sistema operativo "lasciami da solo" e riempire i campi dei pacchetti da noi, anziché lasciarlo fare a lui.
Ci sono due passi nel packet spoofing:
/*************************************************************
Il pacchetto IP è dato, vediamo come spedirlo.
**************************************************************/
void send_raw_ip__packet(struct ipheader* ip){
struct sockaddr_in dest_info;
int enable = 1 ;
// Step 1: Create a raw network socket.
int sock = socket(AF _ INET, SOCK_RAW, IPPROTO_RAW) ;
// Step 2: Set socket option.
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &enable, sizeof(enable));
// Step 3: Provide needed information about destination.
dest_info.sin_family = AF_INET;
dest_info.sin_addr = ip->iph_destip;
// Step 4: Send the packet out.
sendto(sock, ip, ntohs(ip->iph_len), 0, (struct sockaddr *)&dest_info, sizeof(dest_info));
close(sock);
C
Prima di inviare un pacchetto falsificato (spoofed) usando una raw socket, abbiamo bisogno di creare l'intero pacchetto. Costruire il pacchetto significa riempire un buffer con le informazioni per l'header e per il payload. Con l'esempio seguente vediamo come costruire un pacchetto ICMP che fa una richiesta ECHO con un indirizzo IP falso.
#include <stdio.h>
#include <string.h>
#inclue <sys/socket.h>
#include <netinet/ip.h>
/* ICMP Header */
struct icmpheader {
unsigned char icmp_type; // ICMP message type
unsigned char icmp_code; // Error code
unsigned short int icmp_chksum; // Checksum for ICMP header and data
unsigned short int icmp_id; // Used for identifying request
unsigned short int icmp_seq; // Sequence number
}
/* IP Header */
struct ipheader
unsigned char iph_ihl:4, // IP header length
iph_ver:4; // IP version
unsigned char iph_tos; // Type of service
unsigned short int iph_len; // IP Packet length (data + header)
unsigned short int iph_ident; // Identification
unsigned short int iph_flah:3, // Fragmentation flags
iph_offset:13; //Flags offset
unsigned char iph_ttl; // Time-To-Live
unsigned char iph_protocol; // Protocol type
unsigned short int iph_chksum; // IP datagram checksum
struct in_addr iph_sourceip; // Source IP address
struct in_add ip_destip; // Destination IP addres
};
unsigend short in_cksum(unsigend short *buf, int length);
void send_raw_ip_packet(struct ipheader* ip);
int main() {
char buffer[1500];
memset(buffer, 0, 1500);
/* Step 1: fill in the ICMP header */
struct icmpheader* icmp = (struct icmpheader *)(buffer + sizeof(struct ipheader));
icmp->icmp_type = 8; // ICMP type: 8 is request, 0 is reply
// Calculate the checksum for integrity
icmp->icmp_chksum = 0;
icmp->icmp_chksum = in_cksum((unsigned short *)icmp, sizeof(struct icmpheader));
/* Step 2: fill in the IP header */
struct ipheader* ip = (struct ipheader *)buffer;
ip->iph_ver = 4;
ip->iph_ihl = 5;
ip->iph_ttl = 20;
ip->iph_sourceip.s_addr = inet_addr("1.2.3.4");
ip->iph_destip.s_addr = inet.addr("10.0.2.69");
ip->iph_protocol = IPPROTO_ICMP;
ip->iph_len = htons(sizeof(struct ipheader) + sizeof(struct icmpheader));
/* Step 3: finally, send the spoofed packet */
send_raw_ip_packet(ip); // Defined in the previous code
return 0;
}
C
Sniffing e spoofing vengono spesso usati in combinazione:
Il DNS spoofing consisnte nel manipolare e/o falsificare le risposte di un DNS al fine di indirizzare gli utenti verso siti web fraudolenti, invece che su quelli originali.
Con questa tecnica, un'attaccante intercetta la query di un utente diretta ad un server DNS, l'attaccante la intercetta e invia una risposta DNS falsificata prima che il server DNS legittimo risponda con quella corretta. L'attacco può sopraggiungere anche manipolando, dal sistema target, i DNS a cui si deve rivolgere una certa macchina, inserendo gli indirizzi di DNS server che l'attaccante può controllare, facendo sì che ogni richiesta giunga direttamente all'attaccante.
Il website spoofing è una tecnica utilizzata da persone malintenzionate per creare siti web falsi che sembrano essere legittimi col fine di ingrannare l'utente. I siti sono creati per essere molto simili a quelli "noti", come siti web di banche, o di e-commerce. L'obiettivo è portare l'utente a fidarsi di un pagina falsa per rubare i suoi dati personali (username o password del vero sito, o i dati delle carte di credito, o altro ancora.)
Spesso la costruzione di una falsa pagina web è associata all'utilizzi di un URL, simile a quello originale: amazon.com potrebbe essere sostituito con amozon.com.