]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1079 in SNORT/snort3 from wlan_arp_spoof to master
authorTom Peters (thopeter) <thopeter@cisco.com>
Fri, 1 Dec 2017 18:17:24 +0000 (13:17 -0500)
committerTom Peters (thopeter) <thopeter@cisco.com>
Fri, 1 Dec 2017 18:17:24 +0000 (13:17 -0500)
Squashed commit of the following:

commit 5af6f5d36aba1867e9176c837dd0248a3b64dfd8
Author: Steven Baigal <sbaigal@cisco.com>
Date:   Tue Nov 21 16:30:42 2017 -0500

    codec: added wlan support for arp_spoof

src/network_inspectors/arp_spoof/arp_spoof.cc
src/protocols/layer.cc
src/protocols/layer.h

index 71469979ec7a783a9e65daa265db8bfa275b577a..973767cf27be1cf10179bc597be64cd473338eff 100644 (file)
@@ -78,6 +78,7 @@
 #include "protocols/arp.h"
 #include "protocols/eth.h"
 #include "protocols/packet.h"
+#include "protocols/wlan.h"
 #include "sfip/sf_ip.h"
 
 #include "arp_module.h"
@@ -171,13 +172,45 @@ void ArpSpoof::eval(Packet* p)
 
     // precondition - what we registered for
     assert(p->type() == PktType::ARP);
+    const uint8_t* dst_mac_addr;
+    const uint8_t* src_mac_addr;
 
-    // 802.11 not supported
-    if ((p->proto_bits & PROTO_BIT__ETH) == 0)
-        return;
+    if (p->proto_bits & PROTO_BIT__ETH)
+    {
+        const eth::EtherHdr* eh = layer::get_eth_layer(p);
+        src_mac_addr = eh->ether_src;
+        dst_mac_addr = eh->ether_dst;
+    }
+    else
+    {
+        const wlan::WifiHdr* wifih = layer::get_wifi_layer(p);
+        if (wifih == nullptr)
+            return;
+
+        if ((wifih->frame_control & WLAN_FLAG_TODS) &&
+             (wifih->frame_control & WLAN_FLAG_FROMDS))
+         {
+             dst_mac_addr = wifih->addr3;
+             src_mac_addr = wifih->addr4;
+         }
+         else if (wifih->frame_control & WLAN_FLAG_TODS)
+         {
+             src_mac_addr = wifih->addr2;
+             dst_mac_addr = wifih->addr3;
+         }
+         else if (wifih->frame_control & WLAN_FLAG_FROMDS)
+         {
+             dst_mac_addr = wifih->addr1;
+             src_mac_addr = wifih->addr3;
+         }
+         else
+         {
+             dst_mac_addr = wifih->addr1;
+             src_mac_addr = wifih->addr2;
+         }
+    }
 
     const arp::EtherARP* ah = layer::get_arp_layer(p);
-    const eth::EtherHdr* eh = layer::get_eth_layer(p);
 
     /* is the ARP protocol type IP and the ARP hardware type Ethernet? */
     if ((ntohs(ah->ea_hdr.ar_hrd) != 0x0001) ||
@@ -189,12 +222,12 @@ void ArpSpoof::eval(Packet* p)
     switch (ntohs(ah->ea_hdr.ar_op))
     {
     case ARPOP_REQUEST:
-        if (memcmp((const u_char*)eh->ether_dst, (const u_char*)bcast, 6) != 0)
+        if (memcmp((const u_char*)dst_mac_addr, (const u_char*)bcast, 6) != 0)
         {
             DetectionEngine::queue_event(GID_ARP_SPOOF, ARPSPOOF_UNICAST_ARP_REQUEST);
             DebugMessage(DEBUG_INSPECTOR, "MODNAME: Unicast request\n");
         }
-        else if (memcmp((const u_char*)eh->ether_src,
+        else if (memcmp((const u_char*)src_mac_addr,
             (const u_char*)ah->arp_sha, 6) != 0)
         {
             DetectionEngine::queue_event(GID_ARP_SPOOF, ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC);
@@ -202,13 +235,13 @@ void ArpSpoof::eval(Packet* p)
         }
         break;
     case ARPOP_REPLY:
-        if (memcmp((const u_char*)eh->ether_src,
+        if (memcmp((const u_char*)src_mac_addr,
             (const u_char*)ah->arp_sha, 6) != 0)
         {
             DetectionEngine::queue_event(GID_ARP_SPOOF, ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC);
             DebugMessage(DEBUG_INSPECTOR, "MODNAME: Ethernet/ARP mismatch reply src\n");
         }
-        else if (memcmp((const u_char*)eh->ether_dst,
+        else if (memcmp((const u_char*)dst_mac_addr,
             (const u_char*)ah->arp_tha, 6) != 0)
         {
             DetectionEngine::queue_event(GID_ARP_SPOOF, ARPSPOOF_ETHERFRAME_ARP_MISMATCH_DST);
@@ -227,7 +260,7 @@ void ArpSpoof::eval(Packet* p)
         DebugFormat(DEBUG_INSPECTOR,
             "MODNAME: LookupIPMacEntryByIP returned %p\n", (void*)ipme);
 
-        auto cmp_ether_src = memcmp(eh->ether_src, ipme->mac_addr, 6);
+        auto cmp_ether_src = memcmp(src_mac_addr, ipme->mac_addr, 6);
         auto cmp_arp_sha = memcmp(ah->arp_sha, ipme->mac_addr, 6);
 
         // If the Ethernet source address or the ARP source hardware address
index 5e0ddb54a60f4f88c5c06013363a69c437553a8d..61c1ba58db9f998c8ad00ff8404464cb7aa10c82 100644 (file)
@@ -162,6 +162,15 @@ const eth::EtherHdr* get_eth_layer(const Packet* const p)
     return eh ? eh : reinterpret_cast<const eth::EtherHdr*>(get_root_layer(p));
 }
 
+const wlan::WifiHdr* get_wifi_layer(const Packet* const p)
+{
+    uint8_t num_layers = p->num_layers;
+    const Layer* lyr = p->layers;
+
+    return reinterpret_cast<const wlan::WifiHdr*>(
+        find_inner_layer(lyr, num_layers, ProtocolId::ETHERNET_802_11));
+}
+
 const ip::IP6Frag* get_inner_ip6_frag()
 { return get_inner_ip6_frag(curr_pkt); }
 
index d25543484c2940ebf70a3f7b30dba95306c0f077..f8f25f89d1bad8c4f4ebf5d96e33360755905c6a 100644 (file)
@@ -74,6 +74,11 @@ namespace udp
 struct UDPHdr;
 }
 
+namespace wlan
+{
+struct WifiHdr;
+}
+
 namespace icmp
 {
 struct ICMPHdr;
@@ -94,6 +99,7 @@ SO_PUBLIC const vlan::VlanTagHdr* get_vlan_layer(const Packet*);
 SO_PUBLIC const gre::GREHdr* get_gre_layer(const Packet*);
 SO_PUBLIC const eapol::EtherEapol* get_eapol_layer(const Packet*);
 SO_PUBLIC const eth::EtherHdr* get_eth_layer(const Packet*);
+SO_PUBLIC const wlan::WifiHdr* get_wifi_layer(const Packet*);
 SO_PUBLIC const uint8_t* get_root_layer(const Packet* const);
 /* return a pointer to the outermost UDP layer */
 SO_PUBLIC const udp::UDPHdr* get_outer_udp_lyr(const Packet* const);