1 /*
2 * C-Code Rule Example
3 */
4
5 #ifdef HAVE_CONFIG_H
6 #include "config.h"
7 #endif
8
9 #include "sf_snort_plugin_api.h"
10 #include "detection_lib_meta.h"
11
12 /* Forward Declaration */
13 int sid2519Eval(void *p);
14
15 /*
16 alert tcp $EXTERNAL_NET any -> $SMTP_SERVERS 465 (msg:"SMTP Client_Hello overflow attempt";
17 flow:to_server,established; content:"|01|"; depth:1; offset:2; byte_test:2,>,0,6;
18 byte_test:2,!,0,8; byte_test:2,!,16,8; byte_test:2,>,20,10; content:"|8F|"; depth:1;
19 offset:11; byte_test:2,>,32768,0,relative; reference:bugtraq,10116; reference:cve,2003-0719;
20 reference:url,www.microsoft.com/technet/security/bulletin/MS04-011.mspx;
21 classtype:attempted-admin; sid:2519; rev:9;)
22 *
23 */
24
25 /* The GUI will run snort with a special flag to extract this information,
26 * and generate a skeleton rule file with
27 * SRC IP/PORT info,
28 * DST IP/PORT info,
29 * Message
30 * SID
31 * GID
32 * REV
33 * References
34 *
35 * This skeleton rule file will be read as a normal rules file (just no
36 * rule matching options specified. When the shared library is loaded,
37 * it will access the loaded rule info (by SID/GID hash) and update the
38 * rest of the rule structure for processing (ie, handle any flowbits
39 * checks, content & pcre premung'ing, & fast pattern registration.
40 *
41 * A check will be made for the rule revision. Rule data will different
42 * revision info, or non-existant SID/GIDs will cause a snort startup error.
43 *
44 */
45 static RuleReference ref1 =
46 {
47 "bugtraq", /* System Name */
48 "10116" /* ID */
49 };
50
51 static RuleReference ref2 =
52 {
53 "cve", /* System Name */
54 "2003-0719" /* ID */
55 };
56
57 static RuleReference ref3 =
58 {
59 "url", /* System Name */
60 "www.microsoft.com/technet/security/bulletin/MS04-011.mspx"
61 };
62
63 static RuleReference *refs[] =
64 {
65 &ref1,
66 &ref2,
67 &ref3,
68 NULL
69 };
70
71
72 static FlowFlags flowflags1 =
73 {
74 FLOW_TO_SERVER | FLOW_ESTABLISHED
75 };
76
77 static RuleOption option1 =
78 {
79 OPTION_TYPE_FLOWFLAGS,
80 { &flowflags1 }
81 };
82
83 static ContentInfo content1 =
84 { /* Content */
85 (u_int8_t *)"|01|", /* pattern */
86 1, /* depth */
87 2, /* offset */
88 CONTENT_NOCASE | CONTENT_FAST_PATTERN, /* Flags */
89 NULL, /* Holder for Boyer Ptr */
90 NULL,
91 0, /* byteform length */
92 0, /* increment length */
93 0, /* holder for fp offset */
94 0, /* holder for fp length */
95 0, /* holder for fp only */
96 NULL, // offset_refId
97 NULL, // depth_refId
98 NULL, // offset_location
99 NULL // depth_location
100 };
101
102 static RuleOption option2 =
103 {
104 OPTION_TYPE_CONTENT,
105 { &content1 }
106 };
107
108 static ByteData byte1 =
109 { /* Byte test */
110 2, /* bytes */
111 CHECK_GT, /* operator */
112 0, /* value to compare against */
113 6, /* offset */
114 0, /* multiplier */
115 EXTRACT_AS_BYTE | CONTENT_BUF_RAW, /* flags */
116 0, /* offset */
117 NULL, // offset_refId
118 NULL, // value_refId
119 NULL, // offset_location
120 NULL // value_location
121 };
122
123 static RuleOption option3 =
124 {
125 OPTION_TYPE_BYTE_TEST,
126 { &byte1 }
127 };
128
129 static ByteData byte2 =
130 { /* Byte test */
131 2, /* bytes */
132 CHECK_NEQ, /* operator */
133 0, /* value to compare against */
134 8, /* offset */
135 0, /* multiplier */
136 EXTRACT_AS_BYTE | CONTENT_BUF_RAW, /* flags */
137 0, /* offset */
138 NULL, // offset_refId
139 NULL, // value_refId
140 NULL, // offset_location
141 NULL // value_location
142 };
143
144 static RuleOption option4 =
145 {
146 OPTION_TYPE_BYTE_TEST,
147 { &byte2 }
148 };
149
150 static ByteData byte3 =
151 { /* Byte test */
152 2, /* bytes */
153 CHECK_NEQ, /* operator */
154 16, /* value to compare against */
155 8, /* offset */
156 0, /* multiplier */
157 EXTRACT_AS_BYTE | CONTENT_BUF_RAW, /* flags */
158 0, /* offset */
159 NULL, // offset_refId
160 NULL, // value_refId
161 NULL, // offset_location
162 NULL // value_location
163 };
164
165 static RuleOption option5 =
166 {
167 OPTION_TYPE_BYTE_TEST,
168 { &byte3 }
169 };
170
171 static ByteData byte4 =
172 { /* Byte test */
173 2, /* bytes */
174 CHECK_GT, /* operator */
175 20, /* value to compare against */
176 10, /* offset */
177 0, /* multiplier */
178 EXTRACT_AS_BYTE | CONTENT_BUF_RAW, /* flags */
179 0, /* offset */
180 NULL, // offset_refId
181 NULL, // value_refId
182 NULL, // offset_location
183 NULL // value_location
184 };
185
186 static RuleOption option6 =
187 {
188 OPTION_TYPE_BYTE_TEST,
189 { &byte4 }
190 };
191
192 static ContentInfo content2 =
193 { /* Content */
194 (u_int8_t *)"|8F|",
195 1, /* depth */
196 11, /* offset */
197 CONTENT_RELATIVE | CONTENT_BUF_NORMALIZED, /* Flags */
198 NULL, /* Holder for Boyer Ptr */
199 NULL,
200 0, /* byteform length */
201 0, /* increment length */
202 0, /* holder for fp offset */
203 0, /* holder for fp length */
204 0, /* holder for fp only */
205 NULL, // offset_refId
206 NULL, // depth_refId
207 NULL, // offset_location
208 NULL // depth_location
209 };
210
211 static RuleOption option7 =
212 {
213 OPTION_TYPE_CONTENT,
214 { &content2 }
215 };
216
217 static ByteData byte5 =
218 { /* Byte test */
219 2, /* bytes */
220 CHECK_GT, /* operator */
221 32768, /* value to compare against */
222 0, /* offset */
223 0, /* multiplier */
224 EXTRACT_AS_BYTE | CONTENT_RELATIVE | CONTENT_BUF_RAW, /* flags */
225 0, /* offset */
226 NULL, // offset_refId
227 NULL, // value_refId
228 NULL, // offset_location
229 NULL // value_location
230 };
231
232 static RuleOption option8 =
233 {
234 OPTION_TYPE_BYTE_TEST,
235 { &byte5 }
236 };
237
238 static RuleOption *options[] =
239 {
240 &option1,
241 &option2,
242 &option3,
243 &option4,
244 &option5,
245 &option6,
246 &option7,
247 &option8,
248 NULL
249 };
250
251 Rule sid2519 =
252 {
253 /* A skeleton rule generated from the GUI contains user configured
254 * IP & Port info */
255 { /* IP Info */
256 IPPROTO_TCP, /* Protocol */
257 EXTERNAL_NET, /* SRC IP -- pulled fr skeleton rule */
258 ANY_PORT, /* SRC Port -- pulled fr skeleton rule */
259 0, /* uni-directional */
260 SMTP_SERVERS, /* DST IP -- pulled fr skeleton rule */
261 "465", /* DST Port -- pulled fr skeleton rule */
262 },
263
264 { /* Rule Information */
265 RULE_GID, /* Gen ID */
266 2519, /* Sig ID */
267 9, /* Rev */
268
269 "attempted-admin", /* classification */
270 0, /* Hard Coded Priority (overrides
271 class priority if non-0) */
272 "SMTP Client_Hello overflow attempt", /* message */
273 refs, /* References */
274 NULL /* metadata */
275 },
276 options, /* Options */
277 NULL, /* Use internal eval func */
278 0, /* Not initialized */
279 0, /* Rule option count, used internally */
280 0, /* Flag with no alert, used internally */
281 NULL /* ptr to internal data... setup during rule registration */
282 };
283
sid2519Eval(void * p)284 int sid2519Eval(void *p)
285 {
286 //const u_int8_t *uri_cur = 0;
287 const u_int8_t *norm_cur = 0;
288 if (checkFlow(p, sid2519.options[0]->option_u.flowFlags) )
289 {
290 if (contentMatch(p, sid2519.options[1]->option_u.content, &norm_cur)>0)
291 {
292 if(byteTest(p, sid2519.options[2]->option_u.byte, norm_cur))
293 {
294 if(byteTest(p, sid2519.options[3]->option_u.byte, norm_cur))
295 {
296 if(byteTest(p, sid2519.options[4]->option_u.byte, norm_cur))
297 {
298 if(byteTest(p, sid2519.options[5]->option_u.byte, norm_cur))
299 {
300 if (contentMatch(p, sid2519.options[6]->option_u.content, &norm_cur)>0)
301 {
302 if(byteTest(p, sid2519.options[7]->option_u.byte, norm_cur))
303 {
304
305 return RULE_MATCH;
306 }
307 }
308 }
309 }
310 }
311 }
312 }
313 }
314 return RULE_NOMATCH;
315 }
316