1 //--------------------------------------------------------------------------
2 // Copyright (C) 2016-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 // ips_dce_stub_data.cc author Maya Dagon <mdagon@cisco.com>
20 // based on work by Todd Wease
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "framework/cursor.h"
27 #include "framework/ips_option.h"
28 #include "framework/module.h"
29 #include "hash/hash_key_operations.h"
30 #include "profiler/profiler.h"
31
32 #include "dce_common.h"
33
34 using namespace snort;
35
36 #define s_name "dce_stub_data"
37 #define s_help \
38 "sets the cursor to dcerpc stub data"
39
40 //-------------------------------------------------------------------------
41 // dcerpc2 stub data rule option
42 //-------------------------------------------------------------------------
43
44 static THREAD_LOCAL ProfileStats dce2_stub_data_perf_stats;
45
46 class Dce2StubDataOption : public IpsOption
47 {
48 public:
Dce2StubDataOption()49 Dce2StubDataOption() : IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_SET) { }
50
51 uint32_t hash() const override;
52 bool operator==(const IpsOption&) const override;
53
54 EvalStatus eval(Cursor&, Packet*) override;
55 };
56
hash() const57 uint32_t Dce2StubDataOption::hash() const
58 {
59 uint32_t a = IpsOption::hash();
60 uint32_t b = 0, c = 0;
61
62 mix(a, b, c);
63 finalize(a,b,c);
64
65 return c;
66 }
67
operator ==(const IpsOption & ips) const68 bool Dce2StubDataOption::operator==(const IpsOption& ips) const
69 {
70 return IpsOption::operator==(ips);
71 }
72
eval(Cursor & c,Packet * p)73 IpsOption::EvalStatus Dce2StubDataOption::eval(Cursor& c, Packet* p)
74 {
75 RuleProfile profile(dce2_stub_data_perf_stats);
76
77 if (p->dsize == 0)
78 {
79 return NO_MATCH;
80 }
81
82 if (DceContextData::is_noinspect(p))
83 {
84 return NO_MATCH;
85 }
86
87 DCE2_Roptions* ropts = DceContextData::get_current_ropts(p);
88
89 if ( !ropts )
90 return NO_MATCH;
91
92 if (ropts->stub_data != nullptr)
93 {
94 c.set(s_name, ropts->stub_data, (uint16_t)(p->dsize - (ropts->stub_data -
95 p->data)));
96 return MATCH;
97 }
98
99 return NO_MATCH;
100 }
101
102 //-------------------------------------------------------------------------
103 // module
104 //-------------------------------------------------------------------------
105
106 class Dce2StubDataModule : public Module
107 {
108 public:
Dce2StubDataModule()109 Dce2StubDataModule() : Module(s_name, s_help) { }
110 ProfileStats* get_profile() const override;
111
get_usage() const112 Usage get_usage() const override
113 { return DETECT; }
114 };
115
get_profile() const116 ProfileStats* Dce2StubDataModule::get_profile() const
117 {
118 return &dce2_stub_data_perf_stats;
119 }
120
121 //-------------------------------------------------------------------------
122 // api
123 //-------------------------------------------------------------------------
124
dce2_stub_data_mod_ctor()125 static Module* dce2_stub_data_mod_ctor()
126 {
127 return new Dce2StubDataModule;
128 }
129
dce2_stub_data_mod_dtor(Module * m)130 static void dce2_stub_data_mod_dtor(Module* m)
131 {
132 delete m;
133 }
134
dce2_stub_data_ctor(Module *,OptTreeNode *)135 static IpsOption* dce2_stub_data_ctor(Module*, OptTreeNode*)
136 {
137 return new Dce2StubDataOption;
138 }
139
dce2_stub_data_dtor(IpsOption * p)140 static void dce2_stub_data_dtor(IpsOption* p)
141 {
142 delete p;
143 }
144
145 static const IpsApi ips_api =
146 {
147 {
148 PT_IPS_OPTION,
149 sizeof(IpsApi),
150 IPSAPI_VERSION,
151 0,
152 API_RESERVED,
153 API_OPTIONS,
154 s_name,
155 s_help,
156 dce2_stub_data_mod_ctor,
157 dce2_stub_data_mod_dtor
158 },
159 OPT_TYPE_DETECTION,
160 0, PROTO_BIT__TCP | PROTO_BIT__UDP,
161 nullptr,
162 nullptr,
163 nullptr,
164 nullptr,
165 dce2_stub_data_ctor,
166 dce2_stub_data_dtor,
167 nullptr
168 };
169
170 const BaseApi* ips_dce_stub_data = &ips_api.base;
171
172