1 /*
2 ** Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 ** Copyright (C) 2002-2013 Sourcefire, Inc.
4 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License Version 2 as
8 ** published by the Free Software Foundation. You may not use, modify or
9 ** distribute this program under any other version of the GNU General
10 ** Public License.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software
19 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22 /* $Id$ */
23 /* spp_rpc_decode
24 *
25 * Purpose:
26 *
27 * This preprocessor normalizes the RPC requests from remote machines by
28 * converting all fragments into one continous stream.
29 * This is very useful for doing things like defeating hostile attackers
30 * trying to stealth themselves from IDSs by fragmenting the request so the
31 * string 0186A0 is broken up.
32 *
33 * Arguments:
34 *
35 * This plugin takes a list of integers representing the TCP ports that the
36 * user is interested in having normalized
37 *
38 * Effect:
39 *
40 * Changes the data in the packet payload and changes
41 * p->dsize to reflect the new (smaller) payload size.
42 *
43 * Comments:
44 *
45 */
46
47 #ifdef HAVE_CONFIG_H
48 #include "config.h"
49 #endif
50
51 #include <assert.h>
52 #include <sys/types.h>
53 #include <stdlib.h>
54 #include <ctype.h>
55
56 #ifdef HAVE_STRINGS_H
57 #include <strings.h>
58 #endif
59
60 #include "decode.h"
61 #include "plugbase.h"
62 #include "parser.h"
63 #include "log.h"
64 #include "snort_debug.h"
65 #include "util.h"
66
67 #include "mstring.h"
68 #include "snort.h"
69 #include "detect.h"
70 #include "log.h"
71 #include "generators.h"
72 #include "event_queue.h"
73
74 #include "profiler.h"
75 #include "snort_bounds.h"
76 #include "strlcatu.h"
77 #include "detection_util.h"
78
79 #include "session_api.h"
80 #include "stream_api.h"
81
82 #ifdef TARGET_BASED
83 #include "sftarget_protocol_reference.h"
84 #endif
85 #include "sfPolicy.h"
86
87 #define OPT_ALERT_FRAGMENTS "alert_fragments"
88 #define OPT_ALERT_MULTIPLE_REQUESTS "no_alert_multiple_requests"
89 #define OPT_ALERT_LARGE_FRAGMENTS "no_alert_large_fragments"
90 #define OPT_ALERT_INCOMPLETE "no_alert_incomplete"
91
92 #define TEXT_ALERT_MULTIPLE_REQUESTS "alert_multiple_requests"
93 #define TEXT_ALERT_LARGE_FRAGMENTS "alert_large_fragments"
94 #define TEXT_ALERT_INCOMPLETE "alert_incomplete"
95 #define RPC_DECODE_DEFAULT_PORTS "111 32271"
96
97 #define RPC_CLASS DECODE_CLASS /* use the same classification as the other decoder alerts */
98
99 #define RPC_MAX_BUF_SIZE 256
100 #define RPC_FRAG_HDR_SIZE sizeof(uint32_t)
101 #define RPC_FRAG_LEN(ptr) (ntohl(*((uint32_t *)ptr)) & 0x7FFFFFFF)
102
103 typedef struct _RpcDecodeConfig
104 {
105 char alert_fragments; /* Alert when we see ANY fragmented RPC requests */
106 char alert_incomplete; /* Alert when we don't see all of a request in one packet */
107 char alert_multi; /* Alert when we see multiple requests in one packet */
108 char alert_large; /* Alert when we see multiple requests in one packet */
109 uint8_t RpcDecodePorts[MAXPORTS/8];
110
111 } RpcDecodeConfig;
112
113 typedef struct _RpcBuffer
114 {
115 uint8_t *data;
116 uint32_t len;
117 uint32_t size;
118
119 } RpcBuffer;
120
121 typedef struct _RpcSsnData
122 {
123 int active;
124 int events;
125 uint32_t frag_len;
126 uint32_t ignore;
127 uint32_t nseq;
128 uint32_t ofp;
129 RpcBuffer seg;
130 RpcBuffer frag;
131
132 } RpcSsnData;
133
134 typedef enum _RpcStatus
135 {
136 RPC_STATUS__SUCCESS,
137 RPC_STATUS__ERROR,
138 RPC_STATUS__DEFRAG
139
140 } RpcStatus;
141
142 static tSfPolicyUserContextId rpc_decode_config = NULL;
143 static const uint32_t flush_size = 28;
144 static const uint32_t rpc_memcap = 1048510;
145 static uint32_t rpc_memory = 0;
146
147 #ifdef TARGET_BASED
148 static int16_t rpc_decode_app_protocol_id;
149 #endif
150
151 #ifdef PERF_PROFILING
152 PreprocStats rpcdecodePerfStats;
153 #endif
154
155 static void RpcDecodeInit(struct _SnortConfig *, char *);
156 static void PreprocRpcDecode(Packet *, void *);
157 static void ParseRpcConfig(RpcDecodeConfig *, char *);
158 static int ConvertRPC(RpcDecodeConfig *, RpcSsnData *, Packet *);
159 static void RpcDecodeFreeConfig(tSfPolicyUserContextId rpc);
160 static void RpcDecodeCleanExit(int, void *);
161 static void enablePortStreamServices(struct _SnortConfig *, RpcDecodeConfig *, tSfPolicyId);
162 #ifdef TARGET_BASED
163 static void _addServicesToStreamFilter(struct _SnortConfig *, tSfPolicyId);
164 #endif
165 static void RpcDecodePortsAssign(uint8_t *, char *);
166 static int RpcDecodeIsEligible(RpcDecodeConfig *, Packet *);
167
168 #ifdef SNORT_RELOAD
169 static void RpcDecodeReload(struct _SnortConfig *, char *, void **);
170 static void * RpcDecodeReloadSwap(struct _SnortConfig *, void *);
171 static void RpcDecodeReloadSwapFree(void *);
172 #endif
173
174 static RpcSsnData * RpcSsnDataNew(Packet *);
175 static void RpcSsnDataFree(void *);
176 static inline void RpcSsnClean(RpcSsnData *);
177 static inline void RpcSsnSetInactive(RpcSsnData *, Packet *);
178 static inline int RpcSsnIsActive(RpcSsnData *);
179
180 static RpcStatus RpcStatefulInspection(RpcDecodeConfig *, RpcSsnData *, Packet *);
181 static inline void RpcPreprocEvent(RpcDecodeConfig *, RpcSsnData *, int);
182 static RpcStatus RpcHandleFrag(RpcDecodeConfig *, RpcSsnData *, const uint8_t *);
183 static RpcStatus RpcPrepRaw(const uint8_t *, uint32_t, Packet *);
184 static RpcStatus RpcPrepFrag(RpcSsnData *, Packet *);
185 static RpcStatus RpcPrepSeg(RpcSsnData *, Packet *);
186 static inline uint32_t RpcBufLen(RpcBuffer *);
187 static inline uint8_t * RpcBufData(RpcBuffer *);
188 static RpcStatus RpcBufAdd(RpcBuffer *, const uint8_t *, uint32_t);
189 static inline void RpcBufClean(RpcBuffer *);
190
191 static inline void * RpcAlloc(uint32_t);
192 static inline void RpcFree(void *, uint32_t);
193
194
195 //function to assign the RpcDecodePorts array
RpcDecodePortsAssign(uint8_t * RpcDecodePorts,char * portlist)196 static void RpcDecodePortsAssign(uint8_t *RpcDecodePorts, char *portlist)
197 {
198 int num;
199 int num_toks;
200 char **toks;
201 if( portlist == NULL || *portlist == '\0')
202 {
203 portlist = RPC_DECODE_DEFAULT_PORTS;
204 }
205 toks = mSplit(portlist, " \t", 0, &num_toks, 0);
206
207 for(num = 0; num < num_toks; num++)
208 {
209 if(isdigit((int)toks[num][0]))
210 {
211 char *num_p = NULL; /* used to determine last position in string */
212 long t_num;
213
214 t_num = strtol(toks[num], &num_p, 10);
215
216 if(*num_p != '\0')
217 {
218 ParseError("Port Number invalid format: %s.", toks[num]);
219 }
220 else if(t_num < 0 || t_num > MAXPORTS-1 )
221 {
222 ParseError("Port Number out of range: %d.", t_num);
223 }
224
225 RpcDecodePorts[(t_num/8)] |= 1<<(t_num%8);
226 }
227 }
228 mSplitFree(&toks, num_toks);
229
230 }
231
232 /*
233 * Function: SetupRpcDecode()
234 *
235 * Purpose: Registers the preprocessor keyword and initialization
236 * function into the preprocessor list.
237 *
238 * Arguments: None.
239 *
240 * Returns: void function
241 *
242 */
SetupRpcDecode(void)243 void SetupRpcDecode(void)
244 {
245 /* link the preprocessor keyword to the init function in
246 the preproc list */
247 #ifndef SNORT_RELOAD
248 RegisterPreprocessor("rpc_decode", RpcDecodeInit);
249 #else
250 RegisterPreprocessor("rpc_decode", RpcDecodeInit, RpcDecodeReload, NULL,
251 RpcDecodeReloadSwap, RpcDecodeReloadSwapFree);
252 #endif
253
254 DEBUG_WRAP(DebugMessage(DEBUG_RPC,"Preprocessor: RpcDecode in setup...\n"););
255 }
256
257
258 /*
259 * Function: RpcDecodeInit(char *)
260 *
261 * Purpose: Processes the args sent to the preprocessor, sets up the
262 * port list, links the processing function into the preproc
263 * function list
264 *
265 * Arguments: args => ptr to argument string
266 *
267 * Returns: void function
268 *
269 */
RpcDecodeInit(struct _SnortConfig * sc,char * args)270 void RpcDecodeInit(struct _SnortConfig *sc, char *args)
271 {
272 tSfPolicyId policy_id = getParserPolicy(sc);
273 RpcDecodeConfig *pPolicyConfig = NULL;
274
275 if (rpc_decode_config == NULL)
276 {
277 rpc_decode_config = sfPolicyConfigCreate();
278
279 AddFuncToPreprocCleanExitList(RpcDecodeCleanExit, NULL, PRIORITY_LAST, PP_RPCDECODE);
280
281 #ifdef PERF_PROFILING
282 RegisterPreprocessorProfile("rpcdecode", &rpcdecodePerfStats, 0, &totalPerfStats, NULL);
283 #endif
284
285 #ifdef TARGET_BASED
286 /* Find and cache protocol ID for packet comparison */
287 rpc_decode_app_protocol_id = FindProtocolReference("sunrpc");
288 if (rpc_decode_app_protocol_id == SFTARGET_UNKNOWN_PROTOCOL)
289 rpc_decode_app_protocol_id = AddProtocolReference("sunrpc");
290
291 // register with session to handle applications
292 session_api->register_service_handler( PP_RPCDECODE, rpc_decode_app_protocol_id );
293 #endif
294 }
295
296 sfPolicyUserPolicySet (rpc_decode_config, policy_id);
297 pPolicyConfig = (RpcDecodeConfig *) sfPolicyUserDataGetCurrent(rpc_decode_config);
298 if (pPolicyConfig)
299 {
300 ParseError("RPC decode can only be configured once.\n");
301 }
302
303 pPolicyConfig = (RpcDecodeConfig *)SnortAlloc(sizeof(RpcDecodeConfig));
304 if (!pPolicyConfig)
305 {
306 ParseError("RPC_DECODE preprocessor: memory allocate failed.\n");
307 }
308
309 sfPolicyUserDataSetCurrent(rpc_decode_config, pPolicyConfig);
310
311 /* parse the argument list into a list of ports to normalize */
312 ParseRpcConfig(pPolicyConfig, args);
313
314 /* Set the preprocessor function into the function list */
315 AddFuncToPreprocList(sc, PreprocRpcDecode, PRIORITY_APPLICATION, PP_RPCDECODE, PROTO_BIT__TCP);
316 enablePortStreamServices(sc, pPolicyConfig, policy_id);
317
318 #ifdef TARGET_BASED
319 _addServicesToStreamFilter(sc, policy_id);
320 #endif
321
322 DEBUG_WRAP(DebugMessage(DEBUG_RPC,"Preprocessor: RpcDecode Initialized\n"););
323 }
324
325 /*
326 * Function: ParseRpcConfig(char *)
327 *
328 * Purpose: Reads the list of port numbers from the argument string and
329 * parses them into the port list data struct
330 *
331 * Arguments: portlist => argument list
332 *
333 * Returns: void function
334 *
335 */
ParseRpcConfig(RpcDecodeConfig * rpc,char * portlist)336 void ParseRpcConfig(RpcDecodeConfig *rpc, char *portlist)
337 {
338 char portstr[STD_BUF];
339 char **toks;
340 int is_reset = 0;
341 int num_toks;
342 int num;
343
344 if (rpc == NULL)
345 return;
346
347 if(portlist == NULL || *portlist == '\0')
348 {
349 portlist = RPC_DECODE_DEFAULT_PORTS;
350 }
351
352 rpc->alert_multi = 1;
353 rpc->alert_incomplete = 1;
354 rpc->alert_large = 1;
355
356 /* tokenize the argument list */
357 toks = mSplit(portlist, " \t", 0, &num_toks, 0);
358
359 LogMessage("rpc_decode arguments:\n");
360
361 /* convert the tokens and place them into the port list */
362 for(num = 0; num < num_toks; num++)
363 {
364 if(isdigit((int)toks[num][0]))
365 {
366 char *num_p = NULL; /* used to determine last position in string */
367 long t_num;
368
369 t_num = strtol(toks[num], &num_p, 10);
370
371 if(*num_p != '\0')
372 {
373 ParseError("Port Number invalid format: %s.", toks[num]);
374 }
375 else if(t_num < 0 || t_num > MAXPORTS-1)
376 {
377 ParseError("Port Number out of range: %d\n", t_num);
378 }
379
380 /* user specified a legal port number and it should override the default
381 port list, so reset it unless already done */
382 if(!is_reset)
383 {
384 memset(rpc->RpcDecodePorts, 0, sizeof(rpc->RpcDecodePorts));
385 portstr[0] = '\0';
386 is_reset = 1;
387 }
388
389 /* mark this port as being interesting using some portscan2-type voodoo,
390 and also add it to the port list string while we're at it so we can
391 later print out all the ports with a single LogMessage() */
392 rpc->RpcDecodePorts[(t_num/8)] |= 1<<(t_num%8);
393 strlcat(portstr, toks[num], STD_BUF - 1);
394 strlcat(portstr, " ", STD_BUF - 1);
395 }
396 else if(!strcasecmp(OPT_ALERT_MULTIPLE_REQUESTS,toks[num]))
397 {
398 rpc->alert_multi = 0;
399 }
400 else if(!strcasecmp(OPT_ALERT_INCOMPLETE,toks[num]))
401 {
402 rpc->alert_incomplete = 0;
403 }
404 else if(!strcasecmp(OPT_ALERT_LARGE_FRAGMENTS,toks[num]))
405 {
406 rpc->alert_large = 0;
407 }
408 else if(!strcasecmp(OPT_ALERT_FRAGMENTS,toks[num]))
409 {
410 rpc->alert_fragments = 1;
411 }
412 else
413 {
414 ParseError("Unknown argument to rpc_decode "
415 "preprocessor: \"%s\".", toks[num]);
416 }
417 }
418
419 mSplitFree(&toks, num_toks);
420
421 if( !is_reset )
422 {
423 RpcDecodePortsAssign(rpc->RpcDecodePorts, RPC_DECODE_DEFAULT_PORTS);
424 }
425
426 /* print out final port list */
427 LogMessage(" Ports to decode RPC on: %s\n", is_reset ? portstr : RPC_DECODE_DEFAULT_PORTS);
428 LogMessage(" %s: %s\n", OPT_ALERT_FRAGMENTS, rpc->alert_fragments ? "ACTIVE": "INACTIVE");
429 LogMessage(" %s: %s\n", TEXT_ALERT_LARGE_FRAGMENTS, rpc->alert_large ? "ACTIVE": "INACTIVE");
430 LogMessage(" %s: %s\n", TEXT_ALERT_INCOMPLETE, rpc->alert_incomplete ? "ACTIVE": "INACTIVE");
431 LogMessage(" %s: %s\n", TEXT_ALERT_MULTIPLE_REQUESTS, rpc->alert_multi ? "ACTIVE": "INACTIVE");
432 }
433
434
435 /*
436 * Function: PreprocRpcDecode(Packet *)
437 *
438 * Purpose: Inspects the packet's payload for fragment records and
439 * converts them into one infragmented record.
440 *
441 * Arguments: p => pointer to the current packet data struct
442 *
443 * Returns: void function
444 *
445 */
PreprocRpcDecode(Packet * p,void * context)446 static void PreprocRpcDecode(Packet *p, void *context)
447 {
448 RpcDecodeConfig *rconfig = NULL;
449 RpcSsnData *rsdata = NULL;
450 PROFILE_VARS;
451
452 sfPolicyUserPolicySet(rpc_decode_config, getNapRuntimePolicy());
453 rconfig = (RpcDecodeConfig *)sfPolicyUserDataGetCurrent(rpc_decode_config);
454
455 /* Not configured in this policy */
456 if (rconfig == NULL)
457 return;
458
459 // preconditions - what we registered for
460 assert(IsTCP(p) && p->dsize);
461
462 /* If we're stateful that means stream5 has been configured.
463 * In this case we don't look at server packets.
464 * There is the case were stream5 configuration requires a 3 way handshake.
465 * If no 3 way, then the packet flags won't be set, so don't look at it
466 * since we won't be able to determeine who's the client and who's the server. */
467 if (ScStateful()
468 && ((p->packet_flags & PKT_FROM_SERVER)
469 || (!(p->packet_flags & PKT_FROM_CLIENT))))
470 {
471 return;
472 }
473
474 if ( ( session_api != NULL ) && ( p->ssnptr != NULL ) )
475 rsdata = session_api->get_application_data(p->ssnptr, PP_RPCDECODE);
476
477 if (rsdata == NULL)
478 {
479 if (!RpcDecodeIsEligible(rconfig, p))
480 return;
481 }
482
483 PREPROC_PROFILE_START(rpcdecodePerfStats);
484
485 if ((rsdata == NULL) && (session_api != NULL) && (p->ssnptr != NULL))
486 {
487 if (!(session_api->get_session_flags(p->ssnptr) & SSNFLAG_MIDSTREAM))
488 rsdata = RpcSsnDataNew(p);
489 }
490
491 if (RpcSsnIsActive(rsdata)
492 && ((p->packet_flags & PKT_REBUILT_STREAM)
493 || (rsdata->nseq == 0)))
494 {
495 RpcStatus ret = RpcStatefulInspection(rconfig, rsdata, p);
496
497 if (ret == RPC_STATUS__SUCCESS)
498 {
499 PREPROC_PROFILE_END(rpcdecodePerfStats);
500 return;
501 }
502
503 /* Something went wrong - deactivate session tracking
504 * and decode normally */
505 if (ret == RPC_STATUS__ERROR)
506 RpcSsnSetInactive(rsdata, p);
507 }
508
509 DEBUG_WRAP(DebugMessage(DEBUG_RPC,"Stateless inspection\n"););
510
511 RpcPreprocEvent(rconfig, rsdata, ConvertRPC(rconfig, rsdata, p));
512
513 PREPROC_PROFILE_END(rpcdecodePerfStats);
514 return;
515 }
516
RpcPreprocEvent(RpcDecodeConfig * rconfig,RpcSsnData * rsdata,int event)517 static inline void RpcPreprocEvent(RpcDecodeConfig *rconfig, RpcSsnData *rsdata, int event)
518 {
519 if (rconfig == NULL)
520 return;
521
522 if (rsdata != NULL)
523 {
524 /* Only log one event of the same type per session */
525 if (rsdata->events & (1 << event))
526 return;
527
528 rsdata->events |= (1 << event);
529 }
530
531 switch (event)
532 {
533 case RPC_FRAG_TRAFFIC:
534 if (rconfig->alert_fragments)
535 {
536 SnortEventqAdd(GENERATOR_SPP_RPC_DECODE, RPC_FRAG_TRAFFIC,
537 1, RPC_CLASS, 3, RPC_FRAG_TRAFFIC_STR, 0);
538 }
539 break;
540 case RPC_MULTIPLE_RECORD:
541 if (rconfig->alert_multi)
542 {
543 SnortEventqAdd(GENERATOR_SPP_RPC_DECODE, RPC_MULTIPLE_RECORD,
544 1, RPC_CLASS, 3, RPC_MULTIPLE_RECORD_STR, 0);
545 }
546 break;
547 case RPC_LARGE_FRAGSIZE:
548 if (rconfig->alert_large)
549 {
550 SnortEventqAdd(GENERATOR_SPP_RPC_DECODE, RPC_LARGE_FRAGSIZE,
551 1, RPC_CLASS, 3, RPC_LARGE_FRAGSIZE_STR, 0);
552 }
553 break;
554 case RPC_INCOMPLETE_SEGMENT:
555 if (rconfig->alert_incomplete)
556 {
557 SnortEventqAdd(GENERATOR_SPP_RPC_DECODE, RPC_INCOMPLETE_SEGMENT,
558 1, RPC_CLASS, 3, RPC_INCOMPLETE_SEGMENT_STR, 0);
559 }
560 break;
561 case RPC_ZERO_LENGTH_FRAGMENT:
562 if (rconfig->alert_multi)
563 {
564 SnortEventqAdd(GENERATOR_SPP_RPC_DECODE, RPC_ZERO_LENGTH_FRAGMENT,
565 1, RPC_CLASS, 3, RPC_ZERO_LENGTH_FRAGMENT_STR, 0);
566 }
567 break;
568 default:
569 break;
570 }
571 }
572
RpcDecodeIsEligible(RpcDecodeConfig * rconfig,Packet * p)573 static int RpcDecodeIsEligible(RpcDecodeConfig *rconfig, Packet *p)
574 {
575 int valid_app_id = 0;
576 #ifdef TARGET_BASED
577 int16_t app_id = SFTARGET_UNKNOWN_PROTOCOL;
578
579 /* check stream info, fall back to checking ports */
580 if (session_api != NULL)
581 {
582 app_id = session_api->get_application_protocol_id(p->ssnptr);
583 if (app_id > 0)
584 {
585 valid_app_id = 1;
586 }
587 }
588
589 if (valid_app_id && app_id != rpc_decode_app_protocol_id)
590 return 0;
591 #endif
592
593 if (!valid_app_id)
594 {
595 uint16_t check_port;
596
597 if (p->packet_flags & PKT_FROM_CLIENT)
598 check_port = p->dp;
599 else if (p->packet_flags & PKT_FROM_SERVER)
600 check_port = p->sp;
601 /* The below are for the case where stream5 is not configured */
602 else if (p->sp < p->dp)
603 check_port = p->sp;
604 else
605 check_port = p->dp;
606
607 if (!(rconfig->RpcDecodePorts[(check_port/8)] & (1<<(check_port%8))))
608 return 0;
609 }
610
611 return 1;
612 }
613
RpcStatefulInspection(RpcDecodeConfig * rconfig,RpcSsnData * rsdata,Packet * p)614 static RpcStatus RpcStatefulInspection(RpcDecodeConfig *rconfig,
615 RpcSsnData *rsdata, Packet *p)
616 {
617 const uint8_t *data = p->data;
618 uint16_t dsize = p->dsize;
619 uint32_t seq = ntohl(p->tcph->th_seq);
620 int need;
621 RpcStatus status;
622
623 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
624 "STATEFUL: Start *******************************\n"););
625 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
626 "STATEFUL: Ssn: %p\n", rsdata););
627
628 if ((rsdata->nseq != seq) && (rsdata->nseq != 0))
629 {
630 uint32_t overlap;
631
632 if (rsdata->nseq < seq)
633 {
634 /* Missed packets - stop tracking */
635 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
636 "STATEFUL: Missed data\n"););
637 return RPC_STATUS__ERROR;
638 }
639
640 overlap = rsdata->nseq - seq;
641 if (dsize <= overlap)
642 {
643 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
644 "STATEFUL: All data overlapped\n"););
645 return RPC_STATUS__SUCCESS;
646 }
647
648 data += overlap;
649 dsize -= (uint16_t)overlap;
650
651 seq += overlap;
652 }
653
654 rsdata->nseq = seq + dsize;
655
656 if (rsdata->ignore)
657 {
658 if (dsize < rsdata->ignore)
659 {
660 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
661 "STATEFUL: Ignoring %u bytes\n", dsize););
662
663 rsdata->ignore -= dsize;
664
665 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
666 "STATEFUL: Bytes left to ignore: %u \n", rsdata->ignore););
667
668 return RPC_STATUS__SUCCESS;
669 }
670
671 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
672 "STATEFUL: Ignoring %u bytes\n", rsdata->ignore););
673
674 dsize -= (uint16_t)rsdata->ignore;
675 data += rsdata->ignore;
676 rsdata->ignore = 0;
677 }
678
679 /* Might need to evaluate same packet, different decode buffer
680 * more than once and detection option tree won't let us do that
681 * by default */
682 p->packet_flags |= PKT_ALLOW_MULTIPLE_DETECT;
683
684 while (dsize > 0)
685 {
686 if (RpcBufLen(&rsdata->seg) == 0)
687 {
688 if (dsize < RPC_FRAG_HDR_SIZE)
689 {
690 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
691 "STATEFUL: Not enough data for frag header: %u\n",
692 dsize););
693
694 RpcPreprocEvent(rconfig, rsdata, RPC_INCOMPLETE_SEGMENT);
695
696 if (RpcBufAdd(&rsdata->seg, data, dsize) != RPC_STATUS__SUCCESS)
697 return RPC_STATUS__ERROR;
698
699 break;
700 }
701
702 rsdata->frag_len = RPC_FRAG_LEN(data);
703
704 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
705 "STATEFUL: Fragment length: %u\n", rsdata->frag_len););
706
707 if (dsize < (RPC_FRAG_HDR_SIZE + rsdata->frag_len))
708 {
709 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
710 "STATEFUL: Not enough data for fragment: %u\n",
711 dsize););
712
713 RpcPreprocEvent(rconfig, rsdata, RPC_INCOMPLETE_SEGMENT);
714
715 if (RpcBufAdd(&rsdata->seg, data, dsize) != RPC_STATUS__SUCCESS)
716 return RPC_STATUS__ERROR;
717
718 break;
719 }
720
721 dsize -= (RPC_FRAG_HDR_SIZE + rsdata->frag_len);
722
723 status = RpcHandleFrag(rconfig, rsdata, data);
724
725 if (status == RPC_STATUS__ERROR)
726 return RPC_STATUS__ERROR;
727
728 if (status == RPC_STATUS__DEFRAG)
729 {
730 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
731 "STATEFUL: Last frag - calling detect\n"););
732
733 if ((dsize != 0) || (data != p->data))
734 {
735 /* Only do this if there is more than one fragment in
736 * the data we got */
737 if (RpcPrepRaw(data, rsdata->frag_len, p) != RPC_STATUS__SUCCESS)
738 return RPC_STATUS__ERROR;
739
740 Detect(p);
741 }
742
743 if ((dsize > 0) && rconfig->alert_multi)
744 RpcPreprocEvent(rconfig, rsdata, RPC_MULTIPLE_RECORD);
745 }
746
747 data += (RPC_FRAG_HDR_SIZE + rsdata->frag_len);
748 }
749 else
750 {
751 if (RpcBufLen(&rsdata->seg) < RPC_FRAG_HDR_SIZE)
752 {
753 need = RPC_FRAG_HDR_SIZE - RpcBufLen(&rsdata->seg);
754 if (dsize < need)
755 {
756 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
757 "STATEFUL: Not enough data for frag header "
758 "(%u): %u\n", need, dsize););
759
760 RpcPreprocEvent(rconfig, rsdata, RPC_INCOMPLETE_SEGMENT);
761
762 if (RpcBufAdd(&rsdata->seg, data, dsize) != RPC_STATUS__SUCCESS)
763 return RPC_STATUS__ERROR;
764
765 break;
766 }
767
768 if (RpcBufAdd(&rsdata->seg, data, need) != RPC_STATUS__SUCCESS)
769 return RPC_STATUS__ERROR;
770
771 data += need;
772 dsize -= need;
773
774 rsdata->frag_len = RPC_FRAG_LEN(RpcBufData(&rsdata->seg));
775
776 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
777 "STATEFUL: Fragment length: %u\n", rsdata->frag_len););
778 }
779
780 need = rsdata->frag_len - (RpcBufLen(&rsdata->seg) - RPC_FRAG_HDR_SIZE);
781 if (dsize < need)
782 {
783 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
784 "STATEFUL: Not enough data for fragment (%u): %u\n",
785 need, dsize););
786
787 RpcPreprocEvent(rconfig, rsdata, RPC_INCOMPLETE_SEGMENT);
788
789 if (RpcBufAdd(&rsdata->seg, data, dsize) != RPC_STATUS__SUCCESS)
790 return RPC_STATUS__ERROR;
791
792 break;
793 }
794
795 if (RpcBufAdd(&rsdata->seg, data, need) != RPC_STATUS__SUCCESS)
796 return RPC_STATUS__ERROR;
797
798 data += need;
799 dsize -= need;
800
801 status = RpcHandleFrag(rconfig, rsdata, RpcBufData(&rsdata->seg));
802
803 if (status == RPC_STATUS__ERROR)
804 return RPC_STATUS__ERROR;
805
806 if (status == RPC_STATUS__DEFRAG)
807 {
808 if (RpcBufLen(&rsdata->frag) != 0)
809 {
810 if (RpcPrepFrag(rsdata, p) != RPC_STATUS__SUCCESS)
811 return RPC_STATUS__ERROR;
812 }
813 else
814 {
815 if (RpcPrepSeg(rsdata, p) != RPC_STATUS__SUCCESS)
816 return RPC_STATUS__ERROR;
817 }
818
819 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
820 "STATEFUL: Last frag - calling detect\n"););
821
822 if ((dsize > 0) && rconfig->alert_multi)
823 RpcPreprocEvent(rconfig, rsdata, RPC_MULTIPLE_RECORD);
824
825 Detect(p);
826 RpcBufClean(&rsdata->frag);
827 }
828
829 RpcBufClean(&rsdata->seg);
830 }
831 }
832
833 if (RpcBufLen(&rsdata->frag) != 0)
834 {
835 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
836 "STATEFUL: Prepping Frag data: %u\n",
837 RpcBufLen(&rsdata->frag)););
838
839 if (RpcPrepFrag(rsdata, p) != RPC_STATUS__SUCCESS)
840 return RPC_STATUS__ERROR;
841 }
842 else if (RpcBufLen(&rsdata->seg) != 0)
843 {
844 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
845 "STATEFUL: Prepping Seg data: %u\n",
846 RpcBufLen(&rsdata->seg)););
847
848 if (RpcPrepSeg(rsdata, p) != RPC_STATUS__SUCCESS)
849 return RPC_STATUS__ERROR;
850 }
851
852 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
853 "STATEFUL: Success *****************************\n"););
854
855 return RPC_STATUS__SUCCESS;
856 }
857
RpcPrepRaw(const uint8_t * data,uint32_t fraglen,Packet * p)858 static RpcStatus RpcPrepRaw(const uint8_t *data, uint32_t fraglen, Packet *p)
859 {
860 int status;
861
862 status = SafeMemcpy(DecodeBuffer.data, data, RPC_FRAG_HDR_SIZE + fraglen,
863 DecodeBuffer.data, DecodeBuffer.data + sizeof(DecodeBuffer.data));
864
865 if (status != SAFEMEM_SUCCESS)
866 {
867 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
868 "STATEFUL: Failed to copy raw data to alt buffer\n"););
869 return RPC_STATUS__ERROR;
870 }
871
872 SetAltDecode((uint16_t)(RPC_FRAG_HDR_SIZE + fraglen));
873
874 return RPC_STATUS__SUCCESS;
875 }
876
RpcPrepFrag(RpcSsnData * rsdata,Packet * p)877 static RpcStatus RpcPrepFrag(RpcSsnData *rsdata, Packet *p)
878 {
879 int status;
880 uint32_t fraghdr = htonl(RpcBufLen(&rsdata->frag));
881
882 DecodeBuffer.data[0] = *((uint8_t *) &fraghdr);
883 DecodeBuffer.data[1] = *(((uint8_t *) &fraghdr) + 1);
884 DecodeBuffer.data[2] = *(((uint8_t *) &fraghdr) + 2);
885 DecodeBuffer.data[3] = *(((uint8_t *) &fraghdr) + 3);
886
887 DecodeBuffer.data[0] |= 0x80;
888
889 status = SafeMemcpy(DecodeBuffer.data+4, RpcBufData(&rsdata->frag),
890 RpcBufLen(&rsdata->frag), DecodeBuffer.data+4,
891 DecodeBuffer.data + sizeof(DecodeBuffer.data));
892
893 if (status != SAFEMEM_SUCCESS)
894 {
895 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
896 "STATEFUL: Failed to copy frag data to alt buffer\n"););
897 RpcBufClean(&rsdata->frag);
898 return RPC_STATUS__ERROR;
899 }
900
901 SetAltDecode((uint16_t)RpcBufLen(&rsdata->frag));
902
903 if (RpcBufLen(&rsdata->frag) > RPC_MAX_BUF_SIZE)
904 RpcBufClean(&rsdata->frag);
905
906 return RPC_STATUS__SUCCESS;
907 }
908
RpcPrepSeg(RpcSsnData * rsdata,Packet * p)909 static RpcStatus RpcPrepSeg(RpcSsnData *rsdata, Packet *p)
910 {
911 int status;
912
913 status = SafeMemcpy(DecodeBuffer.data, RpcBufData(&rsdata->seg),
914 RpcBufLen(&rsdata->seg), DecodeBuffer.data,
915 DecodeBuffer.data + sizeof(DecodeBuffer.data));
916
917 if (status != SAFEMEM_SUCCESS)
918 {
919 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
920 "STATEFUL: Failed to copy seg data to alt buffer\n"););
921 RpcBufClean(&rsdata->seg);
922 return RPC_STATUS__ERROR;
923 }
924
925 SetAltDecode((uint16_t)RpcBufLen(&rsdata->seg));
926
927 if (RpcBufLen(&rsdata->seg) > RPC_MAX_BUF_SIZE)
928 {
929 rsdata->ignore = (sizeof(uint32_t) + rsdata->frag_len) - RpcBufLen(&rsdata->seg);
930 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
931 "STATEFUL: Ignoring %u bytes\n", rsdata->ignore););
932 RpcBufClean(&rsdata->seg);
933 }
934
935 return RPC_STATUS__SUCCESS;
936 }
937
RpcHandleFrag(RpcDecodeConfig * rconfig,RpcSsnData * rsdata,const uint8_t * fragment)938 static RpcStatus RpcHandleFrag(RpcDecodeConfig *rconfig,
939 RpcSsnData *rsdata, const uint8_t *fragment)
940 {
941 int last_frag = fragment[0] & 0x80;
942 uint32_t frag_len = RPC_FRAG_LEN(fragment);
943
944 if (frag_len == 0)
945 RpcPreprocEvent(rconfig, rsdata, RPC_ZERO_LENGTH_FRAGMENT);
946
947 if (!last_frag)
948 RpcPreprocEvent(rconfig, rsdata, RPC_FRAG_TRAFFIC);
949
950 if ((RpcBufLen(&rsdata->frag) == 0) && last_frag)
951 return RPC_STATUS__DEFRAG;
952
953 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
954 "STATEFUL: Adding %u bytes to frag buffer\n", frag_len););
955
956 if (RpcBufAdd(&rsdata->frag,
957 fragment + sizeof(uint32_t), frag_len) != RPC_STATUS__SUCCESS)
958 {
959 return RPC_STATUS__ERROR;
960 }
961
962 if (last_frag)
963 return RPC_STATUS__DEFRAG;
964
965 return RPC_STATUS__SUCCESS;
966 }
967
RpcBufLen(RpcBuffer * buf)968 static inline uint32_t RpcBufLen(RpcBuffer *buf)
969 {
970 return buf == NULL ? 0 : buf->len;
971 }
972
RpcBufData(RpcBuffer * buf)973 static inline uint8_t * RpcBufData(RpcBuffer *buf)
974 {
975 return buf == NULL ? NULL : buf->data;
976 }
977
RpcBufAdd(RpcBuffer * buf,const uint8_t * data,uint32_t dsize)978 static RpcStatus RpcBufAdd(RpcBuffer *buf, const uint8_t *data, uint32_t dsize)
979 {
980 const uint32_t min_alloc = flush_size;
981 uint32_t alloc_size = dsize;
982 int status;
983
984 if (buf == NULL)
985 return RPC_STATUS__ERROR;
986
987 if (dsize == 0)
988 return RPC_STATUS__SUCCESS;
989
990 if (alloc_size < min_alloc)
991 alloc_size = min_alloc;
992
993 if (buf->data == NULL)
994 {
995 buf->data = (uint8_t *)RpcAlloc(alloc_size);
996 if (buf->data == NULL)
997 {
998 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
999 "STATEFUL: Failed to allocate buffer data\n"););
1000 return RPC_STATUS__ERROR;
1001 }
1002
1003 buf->size = alloc_size;
1004 }
1005 else if ((buf->len + dsize) > buf->size)
1006 {
1007 uint32_t new_size = buf->len + alloc_size;
1008 uint8_t *tmp = (uint8_t *)RpcAlloc(new_size);
1009
1010 if (tmp == NULL)
1011 {
1012 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
1013 "STATEFUL: Failed to reallocate buffer data\n"););
1014 RpcBufClean(buf);
1015 return RPC_STATUS__ERROR;
1016 }
1017
1018 status = SafeMemcpy(tmp, buf->data, buf->len, tmp, tmp + new_size);
1019 RpcFree(buf->data, buf->size);
1020 buf->data = tmp;
1021 buf->size = new_size;
1022
1023 if (status != SAFEMEM_SUCCESS)
1024 {
1025 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
1026 "STATEFUL: Failed to move buffer data\n"););
1027 RpcBufClean(buf);
1028 return RPC_STATUS__ERROR;
1029 }
1030 }
1031
1032 status = SafeMemcpy(buf->data + buf->len, data, dsize,
1033 buf->data + buf->len, buf->data + buf->size);
1034 if (status != SAFEMEM_SUCCESS)
1035 {
1036 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
1037 "STATEFUL: Failed to copy data to buffer\n"););
1038 RpcBufClean(buf);
1039 return RPC_STATUS__ERROR;
1040 }
1041
1042 buf->len += dsize;
1043
1044 return RPC_STATUS__SUCCESS;
1045 }
1046
RpcBufClean(RpcBuffer * buf)1047 static inline void RpcBufClean(RpcBuffer *buf)
1048 {
1049 if (buf->data != NULL)
1050 {
1051 RpcFree(buf->data, buf->size);
1052 buf->data = NULL;
1053 }
1054
1055 buf->len = 0;
1056 buf->size = 0;
1057 }
1058
RpcAlloc(uint32_t size)1059 static inline void * RpcAlloc(uint32_t size)
1060 {
1061 if ((rpc_memory + size) > rpc_memcap)
1062 {
1063 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "STATEFUL: Memcap exceeded\n"););
1064 return NULL;
1065 }
1066
1067 rpc_memory += size;
1068 return SnortAlloc(size);
1069 }
1070
RpcFree(void * data,uint32_t size)1071 static inline void RpcFree(void *data, uint32_t size)
1072 {
1073 if (data == NULL)
1074 return;
1075
1076 if (rpc_memory < size)
1077 rpc_memory = 0;
1078 else
1079 rpc_memory -= size;
1080
1081 free(data);
1082 }
1083
RpcSsnSetInactive(RpcSsnData * rsdata,Packet * p)1084 static inline void RpcSsnSetInactive(RpcSsnData *rsdata, Packet *p)
1085 {
1086 if (rsdata == NULL)
1087 return;
1088
1089 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "STATEFUL: Deactivating session: %p\n",
1090 rsdata););
1091
1092 stream_api->set_flush_point(p->ssnptr, SSN_DIR_FROM_SERVER, rsdata->ofp);
1093 RpcSsnClean(rsdata);
1094 }
1095
RpcSsnIsActive(RpcSsnData * rsdata)1096 static inline int RpcSsnIsActive(RpcSsnData *rsdata)
1097 {
1098 if (rsdata == NULL)
1099 return 0;
1100 return rsdata->active;
1101 }
1102
RpcSsnClean(RpcSsnData * rsdata)1103 static inline void RpcSsnClean(RpcSsnData *rsdata)
1104 {
1105 if (rsdata == NULL)
1106 return;
1107
1108 rsdata->active = 0;
1109 rsdata->frag_len = 0;
1110 rsdata->ignore = 0;
1111 RpcBufClean(&rsdata->seg);
1112 RpcBufClean(&rsdata->frag);
1113 }
1114
RpcSsnDataNew(Packet * p)1115 static RpcSsnData * RpcSsnDataNew(Packet *p)
1116 {
1117 RpcSsnData *rsdata = (RpcSsnData *)RpcAlloc(sizeof(RpcSsnData));
1118 if (rsdata != NULL)
1119 {
1120 char rdir = stream_api->get_reassembly_direction(p->ssnptr);
1121
1122 if (!(rdir & SSN_DIR_TO_SERVER))
1123 {
1124 rdir |= SSN_DIR_TO_SERVER;
1125 stream_api->set_reassembly(p->ssnptr, STREAM_FLPOLICY_FOOTPRINT,
1126 rdir, STREAM_FLPOLICY_SET_ABSOLUTE);
1127 }
1128
1129 rsdata->active = 1;
1130 rsdata->ofp = stream_api->get_flush_point(p->ssnptr, SSN_DIR_TO_SERVER);
1131
1132 stream_api->set_flush_point(p->ssnptr, SSN_DIR_TO_SERVER, flush_size);
1133 session_api->set_application_data(p->ssnptr,
1134 PP_RPCDECODE, (void *)rsdata, RpcSsnDataFree);
1135
1136 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "STATEFUL: Created new session: "
1137 "%p\n", rsdata););
1138 }
1139
1140 return rsdata;
1141 }
1142
RpcSsnDataFree(void * data)1143 static void RpcSsnDataFree(void *data)
1144 {
1145 RpcSsnData *rsdata = (RpcSsnData *)data;
1146
1147 if (data == NULL)
1148 return;
1149
1150 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "STATEFUL: Deleting session: %p\n",
1151 rsdata););
1152
1153 RpcSsnClean(rsdata);
1154 RpcFree(rsdata, sizeof(RpcSsnData));
1155 }
1156
1157 /* most significant bit */
1158 #define MSB 0x80000000
1159
1160 /*
1161 * For proto ref, see rfc1831 section 10 and page 445 UNP vol2
1162 *
1163 * check to make sure we've got enough data to process a record
1164 *
1165 * Where did the original 16 come from? It seems that it could be
1166 * a last frag of 0 length according to spec.
1167 *
1168 * The minimum "valid" packet for us is 8 fields * 4 bytes
1169 *
1170 * This decoder is ignorant of TCP state so we'll have to assume
1171 * that reassembled TCP stuff is reinjected to the preprocessor
1172 * chain
1173 *
1174 * This decoder is also ignorant of multiple RPC requests in a
1175 * single stream. To compensate, we can configure alerts
1176 *
1177 * Additionally, we don't do anything to verify that this is
1178 * really an RPC service port so we don't decode anything that
1179 * happens as a result
1180 *
1181 * From rfc1831:
1182 *
1183 * Fragment Header ( 1 flag bit, 31 bit uint )
1184 * RPC Body
1185 *
1186 * unsigned int xid
1187 * struct call_body {
1188 * unsigned int rpcvers; // must be equal to two (2)
1189 * unsigned int prog;
1190 * unsigned int vers;
1191 * unsigned int proc;
1192 * opaque_auth cred;
1193 * opaque_auth verf;
1194 * }
1195 */
1196
ConvertRPC(RpcDecodeConfig * rconfig,RpcSsnData * rsdata,Packet * p)1197 static int ConvertRPC(RpcDecodeConfig *rconfig, RpcSsnData *rsdata, Packet *p)
1198 {
1199 const uint8_t *data = p->data;
1200 uint32_t psize = p->dsize;
1201 uint8_t *norm_index;
1202 uint8_t *data_index; /* this is the index pointer to walk thru the data */
1203 uint8_t *data_end; /* points to the end of the payload for loop control */
1204 uint32_t length; /* length of current fragment */
1205 int last_fragment = 0; /* have we seen the last fragment sign? */
1206 uint32_t decoded_len; /* our decoded length is always atleast a 0 byte header */
1207 uint32_t fraghdr; /* Used to store the RPC fragment header data */
1208 int fragcount = 0; /* How many fragment counters have we seen? */
1209 int ret;
1210 uint8_t *decode_buf_start = DecodeBuffer.data;
1211 uint8_t *decode_buf_end = decode_buf_start + sizeof(DecodeBuffer.data);
1212
1213 if (psize < 32)
1214 {
1215 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Not enough data to decode: %u\n",
1216 psize););
1217 return 0;
1218 }
1219
1220 /* on match, normalize the data */
1221 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Got RPC traffic (%u bytes)!\n", psize););
1222
1223 /* cheesy alignment safe fraghdr = *(uint32_t *) data*/
1224 *((uint8_t *) &fraghdr) = data[0];
1225 *(((uint8_t *) &fraghdr) + 1) = data[1];
1226 *(((uint8_t *) &fraghdr) + 2) = data[2];
1227 *(((uint8_t *) &fraghdr) + 3) = data[3];
1228
1229
1230 /* The fragment header is 4 bytes in network byte order */
1231 fraghdr = ntohl(fraghdr);
1232 length = fraghdr & 0x7FFFFFFF;
1233
1234 /* Check to see if we are on the last fragment */
1235 if(fraghdr & MSB)
1236 {
1237 /* on match, normalize the data */
1238 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Found Last Fragment: %u!\n", length););
1239
1240 if((length + 4 != psize) && !(p->packet_flags & PKT_REBUILT_STREAM))
1241 {
1242 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "It's not the only thing in this buffer!"
1243 " length: %d psize: %d!\n", length, psize););
1244 return RPC_MULTIPLE_RECORD;
1245 }
1246 else if ( length == 0 )
1247 {
1248 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Zero-length RPC fragment detected."
1249 " length: %d psize: %d.\n", length, psize););
1250 return RPC_ZERO_LENGTH_FRAGMENT;
1251 }
1252 return 0;
1253 }
1254 else if (rconfig->alert_fragments)
1255 {
1256 RpcPreprocEvent(rconfig, rsdata, RPC_FRAG_TRAFFIC);
1257 }
1258
1259 norm_index = DecodeBuffer.data;
1260 data_index = (uint8_t *)data;
1261 data_end = (uint8_t *)data + psize;
1262
1263 /* now we know it's in fragmented records, 4 bytes of
1264 * header(of which the most sig bit fragment (0=yes 1=no).
1265 * The header is followed by the value move pointer up 4
1266 * bytes, we need to stuff header in first 4 bytes.
1267 * But the header has the total length...we don't know
1268 * until the end
1269 */
1270
1271 /* This is where decoded data will be written */
1272 norm_index += 4;
1273 decoded_len = 4;
1274
1275 /* always make sure that we have enough data to process atleast
1276 * the header and that we only process at most, one fragment
1277 */
1278
1279 while(((data_end - data_index) >= 4) && (last_fragment == 0))
1280 {
1281 /* get the fragment length (31 bits) and move the pointer to
1282 the start of the actual data */
1283
1284 *((uint8_t *) &fraghdr) = data_index[0];
1285 *(((uint8_t *) &fraghdr) + 1) = data_index[1];
1286 *(((uint8_t *) &fraghdr) + 2) = data_index[2];
1287 *(((uint8_t *) &fraghdr) + 3) = data_index[3];
1288
1289 fraghdr = ntohl(fraghdr);
1290 length = fraghdr & 0x7FFFFFFF;
1291
1292 if (length == 0)
1293 break;
1294
1295 /* move the current index into the packet past the
1296 fragment header */
1297 data_index += 4;
1298
1299 if(fraghdr & MSB)
1300 {
1301 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Last Fragment detected\n"););
1302 last_fragment = 1;
1303 }
1304
1305 if((length + decoded_len) < decoded_len)
1306 {
1307 /* don't allow integer overflow to confuse us. Should be
1308 * caught by length > psize but who knows when weird
1309 * psize's might be allowed */
1310
1311 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Integer Overflow"
1312 " field(%d) exceeds packet size(%d)\n",
1313 length, psize););
1314 return RPC_LARGE_FRAGSIZE;
1315 }
1316
1317 decoded_len += length;
1318
1319 if(length > psize)
1320 {
1321 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "Length of"
1322 " field(%d) exceeds packet size(%d)\n",
1323 length, psize););
1324 return RPC_INCOMPLETE_SEGMENT;
1325 }
1326 else if(decoded_len > psize)
1327 {
1328 /* The entire request is larger than our current packet
1329 * size
1330 */
1331 DEBUG_WRAP(DebugMessage(DEBUG_RPC, " Decoded Length (%d)"
1332 "exceeds packet size(%d)\n",
1333 decoded_len, psize););
1334 return RPC_LARGE_FRAGSIZE;
1335 }
1336 else if((data_index + length) > data_end)
1337 {
1338 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
1339 "returning LARGE_FRAGSIZE"
1340 "since we'd read past our end\n"););
1341 return RPC_LARGE_FRAGSIZE;
1342 }
1343 else
1344 {
1345 fragcount++;
1346
1347 DEBUG_WRAP(DebugMessage(DEBUG_RPC,
1348 "length: %d size: %d decoded_len: %d\n",
1349 length, psize, decoded_len););
1350
1351 ret = SafeMemcpy(norm_index, data_index, length, decode_buf_start, decode_buf_end);
1352 if (ret != SAFEMEM_SUCCESS)
1353 {
1354 return 0;
1355 }
1356
1357 norm_index += length;
1358 data_index += length;
1359 }
1360 }
1361
1362 /* rewrite the header on the request packet */
1363 /* move the fragment header back onto the data */
1364
1365 fraghdr = ntohl(decoded_len); /* size */
1366
1367 DecodeBuffer.data[0] = *((uint8_t *) &fraghdr);
1368 DecodeBuffer.data[1] = *(((uint8_t *) &fraghdr) + 1);
1369 DecodeBuffer.data[2] = *(((uint8_t *) &fraghdr) + 2);
1370 DecodeBuffer.data[3] = *(((uint8_t *) &fraghdr) + 3);
1371
1372 DecodeBuffer.data[0] |= 0x80; /* Mark as unfragmented */
1373
1374 /* is there another request encoded that is trying to evade us by doing
1375 *
1376 * frag last frag [ more data ]?
1377 */
1378 if(decoded_len + ((fragcount - 1) * 4) != psize)
1379 {
1380 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "decoded len does not compute: %d\n",
1381 decoded_len););
1382 return RPC_MULTIPLE_RECORD;
1383 }
1384
1385 DEBUG_WRAP(DebugMessage(DEBUG_RPC, "New size: %d\n", decoded_len);
1386 DebugMessage(DEBUG_RPC, "converted data:\n");
1387 //PrintNetData(stdout, data, decoded_len);
1388 );
1389
1390 SetAltDecode((uint16_t)decoded_len);
1391
1392 return 0;
1393 }
1394
enablePortStreamServices(struct _SnortConfig * sc,RpcDecodeConfig * rpc,tSfPolicyId policy_id)1395 static void enablePortStreamServices(struct _SnortConfig *sc, RpcDecodeConfig *rpc, tSfPolicyId policy_id)
1396 {
1397 uint32_t portNum;
1398
1399 if (rpc == NULL)
1400 return;
1401
1402 if (stream_api)
1403 {
1404 for (portNum = 0; portNum < MAXPORTS; portNum++)
1405 {
1406 if(rpc->RpcDecodePorts[(portNum/8)] & (1<<(portNum%8)))
1407 {
1408 //Add port the port
1409 stream_api->set_port_filter_status ( sc, IPPROTO_TCP, (uint16_t) portNum,
1410 PORT_MONITOR_SESSION, policy_id, 1 );
1411 stream_api->register_reassembly_port( NULL,
1412 (uint16_t) portNum,
1413 SSN_DIR_FROM_SERVER | SSN_DIR_FROM_CLIENT );
1414 session_api->enable_preproc_for_port( sc, PP_RPCDECODE, PROTO_BIT__TCP, (uint16_t) portNum );
1415 }
1416 }
1417 }
1418 }
1419
1420 #ifdef TARGET_BASED
_addServicesToStreamFilter(struct _SnortConfig * sc,tSfPolicyId policy_id)1421 static void _addServicesToStreamFilter(struct _SnortConfig *sc, tSfPolicyId policy_id)
1422 {
1423 if (stream_api)
1424 stream_api->set_service_filter_status
1425 (sc, rpc_decode_app_protocol_id, PORT_MONITOR_SESSION, policy_id, 1);
1426 }
1427 #endif
1428
RpcDecodeFreeConfigPolicy(tSfPolicyUserContextId rpc,tSfPolicyId policyId,void * pData)1429 static int RpcDecodeFreeConfigPolicy(tSfPolicyUserContextId rpc,tSfPolicyId policyId, void* pData )
1430 {
1431 RpcDecodeConfig *pPolicyConfig = (RpcDecodeConfig *)pData;
1432 sfPolicyUserDataClear (rpc, policyId);
1433 free(pPolicyConfig);
1434 return 0;
1435 }
1436
RpcDecodeFreeConfig(tSfPolicyUserContextId rpc)1437 static void RpcDecodeFreeConfig(tSfPolicyUserContextId rpc)
1438 {
1439
1440 if (rpc == NULL)
1441 return;
1442 sfPolicyUserDataFreeIterate (rpc, RpcDecodeFreeConfigPolicy);
1443 sfPolicyConfigDelete(rpc);
1444 }
1445
RpcDecodeCleanExit(int signal,void * unused)1446 static void RpcDecodeCleanExit(int signal, void *unused)
1447 {
1448 RpcDecodeFreeConfig(rpc_decode_config);
1449 rpc_decode_config = NULL;
1450 }
1451
1452 #ifdef SNORT_RELOAD
RpcDecodeReload(struct _SnortConfig * sc,char * args,void ** new_config)1453 static void RpcDecodeReload(struct _SnortConfig *sc, char *args, void **new_config)
1454 {
1455 tSfPolicyUserContextId rpc_decode_swap_config = (tSfPolicyUserContextId)*new_config;
1456 int policy_id = (int)getParserPolicy(sc);
1457 RpcDecodeConfig *pPolicyConfig = NULL;
1458
1459 if (!rpc_decode_swap_config)
1460 {
1461 rpc_decode_swap_config = sfPolicyConfigCreate();
1462 *new_config = rpc_decode_swap_config;
1463 }
1464 sfPolicyUserPolicySet (rpc_decode_swap_config, policy_id);
1465 pPolicyConfig = (RpcDecodeConfig *)sfPolicyUserDataGetCurrent(rpc_decode_swap_config);
1466 if (pPolicyConfig)
1467 {
1468 ParseError("RPC decode can only be configured once.\n");
1469 }
1470
1471 pPolicyConfig = (RpcDecodeConfig *)SnortAlloc(sizeof(RpcDecodeConfig));
1472 if (!pPolicyConfig)
1473 {
1474 ParseError("RPC Decode preprocessor: memory allocate failed.\n");
1475 }
1476 sfPolicyUserDataSetCurrent(rpc_decode_swap_config, pPolicyConfig);
1477
1478 /* parse the argument list into a list of ports to normalize */
1479 ParseRpcConfig(pPolicyConfig, args);
1480
1481 /* Set the preprocessor function into the function list */
1482 AddFuncToPreprocList(sc, PreprocRpcDecode, PRIORITY_APPLICATION, PP_RPCDECODE, PROTO_BIT__TCP);
1483
1484 enablePortStreamServices(sc, pPolicyConfig, policy_id);
1485
1486 #ifdef TARGET_BASED
1487 _addServicesToStreamFilter(sc, policy_id);
1488 #endif
1489 }
1490
RpcDecodeReloadSwap(struct _SnortConfig * sc,void * swap_config)1491 static void * RpcDecodeReloadSwap(struct _SnortConfig *sc, void *swap_config)
1492 {
1493 tSfPolicyUserContextId rpc_decode_swap_config = (tSfPolicyUserContextId)swap_config;
1494 tSfPolicyUserContextId old_config = rpc_decode_config;
1495
1496 if (rpc_decode_swap_config == NULL)
1497 return NULL;
1498
1499 rpc_decode_config = rpc_decode_swap_config;
1500 return (void *)old_config;
1501 }
1502
RpcDecodeReloadSwapFree(void * data)1503 static void RpcDecodeReloadSwapFree(void *data)
1504 {
1505 if (data == NULL)
1506 return;
1507
1508 RpcDecodeFreeConfig((tSfPolicyUserContextId)data);
1509 }
1510 #endif
1511
1512