From: Jeff Lucovsky Date: Tue, 17 Dec 2024 12:56:42 +0000 (-0500) Subject: detect/content: account for distance variables X-Git-Tag: suricata-7.0.11~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F13440%2Fhead;p=thirdparty%2Fsuricata.git detect/content: account for distance variables Under some cases (below), the depth and offset values are used twice. This commit disregards the distance variable (if any), when computing the final depth. These rules are logically equivalent:: 1. alert tcp any any -> any 8080 (msg:"distance name"; flow:to_server; content:"Authorization:"; content:"5f71ycy"; distance:0; byte_extract:1,0,option_len,string,relative; content:!"|38|"; distance:option_len; within:1; content:"|37|"; distance:-1; within:1; content:"|49|"; distance:option_len; within:1; sid:1;) 2. alert tcp any any -> any 8080 (msg:"distance number"; flow:to_server; content:"Authorization:"; content:"5f71ycy"; distance:0; byte_extract:1,0,option_len,string,relative; content:!"|38|"; distance:7; within:1; content:"|37|"; distance:-1; within:1; content:"|49|"; distance:option_len; within:1; sid:2;) The differences: Rule 1: content:!"|38|"; distance:option_len; within:1; //option_len == 7 Rule 2: content:!"|38|"; distance:7; within:1; Without this commit, rule 2 triggers an alert but rule 1 doesn't. Issue: 7390 (cherry picked from commit ace0d3763674a8dc624ad1f1744ea7442cd86d43) --- diff --git a/src/detect-content.c b/src/detect-content.c index be1f125594..4313684622 100644 --- a/src/detect-content.c +++ b/src/detect-content.c @@ -603,7 +603,8 @@ static void PropagateLimits(Signature *s, SigMatch *sm_head) VALIDATE(depth + cd->within + dist >= 0 && depth + cd->within + dist <= UINT16_MAX); depth = cd->depth = (uint16_t)(depth + cd->within + dist); - } else { + } else if ((cd->flags & DETECT_CONTENT_DISTANCE_VAR) == 0) { + // we cannot know the depth yet if it comes from a var SCLogDebug("offset %u + cd->within %u", offset, cd->within); VALIDATE(depth + cd->within >= 0 && depth + cd->within <= UINT16_MAX); depth = cd->depth = (uint16_t)(offset + cd->within); diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index 3ca221235c..12ce511c9b 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -251,8 +251,8 @@ uint8_t DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThrea /* If the value came from a variable, make sure to adjust the depth so it's relative * to the offset value. */ - if (cd->flags & (DETECT_CONTENT_DISTANCE_VAR|DETECT_CONTENT_OFFSET_VAR|DETECT_CONTENT_DEPTH_VAR)) { - depth += offset; + if (cd->flags & (DETECT_CONTENT_OFFSET_VAR | DETECT_CONTENT_DEPTH_VAR)) { + depth += offset; } /* update offset with prev_offset if we're searching for