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