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

Conversation

phillip-stephens
Copy link
Contributor

The IP packet header field IP Identification field was hardcoded to 54321.

This PR uses the aes fast random number generator to generate a unique IP ID for each packet. This should be faster than reading from /dev/urandom if we used random.c.

Video showing a packet capture from Wireshark and the unique IDs:

Screen.Recording.2024-03-01.at.11.25.59.AM.mov

@@ -64,7 +65,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, aesrand_t *aes,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to make sure here that we're not passing in the same entropy that's passed in from the uint32_t *validation parameter. It might make sense to pass in IPID directly too since that's more tightly typed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair, I've moved to only generating the ip_id in send.c here and passing it directly in.

Also, I changed to using random_bytes which reads from /dev/urandom, should be completely distinct from any other RNG in our code.

@phillip-stephens phillip-stephens marked this pull request as ready for review March 1, 2024 20:24
src/send.c Outdated Show resolved Hide resolved
Copy link
Member

@zakird zakird left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, can you just swap from u_short to uint32_t please?

src/send.c Outdated
@@ -376,6 +381,7 @@ 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,
(uint16_t)aesrand_getword(aes_rand_gen),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does an additional extra full blown AES block encryption for every single packet, in order to produce 16 bits of IP ID. In my quick perf testing on a 10GbE box with 8 cores and netmap, this change reduces send rate from 10.44 Mp/s to 8.80 Mp/s.

Would a more lightweight PRNG make more sense here, think cyclic group like for target permutation, instead of the AES-based PRNG?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that sounds like a significant perf. hit, thanks for running those numbers! Let me look at grabbing the last 16 bits from permutation like @zakird mentioned, I'll double-check no probe-module uses those.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw, 46fac21 resolves the perf hit for me.

src/send.c Outdated Show resolved Hide resolved
Copy link
Member

@zakird zakird left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New approach looks reasonable, but looks like there's some leftover code that needs to be removed.

@phillip-stephens
Copy link
Contributor Author

@zakird Yep, sorry about that, forgot to cleanup after switching the approach. Re-requesting review.

@zakird zakird merged commit b0190cc into main Mar 4, 2024
7 checks passed
@zakird zakird deleted the phillip/randomize-ip-id branch March 4, 2024 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants