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 Base64Decode(payload, decode_len, Base64ModeRFC4648, det_ctx->
base64_decoded);
104 printf(
"Decoded data:\n");
113 static int DetectBase64DecodeParse(
const char *
str, uint32_t *bytes,
114 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)) {
236 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
265 static int g_http_header_buffer_id = 0;
267 static int DetectBase64TestDecodeParse(
void)
272 uint8_t relative = 0;
274 if (!DetectBase64DecodeParse(
"bytes 1", &bytes, &
offset, &relative)) {
277 if (bytes != 1 ||
offset != 0 || relative != 0) {
281 if (!DetectBase64DecodeParse(
"offset 9", &bytes, &
offset, &relative)) {
284 if (bytes != 0 ||
offset != 9 || relative != 0) {
288 if (!DetectBase64DecodeParse(
"relative", &bytes, &
offset, &relative)) {
291 if (bytes != 0 ||
offset != 0 || relative != 1) {
295 if (!DetectBase64DecodeParse(
"bytes 1, offset 2", &bytes, &
offset,
299 if (bytes != 1 ||
offset != 2 || relative != 0) {
303 if (!DetectBase64DecodeParse(
"bytes 1, offset 2, relative", &bytes, &
offset,
307 if (bytes != 1 ||
offset != 2 || relative != 1) {
311 if (!DetectBase64DecodeParse(
"offset 2, relative", &bytes, &
offset,
315 if (bytes != 0 ||
offset != 2 || relative != 1) {
320 if (DetectBase64DecodeParse(
"bytes 1, offset 2, relatve", &bytes, &
offset,
326 if (DetectBase64DecodeParse(
"byts 1, offset 2, relatve", &bytes, &
offset,
332 if (DetectBase64DecodeParse(
"bytes 1, offst 2, relatve", &bytes, &
offset,
338 if (DetectBase64DecodeParse(
"", &bytes, &
offset, &relative)) {
350 static int DetectBase64DecodeTestSetup(
void)
356 "base64_decode; content:\"content\"; "
365 static int DetectBase64DecodeTestDecode(
void)
373 uint8_t payload[] = {
374 'S',
'G',
'V',
's',
'b',
'G',
'8',
'g',
375 'V',
'2',
'9',
'y',
'b',
'G',
'Q',
'=',
378 memset(&
tv, 0,
sizeof(
tv));
385 "alert tcp any any -> any any (msg:\"base64 test\"; "
406 if (det_ctx != NULL) {
420 static int DetectBase64DecodeTestDecodeWithOffset(
void)
428 uint8_t payload[] = {
429 'a',
'a',
'a',
'a',
'a',
'a',
'a',
'a',
430 'S',
'G',
'V',
's',
'b',
'G',
'8',
'g',
431 'V',
'2',
'9',
'y',
'b',
'G',
'Q',
'=',
433 char decoded[] =
"Hello World";
435 memset(&
tv, 0,
sizeof(
tv));
442 "alert tcp any any -> any any (msg:\"base64 test\"; "
443 "base64_decode: offset 8; "
466 if (det_ctx != NULL) {
480 static int DetectBase64DecodeTestDecodeLargeOffset(
void)
488 uint8_t payload[] = {
489 'S',
'G',
'V',
's',
'b',
'G',
'8',
'g',
490 'V',
'2',
'9',
'y',
'b',
'G',
'Q',
'=',
493 memset(&
tv, 0,
sizeof(
tv));
501 "alert tcp any any -> any any (msg:\"base64 test\"; "
502 "base64_decode: bytes 16, offset 32; "
522 if (det_ctx != NULL) {
536 static int DetectBase64DecodeTestDecodeRelative(
void)
544 uint8_t payload[] = {
545 'a',
'a',
'a',
'a',
'a',
'a',
'a',
'a',
546 'S',
'G',
'V',
's',
'b',
'G',
'8',
'g',
547 'V',
'2',
'9',
'y',
'b',
'G',
'Q',
'=',
549 char decoded[] =
"Hello World";
551 memset(&
tv, 0,
sizeof(
tv));
558 "alert tcp any any -> any any (msg:\"base64 test\"; "
559 "content:\"aaaaaaaa\"; "
560 "base64_decode: relative; "
583 if (det_ctx != NULL) {
597 static void DetectBase64DecodeRegisterTests(
void)
601 UtRegisterTest(
"DetectBase64TestDecodeParse", DetectBase64TestDecodeParse);
602 UtRegisterTest(
"DetectBase64DecodeTestSetup", DetectBase64DecodeTestSetup);
604 DetectBase64DecodeTestDecode);
606 DetectBase64DecodeTestDecodeWithOffset);
608 DetectBase64DecodeTestDecodeLargeOffset);
610 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
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)
#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)
uint32_t base64_decode_max_len
#define DEBUG_VALIDATE_BUG_ON(exp)
void(* RegisterTests)(void)