1 /*
2  ** Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3  ** Copyright (C) 1998-2013 Sourcefire, Inc.
4  **
5  ** This program is free software; you can redistribute it and/or modify
6  ** it under the terms of the GNU General Public License Version 2 as
7  ** published by the Free Software Foundation.  You may not use, modify or
8  ** distribute this program under any other version of the GNU General
9  ** Public License.
10  **
11  ** This program is distributed in the hope that it will be useful,
12  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  ** GNU General Public License for more details.
15  **
16  ** You should have received a copy of the GNU General Public License
17  ** along with this program; if not, write to the Free Software
18  ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 
21 /* sp_base64_data
22  *
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 
29 #include <sys/types.h>
30 #include <stdlib.h>
31 #include <ctype.h>
32 #ifdef HAVE_STRINGS_H
33 #include <strings.h>
34 #endif
35 #include <errno.h>
36 
37 #include "sf_types.h"
38 #include "snort_bounds.h"
39 #include "rules.h"
40 #include "decode.h"
41 #include "plugbase.h"
42 #include "parser.h"
43 #include "snort_debug.h"
44 #include "util.h"
45 #include "mstring.h"
46 
47 #include "snort.h"
48 #include "profiler.h"
49 #include "sp_base64_data.h"
50 #ifdef PERF_PROFILING
51 PreprocStats base64DataPerfStats;
52 extern PreprocStats ruleOTNEvalPerfStats;
53 #endif
54 
55 #include "detection_options.h"
56 #include "detection_util.h"
57 
58 extern char *file_name;  /* this is the file name from rules.c, generally used
59                             for error messages */
60 
61 extern int file_line;    /* this is the file line number from rules.c that is
62                             used to indicate file lines for error messages */
63 
64 static void Base64DataInit(struct _SnortConfig *, char *, OptTreeNode *, int);
65 void Base64DataParse(char *, OptTreeNode *);
66 int  Base64DataEval(void *option_data, Packet *p);
67 
68 /****************************************************************************
69  *
70  * Function: SetupBase64Data()
71  *
72  * Purpose: Load 'er up
73  *
74  * Arguments: None.
75  *
76  * Returns: void function
77  *
78  ****************************************************************************/
SetupBase64Data(void)79 void SetupBase64Data(void)
80 {
81     /* map the keyword to an initialization/processing function */
82     RegisterRuleOption("base64_data", Base64DataInit, NULL, OPT_TYPE_DETECTION, NULL);
83 #ifdef PERF_PROFILING
84     RegisterPreprocessorProfile("base64_data", &base64DataPerfStats, 3, &ruleOTNEvalPerfStats, NULL);
85 #endif
86 
87     DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: base64_data Setup\n"););
88 }
89 
90 
91 /****************************************************************************
92  *
93  * Function: Base64DataInit(struct _SnortConfig *, char *, OptTreeNode *, int protocol)
94  *
95  * Purpose: Generic rule configuration function.  Handles parsing the rule
96  *          information and attaching the associated detection function to
97  *          the OTN.
98  *
99  * Arguments: data => rule arguments/data
100  *            otn => pointer to the current rule option list node
101  *            protocol => protocol the rule is on (we don't care in this case)
102  *
103  * Returns: void function
104  *
105  ****************************************************************************/
Base64DataInit(struct _SnortConfig * sc,char * data,OptTreeNode * otn,int protocol)106 static void Base64DataInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol)
107 {
108     OptFpList *fpl;
109     if(otn->ds_list[PLUGIN_BASE64_DECODE] == NULL )
110     {
111         /*use base64_decode before base64_data*/
112         FatalError("%s(%d): base64_decode needs to be specified before base64_data in a rule\n",
113                 file_name, file_line);
114     }
115 
116     Base64DataParse(data, otn);
117 
118     fpl = AddOptFuncToList(Base64DataEval, otn);
119     fpl->type = RULE_OPTION_TYPE_BASE64_DATA;
120 
121 }
122 
123 
124 
125 /****************************************************************************
126  *
127  * Function: Base64DataParse(char *, OptTreeNode *)
128  *
129  * Purpose: This is the function that is used to process the option keyword's
130  *          arguments and attach them to the rule's data structures.
131  *
132  * Arguments: data => argument data
133  *            otn => pointer to the current rule's OTN
134  *
135  * Returns: void function
136  *
137  ****************************************************************************/
Base64DataParse(char * data,OptTreeNode * otn)138 void Base64DataParse(char *data, OptTreeNode *otn)
139 {
140     if (!IsEmptyStr(data))
141     {
142         FatalError("%s(%d): base64_data takes no arguments\n",
143                 file_name, file_line);
144     }
145 
146 }
147 
148 
149 /****************************************************************************
150  *
151  * Function: Base64DataEval(char *, OptTreeNode *, OptFpList *)
152  *
153  * Purpose: Use this function to perform the particular detection routine
154  *          that this rule keyword is supposed to encompass.
155  *
156  * Arguments: p => pointer to the decoded packet
157  *            otn => pointer to the current rule's OTN
158  *            fp_list => pointer to the function pointer list
159  *
160  * Returns: If the detection test fails, this function *must* return a zero!
161  *          On success, it calls the next function in the detection list
162  *
163  ****************************************************************************/
Base64DataEval(void * option_data,Packet * p)164 int Base64DataEval(void *option_data, Packet *p)
165 {
166     int rval = DETECTION_OPTION_NO_MATCH;
167     PROFILE_VARS;
168 
169     PREPROC_PROFILE_START(base64DataPerfStats);
170 
171     if ((p->dsize == 0) || !base64_decode_size )
172     {
173         PREPROC_PROFILE_END(base64DataPerfStats);
174         return rval;
175     }
176 
177     SetDoePtr(base64_decode_buf, DOE_BUF_STD);
178     SetAltDetect(base64_decode_buf, (uint16_t)base64_decode_size);
179     rval = DETECTION_OPTION_MATCH;
180 
181     PREPROC_PROFILE_END(base64DataPerfStats);
182     return rval;
183 }
184