1 /* Copyright (C) 2007-2020 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18 /**
19 * \file
20 *
21 * \author Victor Julien <victor@inliniac.net>
22 *
23 * Implements the to_md5 transformation keyword
24 */
25
26 #include "suricata-common.h"
27
28 #include "detect.h"
29 #include "detect-engine.h"
30 #include "detect-engine-prefilter.h"
31 #include "detect-parse.h"
32 #include "detect-transform-md5.h"
33
34 #include "util-unittest.h"
35 #include "util-print.h"
36
37 static int DetectTransformToMd5Setup (DetectEngineCtx *, Signature *, const char *);
38 #ifdef HAVE_NSS
39 #ifdef UNITTESTS
40 static void DetectTransformToMd5RegisterTests(void);
41 #endif
42 static void TransformToMd5(InspectionBuffer *buffer, void *options);
43 #endif
44
DetectTransformMd5Register(void)45 void DetectTransformMd5Register(void)
46 {
47 sigmatch_table[DETECT_TRANSFORM_MD5].name = "to_md5";
48 sigmatch_table[DETECT_TRANSFORM_MD5].desc =
49 "convert to md5 hash of the buffer";
50 sigmatch_table[DETECT_TRANSFORM_MD5].url =
51 "/rules/transforms.html#to-md5";
52 sigmatch_table[DETECT_TRANSFORM_MD5].Setup =
53 DetectTransformToMd5Setup;
54 #ifdef HAVE_NSS
55 sigmatch_table[DETECT_TRANSFORM_MD5].Transform =
56 TransformToMd5;
57 #ifdef UNITTESTS
58 sigmatch_table[DETECT_TRANSFORM_MD5].RegisterTests =
59 DetectTransformToMd5RegisterTests;
60 #endif
61 #endif
62 sigmatch_table[DETECT_TRANSFORM_MD5].flags |= SIGMATCH_NOOPT;
63 }
64
65 #ifndef HAVE_NSS
DetectTransformToMd5Setup(DetectEngineCtx * de_ctx,Signature * s,const char * nullstr)66 static int DetectTransformToMd5Setup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr)
67 {
68 SCLogError(SC_ERR_NO_MD5_SUPPORT, "no MD5 calculation support built in, "
69 "needed for to_md5 keyword");
70 return -1;
71 }
72 #else
73 /**
74 * \internal
75 * \brief Apply the nocase keyword to the last pattern match, either content or uricontent
76 * \param det_ctx detection engine ctx
77 * \param s signature
78 * \param nullstr should be null
79 * \retval 0 ok
80 * \retval -1 failure
81 */
DetectTransformToMd5Setup(DetectEngineCtx * de_ctx,Signature * s,const char * nullstr)82 static int DetectTransformToMd5Setup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr)
83 {
84 SCEnter();
85 int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_MD5, NULL);
86 SCReturnInt(r);
87 }
88
TransformToMd5(InspectionBuffer * buffer,void * options)89 static void TransformToMd5(InspectionBuffer *buffer, void *options)
90 {
91 const uint8_t *input = buffer->inspect;
92 const uint32_t input_len = buffer->inspect_len;
93 uint8_t output[MD5_LENGTH];
94
95 //PrintRawDataFp(stdout, input, input_len);
96
97 HASHContext *ctx = HASH_Create(HASH_AlgMD5);
98 if (ctx) {
99 HASH_Begin(ctx);
100 HASH_Update(ctx, input, input_len);
101 unsigned int len = 0;
102 HASH_End(ctx, output, &len, sizeof(output));
103 HASH_Destroy(ctx);
104
105 InspectionBufferCopy(buffer, output, sizeof(output));
106 }
107 }
108
109 #ifdef UNITTESTS
DetectTransformToMd5Test01(void)110 static int DetectTransformToMd5Test01(void)
111 {
112 const uint8_t *input = (const uint8_t *)" A B C D ";
113 uint32_t input_len = strlen((char *)input);
114
115 InspectionBuffer buffer;
116 InspectionBufferInit(&buffer, 8);
117 InspectionBufferSetup(NULL, -1, &buffer, input, input_len);
118 PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
119 TransformToMd5(&buffer, NULL);
120 PrintRawDataFp(stdout, buffer.inspect, buffer.inspect_len);
121 InspectionBufferFree(&buffer);
122 PASS;
123 }
124
DetectTransformToMd5RegisterTests(void)125 static void DetectTransformToMd5RegisterTests(void)
126 {
127 UtRegisterTest("DetectTransformToMd5Test01",
128 DetectTransformToMd5Test01);
129 }
130 #endif
131 #endif
132