Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent fingerprinting ZMap by randomizing the IP ID #798

Merged
merged 14 commits into from Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/probe-modules/module_tcp_cisco_backdoor.c
Expand Up @@ -64,7 +64,7 @@ static int synscan_init_perthread(void *buf, macaddr_t *src, macaddr_t *gw,

static int synscan_make_packet(void *buf, UNUSED size_t *buf_len,
ipaddr_n_t src_ip, ipaddr_n_t dst_ip, uint8_t ttl,
uint32_t *validation, int probe_num,
uint32_t *validation, int probe_num, uint16_t ip_id,
UNUSED void *arg)
{
struct ether_header *eth_header = (struct ether_header *)buf;
Expand All @@ -85,6 +85,7 @@ static int synscan_make_packet(void *buf, UNUSED size_t *buf_len,
ip_header->ip_dst.s_addr, tcp_header);

ip_header->ip_sum = 0;
ip_header->ip_id = ip_id;
ip_header->ip_sum = zmap_ip_checksum((unsigned short *)ip_header);

return EXIT_SUCCESS;
Expand Down
4 changes: 3 additions & 1 deletion src/probe_modules/module_bacnet.c
Expand Up @@ -76,7 +76,8 @@ int bacnet_init_perthread(void *buf, macaddr_t *src, macaddr_t *gw, void **arg)

int bacnet_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
ipaddr_n_t dst_ip, port_n_t dport, uint8_t ttl,
uint32_t *validation, int probe_num, UNUSED void *arg)
uint32_t *validation, int probe_num, uint16_t ip_id,
UNUSED void *arg)
{
struct ether_header *eth_header = (struct ether_header *)buf;
struct ip *ip_header = (struct ip *)(&eth_header[1]);
Expand All @@ -87,6 +88,7 @@ int bacnet_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
ip_header->ip_dst.s_addr = dst_ip;
ip_header->ip_ttl = ttl;
ip_header->ip_sum = 0;
ip_header->ip_id = ip_id;

udp_header->uh_sport =
htons(get_src_port(num_ports, probe_num, validation));
Expand Down
4 changes: 3 additions & 1 deletion src/probe_modules/module_dns.c
Expand Up @@ -776,7 +776,8 @@ int get_dns_question_index_by_probe_num(int probe_num) {

int dns_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
ipaddr_n_t dst_ip, port_n_t dport, uint8_t ttl,
uint32_t *validation, int probe_num, UNUSED void *arg)
uint32_t *validation, int probe_num,
uint16_t ip_id, UNUSED void *arg)
{
struct ether_header *eth_header = (struct ether_header *)buf;
struct ip *ip_header = (struct ip *)(&eth_header[1]);
Expand Down Expand Up @@ -808,6 +809,7 @@ int dns_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
ip_header->ip_src.s_addr = src_ip;
ip_header->ip_dst.s_addr = dst_ip;
ip_header->ip_ttl = ttl;
ip_header->ip_id = ip_id;
// Above we wanted to look up the dns question index (so we could send 2 probes for the same DNS query)
// Here we want the port to be unique regardless of if this is the 2nd probe to the same DNS query so using
// probe_num itself to set the unique UDP source port.
Expand Down
5 changes: 3 additions & 2 deletions src/probe_modules/module_icmp_echo.c
Expand Up @@ -163,7 +163,8 @@ static int icmp_echo_init_perthread(void *buf, macaddr_t *src, macaddr_t *gw,
static int icmp_echo_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
ipaddr_n_t dst_ip, UNUSED port_n_t dst_port,
uint8_t ttl, uint32_t *validation,
UNUSED int probe_num, UNUSED void *arg)
UNUSED int probe_num, uint16_t ip_id,
UNUSED void *arg)
{
struct ether_header *eth_header = (struct ether_header *)buf;
struct ip *ip_header = (struct ip *)(&eth_header[1]);
Expand All @@ -186,7 +187,7 @@ static int icmp_echo_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
// Update the IP and UDP headers to match the new payload length
size_t ip_len = sizeof(struct ip) + ICMP_MINLEN + icmp_payload_len;
ip_header->ip_len = htons(ip_len);

ip_header->ip_id = ip_id;
ip_header->ip_sum = 0;
ip_header->ip_sum = zmap_ip_checksum((unsigned short *)ip_header);
*buf_len = ip_len + sizeof(struct ether_header);
Expand Down
4 changes: 3 additions & 1 deletion src/probe_modules/module_icmp_echo_time.c
Expand Up @@ -55,7 +55,8 @@ static int icmp_echo_init_perthread(void *buf, macaddr_t *src, macaddr_t *gw,
static int icmp_echo_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
ipaddr_n_t dst_ip, UNUSED port_n_t dport,
uint8_t ttl, uint32_t *validation,
UNUSED int probe_num, UNUSED void *arg)
UNUSED int probe_num, uint16_t ip_id,
UNUSED void *arg)
{
struct ether_header *eth_header = (struct ether_header *)buf;
struct ip *ip_header = (struct ip *)(&eth_header[1]);
Expand Down Expand Up @@ -88,6 +89,7 @@ static int icmp_echo_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
sizeof(struct icmp_payload_for_rtt);
ip_header->ip_len = htons(ip_len);

ip_header->ip_id = ip_id;
ip_header->ip_sum = 0;
ip_header->ip_sum = zmap_ip_checksum((unsigned short *)ip_header);

Expand Down
3 changes: 2 additions & 1 deletion src/probe_modules/module_tcp_synackscan.c
Expand Up @@ -54,7 +54,7 @@ static int synackscan_make_packet(void *buf, UNUSED size_t *buf_len,
ipaddr_n_t src_ip, ipaddr_n_t dst_ip,
port_n_t dport, uint8_t ttl,
uint32_t *validation, int probe_num,
UNUSED void *arg)
uint16_t ip_id, UNUSED void *arg)
{
struct ether_header *eth_header = (struct ether_header *)buf;
struct ip *ip_header = (struct ip *)(&eth_header[1]);
Expand All @@ -66,6 +66,7 @@ static int synackscan_make_packet(void *buf, UNUSED size_t *buf_len,
ip_header->ip_src.s_addr = src_ip;
ip_header->ip_dst.s_addr = dst_ip;
ip_header->ip_ttl = ttl;
ip_header->ip_id = ip_id;

tcp_header->th_sport =
htons(get_src_port(num_ports, probe_num, validation));
Expand Down
4 changes: 3 additions & 1 deletion src/probe_modules/module_tcp_synscan.c
Expand Up @@ -92,7 +92,7 @@ static int synscan_init_perthread(void *buf, macaddr_t *src, macaddr_t *gw,
static int synscan_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
ipaddr_n_t dst_ip, port_n_t dport, uint8_t ttl,
uint32_t *validation, int probe_num,
UNUSED void *arg)
uint16_t ip_id, UNUSED void *arg)
{
struct ether_header *eth_header = (struct ether_header *)buf;
struct ip *ip_header = (struct ip *)(&eth_header[1]);
Expand All @@ -112,6 +112,8 @@ static int synscan_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
tcp_header->th_sum = tcp_checksum(zmap_tcp_synscan_tcp_header_len,
ip_header->ip_src.s_addr,
ip_header->ip_dst.s_addr, tcp_header);

ip_header->ip_id = ip_id;
// checksum value must be zero when calculating packet's checksum
ip_header->ip_sum = 0;
ip_header->ip_sum = zmap_ip_checksum((unsigned short *)ip_header);
Expand Down
8 changes: 6 additions & 2 deletions src/probe_modules/module_udp.c
Expand Up @@ -270,7 +270,8 @@ int udp_init_perthread(void *buf, macaddr_t *src, macaddr_t *gw, void **arg_ptr)

int udp_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
ipaddr_n_t dst_ip, port_n_t dport, uint8_t ttl,
uint32_t *validation, int probe_num, UNUSED void *arg)
uint32_t *validation, int probe_num, uint16_t ip_id,
UNUSED void *arg)
{
struct ether_header *eth_header = (struct ether_header *)buf;
struct ip *ip_header = (struct ip *)(&eth_header[1]);
Expand All @@ -285,6 +286,7 @@ int udp_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
htons(get_src_port(num_ports, probe_num, validation));
udp_header->uh_dport = dport;

ip_header->ip_id = ip_id;
ip_header->ip_sum = 0;
ip_header->ip_sum = zmap_ip_checksum((unsigned short *)ip_header);

Expand All @@ -295,7 +297,8 @@ int udp_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,

int udp_make_templated_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
ipaddr_n_t dst_ip, port_n_t dport, uint8_t ttl,
uint32_t *validation, int probe_num, void *arg)
uint32_t *validation, int probe_num, uint16_t ip_id,
void *arg)
{
struct ether_header *eth_header = (struct ether_header *)buf;
struct ip *ip_header = (struct ip *)(&eth_header[1]);
Expand Down Expand Up @@ -334,6 +337,7 @@ int udp_make_templated_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
udp_header->uh_ulen = ntohs(sizeof(struct udphdr) + payload_len);

ip_header->ip_sum = 0;
ip_header->ip_id = ip_id;
ip_header->ip_sum = zmap_ip_checksum((unsigned short *)ip_header);

// Recalculate the total length of the packet
Expand Down
6 changes: 4 additions & 2 deletions src/probe_modules/module_udp.h
Expand Up @@ -64,10 +64,12 @@ void udp_print_packet(FILE *fp, void *packet);

int udp_make_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
ipaddr_n_t dst_ip, port_n_t dport, uint8_t ttl,
uint32_t *validation, int probe_num, void *arg);
uint32_t *validation, int probe_num, uint16_t ip_id,
void *arg);
int udp_make_templated_packet(void *buf, size_t *buf_len, ipaddr_n_t src_ip,
ipaddr_n_t dst_ip, port_n_t dport, uint8_t ttl,
uint32_t *validation, int probe_num, void *arg);
uint32_t *validation, int probe_num, uint16_t ip_id,
void *arg);

int udp_do_validate_packet(const struct ip *ip_hdr, uint32_t len,
UNUSED uint32_t *src_ip, uint32_t *validation,
Expand Down
2 changes: 1 addition & 1 deletion src/probe_modules/probe_modules.h
Expand Up @@ -52,7 +52,7 @@ typedef int (*probe_make_packet_cb)(void *packetbuf, size_t *buf_len,
ipaddr_n_t src_ip, ipaddr_n_t dst_ip,
port_n_t dst_port, uint8_t ttl,
uint32_t *validation, int probe_num,
void *arg);
uint16_t ip_id, void *arg);

typedef void (*probe_print_packet_cb)(FILE *, void *packetbuf);

Expand Down
6 changes: 4 additions & 2 deletions src/send.c
Expand Up @@ -366,8 +366,8 @@ int send_run(sock_t st, shard_t *s)
for (int i = 0; i < zconf.packet_streams; i++) {
count++;
uint32_t src_ip = get_src_ip(current_ip, i);
uint32_t validation[VALIDATE_BYTES /
sizeof(uint32_t)];
uint8_t size_of_validation = VALIDATE_BYTES / sizeof(uint32_t);
uint32_t validation[size_of_validation];
validate_gen(src_ip, current_ip,
htons(current_port),
(uint8_t *)validation);
Expand All @@ -376,6 +376,8 @@ int send_run(sock_t st, shard_t *s)
zconf.probe_module->make_packet(
buf, &length, src_ip, current_ip,
htons(current_port), ttl, validation, i,
// Grab last 2 bytes of validation for ip_id
(uint16_t)(validation[size_of_validation - 1] & 0xFFFF),
probe_data);
if (length > MAX_PACKET_SIZE) {
log_fatal(
Expand Down