Fix protocol mismatch when manually specifying v4+v6 --local-addr#679
Conversation
phillip-stephens
left a comment
There was a problem hiding this comment.
This seems overall good and I appreciate the fix! I agree that without this fix and with the CLI invocation you gave, there is a bug and this PR fixes it.
I have a couple of suggestions, I'll just go ahead and make these changes because they're small and then we can get this closed out.
conn.go
Outdated
| if len(filtered) == 0 { | ||
| return localIPs | ||
| } |
There was a problem hiding this comment.
IMO, since this is a filtering function we shouldn't have any "fallback" to the full list if there isn't a local IP that'd work for the target IP type. It should simply filter the list and leave it up to the caller to decide what to do.
| if len(localIPs) != 0 { | ||
| localIP = localIPs[rand.Intn(len(localIPs))] | ||
| candidates := filterLocalAddrsByFamily(localIPs, targetIP) | ||
| localIP = candidates[rand.Intn(len(candidates))] |
There was a problem hiding this comment.
rand.Intn will panic of called with n <= 0. I'd suggest we add a check to be sure the list's size is > 0. (Note - this is really only an issue when combined with my above suggestion, since as you've written it I don't think we'd hit this case)
…ed against a panic in rand.Intn
When
--local-addris configured with a mix of IPv4 and IPv6 addresses (e.g.--local-addr 192.168.1.1,2001:db8::1), SetRandomLocalAddr picks one at random without considering the target's address family. This causes scans to fail intermittently. Whenever the randomly chosen local address doesn't match the target's protocol (e.g. binding an IPv6 source for an IPv4 destination), the OS rejects the connection and your grab attempt fails with{"ip":"2607:f8b0:400a:809::200e","data":{"http":{"status":"connection-timeout","protocol":"http","port":80,"result":{},"timestamp":"2026-02-27T13:38:26-08:00","error":"unable to dial target (2607:f8b0:400a:809::200e) with L4 Dialer: dial context failed: dial tcp: address 10.10.9.92:0: no suitable address found"}}}How to Test
Run this command a few times with the existing implementation:
It will fail 50% of the time. Then test mine and confirm that it works consistently.
Notes & Caveats
I've tested this patch locally and it works. However I'm not a particularly experienced Go dev and this is my first time looking at the zgrab2 source code, so feedback is welcome and appreciated. In particular, I'm not sure if
filterLocalAddrsByFamily's current return behavior is reasonable or if I should be returning an error.Issue Tracking
N/A