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