Go to the documentation of this file.
28 #define BASE64_DECODE_MAX 65535
36 static const char decode_pattern[] =
"\\s*(bytes\\s+(\\d+),?)?"
37 "\\s*(offset\\s+(\\d+),?)?"
45 static void DetectBase64DecodeRegisterTests(
void);
52 "Decodes base64 encoded data.";
54 "/rules/base64-keywords.html#base64-decode";
59 DetectBase64DecodeRegisterTests;
72 printf(
"Input data:\n");
86 payload = payload + data->
offset;
92 printf(
"Decoding:\n");
97 uint32_t num_decoded =
98 SCBase64Decode(payload, decode_len, SCBase64ModeRFC4648, det_ctx->
base64_decoded);
104 printf(
"Decoded data:\n");
113 static int DetectBase64DecodeParse(
114 const char *
str, uint16_t *bytes, uint32_t *
offset, uint8_t *relative)
116 const char *bytes_str = NULL;
117 const char *offset_str = NULL;
118 const char *relative_str = NULL;
125 pcre2_match_data *match = NULL;
133 if (pcre2_substring_get_bynumber(match, 2, (PCRE2_UCHAR8 **)&bytes_str, &pcre2_len) == 0) {
135 SCLogError(
"Bad value for bytes: \"%s\"", bytes_str);
142 if (pcre2_substring_get_bynumber(match, 4, (PCRE2_UCHAR8 **)&offset_str, &pcre2_len) == 0) {
144 SCLogError(
"Bad value for offset: \"%s\"", offset_str);
151 if (pcre2_substring_get_bynumber(match, 5, (PCRE2_UCHAR8 **)&relative_str, &pcre2_len) ==
153 if (strcmp(relative_str,
"relative") == 0) {
157 SCLogError(
"Invalid argument: \"%s\"", relative_str);
165 pcre2_match_data_free(match);
170 if (bytes_str != NULL) {
171 pcre2_substring_free((PCRE2_UCHAR8 *)bytes_str);
173 if (offset_str != NULL) {
174 pcre2_substring_free((PCRE2_UCHAR8 *)offset_str);
176 if (relative_str != NULL) {
177 pcre2_substring_free((PCRE2_UCHAR8 *)relative_str);
180 pcre2_match_data_free(match);
190 uint8_t relative = 0;
196 if (!DetectBase64DecodeParse(
str, &bytes, &
offset, &relative)) {
262 static int g_http_header_buffer_id = 0;
264 static int DetectBase64TestDecodeParse(
void)
269 uint8_t relative = 0;
271 if (!DetectBase64DecodeParse(
"bytes 1", &bytes, &
offset, &relative)) {
274 if (bytes != 1 ||
offset != 0 || relative != 0) {
278 if (!DetectBase64DecodeParse(
"offset 9", &bytes, &
offset, &relative)) {
281 if (bytes != 0 ||
offset != 9 || relative != 0) {
285 if (!DetectBase64DecodeParse(
"relative", &bytes, &
offset, &relative)) {
288 if (bytes != 0 ||
offset != 0 || relative != 1) {
292 if (!DetectBase64DecodeParse(
"bytes 1, offset 2", &bytes, &
offset,
296 if (bytes != 1 ||
offset != 2 || relative != 0) {
300 if (!DetectBase64DecodeParse(
"bytes 1, offset 2, relative", &bytes, &
offset,
304 if (bytes != 1 ||
offset != 2 || relative != 1) {
308 if (!DetectBase64DecodeParse(
"offset 2, relative", &bytes, &
offset,
312 if (bytes != 0 ||
offset != 2 || relative != 1) {
317 if (DetectBase64DecodeParse(
"bytes 1, offset 2, relatve", &bytes, &
offset,
323 if (DetectBase64DecodeParse(
"byts 1, offset 2, relatve", &bytes, &
offset,
329 if (DetectBase64DecodeParse(
"bytes 1, offst 2, relatve", &bytes, &
offset,
335 if (DetectBase64DecodeParse(
"", &bytes, &
offset, &relative)) {
347 static int DetectBase64DecodeTestSetup(
void)
353 "base64_decode; content:\"content\"; "
362 static int DetectBase64DecodeTestDecode(
void)
370 uint8_t payload[] = {
371 'S',
'G',
'V',
's',
'b',
'G',
'8',
'g',
372 'V',
'2',
'9',
'y',
'b',
'G',
'Q',
'=',
375 memset(&
tv, 0,
sizeof(
tv));
382 "alert tcp any any -> any any (msg:\"base64 test\"; "
403 if (det_ctx != NULL) {
417 static int DetectBase64DecodeTestDecodeWithOffset(
void)
425 uint8_t payload[] = {
426 'a',
'a',
'a',
'a',
'a',
'a',
'a',
'a',
427 'S',
'G',
'V',
's',
'b',
'G',
'8',
'g',
428 'V',
'2',
'9',
'y',
'b',
'G',
'Q',
'=',
430 char decoded[] =
"Hello World";
432 memset(&
tv, 0,
sizeof(
tv));
439 "alert tcp any any -> any any (msg:\"base64 test\"; "
440 "base64_decode: offset 8; "
463 if (det_ctx != NULL) {
477 static int DetectBase64DecodeTestDecodeLargeOffset(
void)
485 uint8_t payload[] = {
486 'S',
'G',
'V',
's',
'b',
'G',
'8',
'g',
487 'V',
'2',
'9',
'y',
'b',
'G',
'Q',
'=',
490 memset(&
tv, 0,
sizeof(
tv));
498 "alert tcp any any -> any any (msg:\"base64 test\"; "
499 "base64_decode: bytes 16, offset 32; "
519 if (det_ctx != NULL) {
533 static int DetectBase64DecodeTestDecodeRelative(
void)
541 uint8_t payload[] = {
542 'a',
'a',
'a',
'a',
'a',
'a',
'a',
'a',
543 'S',
'G',
'V',
's',
'b',
'G',
'8',
'g',
544 'V',
'2',
'9',
'y',
'b',
'G',
'Q',
'=',
546 char decoded[] =
"Hello World";
548 memset(&
tv, 0,
sizeof(
tv));
555 "alert tcp any any -> any any (msg:\"base64 test\"; "
556 "content:\"aaaaaaaa\"; "
557 "base64_decode: relative; "
580 if (det_ctx != NULL) {
594 static void DetectBase64DecodeRegisterTests(
void)
598 UtRegisterTest(
"DetectBase64TestDecodeParse", DetectBase64TestDecodeParse);
599 UtRegisterTest(
"DetectBase64DecodeTestSetup", DetectBase64DecodeTestSetup);
601 DetectBase64DecodeTestDecode);
603 DetectBase64DecodeTestDecodeWithOffset);
605 DetectBase64DecodeTestDecodeLargeOffset);
607 DetectBase64DecodeTestDecodeRelative);
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
SigTableElmt * sigmatch_table
void(* Free)(DetectEngineCtx *, void *)
struct SigMatch_ * smlists_tail[DETECT_SM_LIST_MAX]
int DetectBase64DecodeDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, const uint8_t *payload, uint32_t payload_len)
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
main detection engine ctx
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
struct DetectBase64Decode_ DetectBase64Decode
void SigCleanSignatures(DetectEngineCtx *de_ctx)
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
int DetectBufferTypeGetByName(const char *name)
uint16_t base64_decode_max_len
#define PASS
Pass the test.
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Per thread variable structure.
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
int SigGroupCleanup(DetectEngineCtx *de_ctx)
#define BASE64_DECODE_MAX
SignatureInitData * init_data
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
#define DETECT_SM_LIST_NOTSET
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
#define SIGMATCH_OPTIONAL_OPT
#define SCLogError(...)
Macro used to log ERROR messages.
int SigMatchListSMBelongsTo(const Signature *s, const SigMatch *key_sm)
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
a single match condition for a signature
DetectEngineCtx * DetectEngineCtxInit(void)
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us.
SigMatch * SigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
void DetectBase64DecodeRegister(void)
#define DEBUG_VALIDATE_BUG_ON(exp)
void(* RegisterTests)(void)