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:
Eric 2013-08-31 15:57:15 -04:00
parent 2972bbefdc
commit c185f6b0a4

View File

@ -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);
@ -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");