Fake an ethernet header rather than expose vulns
There is probably a slight performance hit, but if you're scanning with ZMap through a VPN, you probably don't care THAT much about performance anyway...(also we only add a memcpy for all accepted packets)
This commit is contained in:
parent
2972bbefdc
commit
c185f6b0a4
38
src/recv.c
38
src/recv.c
@ -59,6 +59,8 @@ static inline void set_ip(uint32_t ip)
|
|||||||
ip_seen[ip >> 6] |= (uint64_t)1 << (ip & 0x3F);
|
ip_seen[ip >> 6] |= (uint64_t)1 << (ip & 0x3F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u_char fake_eth_hdr[65535];
|
||||||
|
|
||||||
void packet_cb(u_char __attribute__((__unused__)) *user,
|
void packet_cb(u_char __attribute__((__unused__)) *user,
|
||||||
const struct pcap_pkthdr *p, const u_char *bytes)
|
const struct pcap_pkthdr *p, const u_char *bytes)
|
||||||
{
|
{
|
||||||
@ -97,18 +99,19 @@ void packet_cb(u_char __attribute__((__unused__)) *user,
|
|||||||
|
|
||||||
fieldset_t *fs = fs_new_fieldset();
|
fieldset_t *fs = fs_new_fieldset();
|
||||||
fs_add_ip_fields(fs, ip_hdr);
|
fs_add_ip_fields(fs, ip_hdr);
|
||||||
// HACK !!! FIXME !!! TODO !!! BAD BAD BAD
|
// HACK:
|
||||||
// probe modules for whatever reason expect the full ethernet frame
|
// probe modules (for whatever reason) expect the full ethernet frame
|
||||||
// in process_packet. For VPN, we only get back an IP frame
|
// in process_packet. For VPN, we only get back an IP frame.
|
||||||
// so we COULD malloc a fake ethernet frame and copy over this payload
|
// Here, we fake an ethernet frame (which is initialized to
|
||||||
// but waaaaaaahhhh performanceeee.
|
// have ETH_P_IP proto and 00s for dest/src).
|
||||||
// so instead, we will ASSUME (!) that the probe module will only care about
|
if (zconf.send_ip_pkts) {
|
||||||
// the IP header, and do ip_hdr = &packet[sizeof(struct ethhdr)] the first thing
|
if (buflen > sizeof(fake_eth_hdr)) {
|
||||||
// in their function (tcp, icmp and udp probe modules all do).
|
buflen = sizeof(fake_eth_hdr);
|
||||||
//
|
}
|
||||||
// !!!IF YOUR PROBE MODULE USES THE ETH PACKET, AND YOU USE THE --vpn OPTION, YOU _WILL_ BE OWNED!!!!
|
memcpy(&fake_eth_hdr[sizeof(struct ethhdr)], bytes, buflen);
|
||||||
//
|
bytes = fake_eth_hdr;
|
||||||
zconf.probe_module->process_packet(bytes - (zconf.send_ip_pkts * sizeof(struct ethhdr)), buflen + (zconf.send_ip_pkts * sizeof(struct ethhdr)), fs);
|
}
|
||||||
|
zconf.probe_module->process_packet(bytes, buflen, fs);
|
||||||
fs_add_system_fields(fs, is_repeat, zsend.complete);
|
fs_add_system_fields(fs, is_repeat, zsend.complete);
|
||||||
int success_index = zconf.fsconf.success_index;
|
int success_index = zconf.fsconf.success_index;
|
||||||
assert(success_index < fs->len);
|
assert(success_index < fs->len);
|
||||||
@ -133,18 +136,18 @@ void packet_cb(u_char __attribute__((__unused__)) *user,
|
|||||||
// we need to translate the data provided by the probe module
|
// we need to translate the data provided by the probe module
|
||||||
// into a fieldset that can be used by the output module
|
// into a fieldset that can be used by the output module
|
||||||
if (!is_success && zconf.filter_unsuccessful) {
|
if (!is_success && zconf.filter_unsuccessful) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (is_repeat && zconf.filter_duplicates) {
|
if (is_repeat && zconf.filter_duplicates) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
o = translate_fieldset(fs, &zconf.fsconf.translation);
|
o = translate_fieldset(fs, &zconf.fsconf.translation);
|
||||||
if (zconf.output_module && zconf.output_module->process_ip) {
|
if (zconf.output_module && zconf.output_module->process_ip) {
|
||||||
zconf.output_module->process_ip(o);
|
zconf.output_module->process_ip(o);
|
||||||
}
|
}
|
||||||
cleanup:
|
cleanup:
|
||||||
fs_free(fs);
|
fs_free(fs);
|
||||||
free(o);
|
free(o);
|
||||||
if (zconf.output_module && zconf.output_module->update
|
if (zconf.output_module && zconf.output_module->update
|
||||||
&& !(zrecv.success_unique % zconf.output_module->update_interval)) {
|
&& !(zrecv.success_unique % zconf.output_module->update_interval)) {
|
||||||
zconf.output_module->update(&zconf, &zsend, &zrecv);
|
zconf.output_module->update(&zconf, &zsend, &zrecv);
|
||||||
@ -194,6 +197,11 @@ int recv_run(pthread_mutex_t *recv_ready_mutex)
|
|||||||
log_fatal("recv", "couldn't install filter");
|
log_fatal("recv", "couldn't install filter");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (zconf.send_ip_pkts) {
|
||||||
|
struct ethhdr *eth = (struct ethhdr *)fake_eth_hdr;
|
||||||
|
memset(fake_eth_hdr, 0, sizeof(fake_eth_hdr));
|
||||||
|
eth->h_proto = htons(ETH_P_IP);
|
||||||
|
}
|
||||||
log_debug("recv", "receiver ready");
|
log_debug("recv", "receiver ready");
|
||||||
if (zconf.filter_duplicates) {
|
if (zconf.filter_duplicates) {
|
||||||
log_debug("recv", "duplicate responses will be excluded from output");
|
log_debug("recv", "duplicate responses will be excluded from output");
|
||||||
|
Loading…
Reference in New Issue
Block a user