📄 spp_arpspoof.c
字号:
AddIPMacEntryToList(ipmel, ipme); mSplitFree(&toks, num_toks); mSplitFree(&macbytes, num_macbytes);#if defined(DEBUG) PrintIPMacEntryList(ipmel);#endif return;}/** * Detect ARP anomalies and overwrite attacks. * * @param p packet to detect anomalies and overwrite attacks on * @param context unused * * @return void function */void DetectARPattacks(Packet *p, void *context){ IPMacEntry *ipme; PROFILE_VARS; /* is the packet valid? */ if (p == NULL) return; /* are the Ethernet and ARP headers present? */ if (p->eh == NULL || p->ah == NULL) return; /* is the ARP protocol type IP and the ARP hardware type Ethernet? */ if ((ntohs(p->ah->ea_hdr.ar_hrd) != 0x0001) || (ntohs(p->ah->ea_hdr.ar_pro) != ETHERNET_TYPE_IP)) return; PREPROC_PROFILE_START(arpPerfStats); switch(ntohs(p->ah->ea_hdr.ar_op)) { case ARPOP_REQUEST: if (check_unicast_arp) { if (memcmp((u_char *)p->eh->ether_dst, (u_char *)bcast, 6) != 0) { SnortEventqAdd(GENERATOR_SPP_ARPSPOOF, ARPSPOOF_UNICAST_ARP_REQUEST, 1, 0, 3, ARPSPOOF_UNICAST_ARP_REQUEST_STR, 0); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "MODNAME: Unicast request\n");); } } else if (memcmp((u_char *)p->eh->ether_src, (u_char *)p->ah->arp_sha, 6) != 0) { SnortEventqAdd(GENERATOR_SPP_ARPSPOOF, ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC, 1, 0, 3, ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC_STR, 0); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "MODNAME: Ethernet/ARP mismatch request\n");); } break; case ARPOP_REPLY: if (memcmp((u_char *)p->eh->ether_src, (u_char *)p->ah->arp_sha, 6) != 0) { SnortEventqAdd(GENERATOR_SPP_ARPSPOOF, ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC, 1, 0, 3, ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC_STR, 0); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "MODNAME: Ethernet/ARP mismatch reply src\n");); } else if (memcmp((u_char *)p->eh->ether_dst, (u_char *)p->ah->arp_tha, 6) != 0) { SnortEventqAdd(GENERATOR_SPP_ARPSPOOF, ARPSPOOF_ETHERFRAME_ARP_MISMATCH_DST, 1, 0, 3, ARPSPOOF_ETHERFRAME_ARP_MISMATCH_DST_STR, 0); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "MODNAME: Ethernet/ARP mismatch reply dst\n");); } break; } PREPROC_PROFILE_END(arpPerfStats); /* return if the overwrite list hasn't been initialized */ if (!check_overwrite) return; /* LookupIPMacEntryByIP() is too slow, will be fixed later */ if ((ipme = LookupIPMacEntryByIP(ipmel, *(u_int32_t *)&p->ah->arp_spa)) == NULL) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "MODNAME: LookupIPMacEntryByIp returned NULL\n");); return; } else { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "MODNAME: LookupIPMacEntryByIP returned %p\n", ipme);); /* If the Ethernet source address or the ARP source hardware address * in p doesn't match the MAC address in ipme, then generate an alert */ if ((memcmp((u_int8_t *)p->eh->ether_src, (u_int8_t *)ipme->mac_addr, 6)) || (memcmp((u_int8_t *)p->ah->arp_sha, (u_int8_t *)ipme->mac_addr, 6))) { SnortEventqAdd(GENERATOR_SPP_ARPSPOOF, ARPSPOOF_ARP_CACHE_OVERWRITE_ATTACK, 1, 0, 3, ARPSPOOF_ARP_CACHE_OVERWRITE_ATTACK_STR, 0); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "MODNAME: Attempted ARP cache overwrite attack\n");); return; } } }/** * Add IP/MAC pair to a linked list. * * @param ip_mac_entry_list pointer to the list structure * @param ip_mac_entry linked list structure node * * @return 0 if the node is added successfully, 1 otherwise */int AddIPMacEntryToList(IPMacEntryList *ip_mac_entry_list, IPMacEntry *ip_mac_entry){ IPMacEntryListNode *newNode; if (ip_mac_entry == NULL || ip_mac_entry_list == NULL) return 1; newNode = (IPMacEntryListNode *)SnortAlloc(sizeof(IPMacEntryListNode)); newNode->ip_mac_entry = ip_mac_entry; newNode->next = NULL; if (ip_mac_entry_list->head == NULL) { ip_mac_entry_list->head = newNode; ip_mac_entry_list->size = 1; } else { ip_mac_entry_list->tail->next = newNode; ip_mac_entry_list->size += 1; } ip_mac_entry_list->tail = newNode; return 0;}/** * Locate a linked list structure node by an IP address. * * @param ip_mac_entry_list pointer to the list structure * @param ipv4_addr IPv4 address as an unsigned 32-bit integer * * @return pointer to a structure node if a match is found, NULL otherwise */IPMacEntry *LookupIPMacEntryByIP(IPMacEntryList *ip_mac_entry_list, u_int32_t ipv4_addr){ IPMacEntryListNode *current;#if defined(DEBUG) struct in_addr ina, inb; char *cha, *chb;#endif if (ip_mac_entry_list == NULL) return NULL; for (current = ip_mac_entry_list->head; current != NULL; current = current->next) {#if defined(DEBUG) ina.s_addr = ipv4_addr; inb.s_addr = current->ip_mac_entry->ipv4_addr; cha = strdup(inet_ntoa(ina)); chb = strdup(inet_ntoa(inb)); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "MODNAME: LookupIPMacEntryByIP() comparing %s to %s\n", cha, chb););#endif if (current->ip_mac_entry->ipv4_addr == ipv4_addr) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "MODNAME: LookupIPMecEntryByIP() match!");); return current->ip_mac_entry; } } return NULL;}/** * Free the linked list of IP/MAC address pairs * * @param ip_mac_entry_list pointer to the list structure * * @return void function */void FreeIPMacEntryList(IPMacEntryList *ip_mac_entry_list){ IPMacEntryListNode *prev; IPMacEntryListNode *current; if (ip_mac_entry_list == NULL) return; current = ip_mac_entry_list->head; while (current != NULL) { if (current->ip_mac_entry != NULL) free(current->ip_mac_entry); prev = current; current = current->next; free(prev); } ip_mac_entry_list->head = NULL; ip_mac_entry_list->size = 0; return;}void ARPspoofCleanExit(int signal, void *unused){ if (ipmel != NULL) { FreeIPMacEntryList(ipmel); free(ipmel); ipmel = NULL; } check_unicast_arp = check_overwrite = 0; return;}#if defined(DEBUG)/** * Print the overwrite list for debugging purposes * * @param ip_mac_entry_list pointer to the list structure * * @return void function */void PrintIPMacEntryList(IPMacEntryList *ip_mac_entry_list){ IPMacEntryListNode *current; int i; struct in_addr in; if (ip_mac_entry_list == NULL) return; current = ip_mac_entry_list->head; printf("Arpspoof IPMacEntry List"); printf(" Size: %i\n", ip_mac_entry_list->size); while (current != NULL) { in.s_addr = current->ip_mac_entry->ipv4_addr; printf("%s -> ", inet_ntoa(in)); for (i = 0; i < 6; i++) { printf("%02x", current->ip_mac_entry->mac_addr[i]); if (i != 5) printf(":"); } printf("\n"); current = current->next; } return;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -