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
Conversation
Need to randomize ID on every packet send. This reverts commit fcc944a.
@@ -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, |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this 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), |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
@zakird Yep, sorry about that, forgot to cleanup after switching the approach. Re-requesting review. |
The IP packet header field
IP Identification
field was hardcoded to54321
.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 usedrandom.c
.Video showing a packet capture from Wireshark and the unique IDs:
Screen.Recording.2024-03-01.at.11.25.59.AM.mov