1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation. You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 //--------------------------------------------------------------------------
18
19 // arp_module.cc author Russ Combs <rucombs@cisco.com>
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "arp_module.h"
26
27 using namespace snort;
28
29 #define ARPSPOOF_UNICAST_ARP_REQUEST_STR \
30 "unicast ARP request"
31 #define ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC_STR \
32 "ethernet/ARP mismatch for source hardware address"
33 #define ARPSPOOF_ETHERFRAME_ARP_MISMATCH_DST_STR \
34 "ethernet/ARP mismatch for destination hardware address in reply"
35 #define ARPSPOOF_ARP_CACHE_OVERWRITE_ATTACK_STR \
36 "attempted ARP cache overwrite attack"
37
38 THREAD_LOCAL SimpleStats asstats;
39
40 //-------------------------------------------------------------------------
41 // arp_spoof stuff
42 //-------------------------------------------------------------------------
43
44 static const Parameter arp_spoof_hosts_params[] =
45 {
46 { "ip", Parameter::PT_IP4, nullptr, nullptr,
47 "host ip address" },
48
49 { "mac", Parameter::PT_MAC, nullptr, nullptr,
50 "host mac address" },
51
52 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
53 };
54
55 static const Parameter s_params[] =
56 {
57 { "hosts", Parameter::PT_LIST, arp_spoof_hosts_params, nullptr,
58 "configure ARP cache overwrite attacks" },
59
60 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
61 };
62
63 static const RuleMap s_rules[] =
64 {
65 { ARPSPOOF_UNICAST_ARP_REQUEST, ARPSPOOF_UNICAST_ARP_REQUEST_STR },
66 { ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC, ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC_STR },
67 { ARPSPOOF_ETHERFRAME_ARP_MISMATCH_DST, ARPSPOOF_ETHERFRAME_ARP_MISMATCH_DST_STR },
68 { ARPSPOOF_ARP_CACHE_OVERWRITE_ATTACK, ARPSPOOF_ARP_CACHE_OVERWRITE_ATTACK_STR },
69
70 { 0, nullptr }
71 };
72
73 //-------------------------------------------------------------------------
74 // arp_spoof module
75 //-------------------------------------------------------------------------
76
ArpSpoofModule()77 ArpSpoofModule::ArpSpoofModule() :
78 Module(MOD_NAME, MOD_HELP, s_params)
79 {
80 config = nullptr;
81 }
82
~ArpSpoofModule()83 ArpSpoofModule::~ArpSpoofModule()
84 {
85 if ( config )
86 delete config;
87 }
88
get_rules() const89 const RuleMap* ArpSpoofModule::get_rules() const
90 { return s_rules; }
91
get_profile() const92 ProfileStats* ArpSpoofModule::get_profile() const
93 { return &arpPerfStats; }
94
set(const char *,Value & v,SnortConfig *)95 bool ArpSpoofModule::set(const char*, Value& v, SnortConfig*)
96 {
97 if ( v.is("ip") )
98 host.ipv4_addr = v.get_ip4();
99
100 else if ( v.is("mac") )
101 v.get_mac(host.mac_addr);
102
103 return true;
104 }
105
get_config()106 ArpSpoofConfig* ArpSpoofModule::get_config()
107 {
108 ArpSpoofConfig* temp = config;
109 config = nullptr;
110 return temp;
111 }
112
begin(const char *,int,SnortConfig *)113 bool ArpSpoofModule::begin(const char*, int, SnortConfig*)
114 {
115 if ( !config )
116 {
117 config = new ArpSpoofConfig;
118 config->check_overwrite = false;
119 }
120 memset(&host, 0, sizeof(host));
121 return true;
122 }
123
end(const char *,int idx,SnortConfig *)124 bool ArpSpoofModule::end(const char*, int idx, SnortConfig*)
125 {
126 if ( idx )
127 config->ipmel.emplace_back(host);
128 else
129 config->check_overwrite = !config->ipmel.empty();
130
131 return true;
132 }
133
get_pegs() const134 const PegInfo* ArpSpoofModule::get_pegs() const
135 { return simple_pegs; }
136
get_counts() const137 PegCount* ArpSpoofModule::get_counts() const
138 { return (PegCount*)&asstats; }
139
140