detect/bsize: Semantic validation of bsize values

This commit adds validation of the bsize value(s) with the available
buffer size. Signatures are flagged if the bsize and buffer size are
incompatible.

Issue: 3682
pull/8165/head
Jeff Lucovsky 3 years ago committed by Victor Julien
parent 25c0a6ea7c
commit ecfdc24e08

@ -1,4 +1,4 @@
/* Copyright (C) 2017-2020 Open Information Security Foundation
/* Copyright (C) 2017-2022 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
@ -61,6 +61,8 @@ void DetectBsizeRegister(void)
#endif
}
static int SigParseGetMaxBsize(DetectU64Data *bsz);
/** \brief bsize match function
*
* \param ctx match ctx
@ -124,12 +126,27 @@ static DetectU64Data *DetectBsizeParse(const char *str)
return DetectU64Parse(str);
}
static int SigParseGetMaxBsize(DetectU64Data *bsz)
{
switch (bsz->mode) {
case DETECT_UINT_LT:
case DETECT_UINT_EQ:
return bsz->arg1;
case DETECT_UINT_RA:
return bsz->arg2;
case DETECT_UINT_GT:
default:
SCReturnInt(-2);
}
SCReturnInt(-1);
}
/**
* \brief this function is used to parse bsize data into the current signature
*
* \param de_ctx pointer to the Detection Engine Context
* \param s pointer to the Current Signature
* \param bsizestr pointer to the user provided bsize options
* \param sizestr pointer to the user provided bsize options
*
* \retval 0 on Success
* \retval -1 on Failure
@ -149,6 +166,24 @@ static int DetectBsizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char *
DetectU64Data *bsz = DetectBsizeParse(sizestr);
if (bsz == NULL)
goto error;
const int bsize = SigParseGetMaxBsize(bsz);
uint64_t needed;
if (bsize >= 0) {
int len, offset;
SigParseRequiredContentSize(s, bsize, list, &len, &offset);
SCLogDebug("bsize: %d; len: %d; offset: %d [%s]", bsize, len, offset, s->sig_str);
needed = len;
if (len > bsize) {
goto value_error;
}
if ((len + offset) > bsize) {
needed += offset;
goto value_error;
}
}
sm = SigMatchAlloc();
if (sm == NULL)
goto error;
@ -159,6 +194,19 @@ static int DetectBsizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char *
SCReturnInt(0);
value_error:
if (bsz->mode == DETECT_UINT_RA) {
SCLogError(SC_ERR_INVALID_SIGNATURE,
"signature can't match as required content length %" PRIu64
" exceeds bsize range: %" PRIu64 "-%" PRIu64,
needed, bsz->arg1, bsz->arg2);
} else {
SCLogError(SC_ERR_INVALID_SIGNATURE,
"signature can't match as required content length %" PRIu64 " exceeds bsize value: "
"%" PRIu64,
needed, bsz->arg1);
}
error:
DetectBsizeFree(de_ctx, bsz);
SCReturnInt(-1);

@ -1,4 +1,4 @@
/* Copyright (C) 2017-2020 Open Information Security Foundation
/* Copyright (C) 2017-2022 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
@ -118,41 +118,42 @@ static int DetectBsizeTest04(void)
static int DetectBsizeSigTest01(void)
{
#if 0
TEST_OK("alert http any any -> any any (http_request_line; bsize:10; sid:1;)");
TEST_OK("alert http any any -> any any (file_data; bsize:>1000; sid:2;)");
TEST_FAIL("alert tcp any any -> any any (content:\"abc\"; bsize:10; sid:3;)");
TEST_FAIL("alert http any any -> any any (content:\"GET\"; http_method; bsize:10; sid:4;)");
TEST_FAIL("alert http any any -> any any (http_request_line; content:\"GET\"; bsize:<10>; sid:5;)");
/* bsize validation with buffer */
TEST_OK("alert http any any -> any any (http.uri; content:\"/index.php\"; bsize:>1024; "
"sid:6;)");
TEST_OK("alert http any any -> any any (http.uri; content:\"abdcef\"; content: \"g\"; bsize:1; "
"sid:7;)");
TEST_OK("alert http any any -> any any (http.uri; content:\"abdcef\"; content: \"g\"; bsize:4; "
"sid:8;)");
TEST_OK("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:<20; "
" sid:9;)");
TEST_OK("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:15<>25; "
"sid:10;)");
TEST_OK("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:10<>15; "
"sid:13;)");
TEST_FAIL("alert tcp any any -> any any (content:\"abc\"; bsize:10; sid:3;)");
TEST_FAIL("alert http any any -> any any (content:\"GET\"; http_method; bsize:10; sid:4;)");
TEST_FAIL("alert http any any -> any any (http_request_line; content:\"GET\"; bsize:<10>; "
"sid:5;)");
TEST_FAIL("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:2; "
"sid:11;)");
TEST_FAIL("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:<13; "
"sid:12;)");
TEST_OK("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:10<>15; "
"sid:13;)");
TEST_FAIL(
"alert http any any -> any any (http.uri; content:\"abcdef\"; content: \"g\"; bsize:1; "
"sid:7;)");
TEST_FAIL(
"alert http any any -> any any (http.uri; content:\"abcdef\"; content: \"g\"; bsize:4; "
"sid:8;)");
TEST_FAIL("alert http any any -> any any (http.uri; content:\"abcdefghi123456\"; offset:12; "
"bsize:3; sid:14;)");
TEST_FAIL("alert http any any -> any any (http.uri; content:\"abc\"; offset:3; depth:3; "
"bsize:3; sid:15;)");
TEST_FAIL("alert http any any -> any any (http.uri; content:\"abdcef\"; content: \"gh\"; "
TEST_FAIL("alert http any any -> any any (http.uri; content:\"abcdef\"; content: \"gh\"; "
"bsize:1; sid:16;)");
TEST_FAIL("alert http any any -> any any (http.uri; content:\"abc\"; offset:3; bsize:3; "
"sid:17;)");
#endif
TEST_FAIL("alert http any any -> any any (http.uri; content:\"abc\"; offset:65535; bsize:3; "
"sid:18;)");
PASS;

Loading…
Cancel
Save