detect/content: Negated endswith matches

Issue: 5541

This commit handles negated endswith matches.

(cherry picked from commit c083cbda33)
pull/8746/head
Jeff Lucovsky 4 years ago committed by Victor Julien
parent bb9880bad8
commit 0a9b7d0528

@ -279,7 +279,8 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx
const uint8_t *sbuffer = buffer + offset; const uint8_t *sbuffer = buffer + offset;
uint32_t sbuffer_len = depth - offset; uint32_t sbuffer_len = depth - offset;
uint32_t match_offset = 0; uint32_t match_offset = 0;
SCLogDebug("sbuffer_len %"PRIu32, sbuffer_len); SCLogDebug("sbuffer_len %" PRIu32 " depth: %" PRIu32 ", buffer_len: %" PRIu32,
sbuffer_len, depth, buffer_len);
#ifdef DEBUG #ifdef DEBUG
BUG_ON(sbuffer_len > buffer_len); BUG_ON(sbuffer_len > buffer_len);
#endif #endif
@ -309,66 +310,84 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx
} else { } else {
goto match; goto match;
} }
} else if (cd->flags & DETECT_CONTENT_NEGATED) {
SCLogDebug("content %"PRIu32" matched at offset %"PRIu32", but negated so no match", cd->id, match_offset);
/* don't bother carrying recursive matches now, for preceding
* relative keywords */
if (DETECT_CONTENT_IS_SINGLE(cd))
det_ctx->discontinue_matching = 1;
goto no_match;
} else { } else {
match_offset = (uint32_t)((found - buffer) + cd->content_len); match_offset = (uint32_t)((found - buffer) + cd->content_len);
SCLogDebug("content %"PRIu32" matched at offset %"PRIu32"", cd->id, match_offset); if (cd->flags & DETECT_CONTENT_NEGATED) {
det_ctx->buffer_offset = match_offset; SCLogDebug("content %" PRIu32 " matched at offset %" PRIu32
", but negated so no match",
if ((cd->flags & DETECT_CONTENT_ENDS_WITH) == 0 || match_offset == buffer_len) { cd->id, match_offset);
/* Match branch, add replace to the list if needed */ /* don't bother carrying recursive matches now, for preceding
if (cd->flags & DETECT_CONTENT_REPLACE) { * relative keywords */
if (inspection_mode == DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD) {
/* we will need to replace content if match is confirmed /* found a match but not at the end of the buffer */
* cast to non-const as replace writes to it. */ if (cd->flags & DETECT_CONTENT_ENDS_WITH) {
det_ctx->replist = DetectReplaceAddToList(det_ctx->replist, (uint8_t *)found, cd); if (sbuffer_len != match_offset) {
} else { SCLogDebug("content \"%s\" %" PRIu32 " matched at offset %" PRIu32
SCLogWarning(SC_ERR_INVALID_VALUE, "Can't modify payload without packet"); ", but not at end of buffer so match",
cd->content, cd->id, match_offset);
goto match;
} }
} }
if (DETECT_CONTENT_IS_SINGLE(cd))
det_ctx->discontinue_matching = 1;
goto no_match;
} else {
SCLogDebug("content %" PRIu32 " matched at offset %" PRIu32 "", cd->id,
match_offset);
det_ctx->buffer_offset = match_offset;
if ((cd->flags & DETECT_CONTENT_ENDS_WITH) == 0 || match_offset == buffer_len) {
/* Match branch, add replace to the list if needed */
if (cd->flags & DETECT_CONTENT_REPLACE) {
if (inspection_mode == DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD) {
/* we will need to replace content if match is confirmed
* cast to non-const as replace writes to it. */
det_ctx->replist = DetectReplaceAddToList(
det_ctx->replist, (uint8_t *)found, cd);
} else {
SCLogWarning(SC_ERR_INVALID_VALUE,
"Can't modify payload without packet");
}
}
/* if this is the last match we're done */ /* if this is the last match we're done */
if (smd->is_last) { if (smd->is_last) {
goto match; goto match;
} }
SCLogDebug("content %"PRIu32, cd->id); SCLogDebug("content %" PRIu32, cd->id);
KEYWORD_PROFILING_END(det_ctx, smd->type, 1); KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
/* see if the next buffer keywords match. If not, we will
* search for another occurrence of this content and see
* if the others match then until we run out of matches */
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd+1,
p, f, buffer, buffer_len, stream_start_offset, flags,
inspection_mode);
if (r == 1) {
SCReturnInt(1);
}
SCLogDebug("no match for 'next sm'");
if (det_ctx->discontinue_matching) { /* see if the next buffer keywords match. If not, we will
SCLogDebug("'next sm' said to discontinue this right now"); * search for another occurrence of this content and see
goto no_match; * if the others match then until we run out of matches */
} uint8_t r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd + 1, p, f,
buffer, buffer_len, stream_start_offset, flags, inspection_mode);
if (r == 1) {
SCReturnInt(1);
}
SCLogDebug("no match for 'next sm'");
/* no match and no reason to look for another instance */ if (det_ctx->discontinue_matching) {
if ((cd->flags & DETECT_CONTENT_WITHIN_NEXT) == 0) { SCLogDebug("'next sm' said to discontinue this right now");
SCLogDebug("'next sm' does not depend on me, so we can give up"); goto no_match;
det_ctx->discontinue_matching = 1; }
goto no_match;
}
SCLogDebug("'next sm' depends on me %p, lets see what we can do (flags %u)", cd, cd->flags); /* no match and no reason to look for another instance */
if ((cd->flags & DETECT_CONTENT_WITHIN_NEXT) == 0) {
SCLogDebug("'next sm' does not depend on me, so we can give up");
det_ctx->discontinue_matching = 1;
goto no_match;
}
SCLogDebug("'next sm' depends on me %p, lets see what we can do (flags %u)",
cd, cd->flags);
}
/* set the previous match offset to the start of this match + 1 */
prev_offset = (match_offset - (cd->content_len - 1));
SCLogDebug("trying to see if there is another match after prev_offset %" PRIu32,
prev_offset);
} }
/* set the previous match offset to the start of this match + 1 */
prev_offset = (match_offset - (cd->content_len - 1));
SCLogDebug("trying to see if there is another match after prev_offset %"PRIu32, prev_offset);
} }
} while(1); } while(1);

Loading…
Cancel
Save