Project

General

Profile

Actions

Bug #9087

open
JL JL

detect: bidirectional rule alerts on its toserver half when the toserver buffer has the higher progress

Bug #9087: detect: bidirectional rule alerts on its toserver half when the toserver buffer has the higher progress

Added by Jeff Lucovsky 1 day ago.

Status:
New
Priority:
Normal
Assignee:
Target version:
Affected Versions:
Effort:
Difficulty:
Label:
Needs backport

Description

A bidirectional (=>) rule can alert when only its toserver half matched. The toclient buffers are never inspected, so whatever the rule asks of the response is ignored.

Reproducer

One plain HTTP/1.1 exchange, GET /index.html with Host: example.com, answered by 200 OK.

alert http any any => any any (msg:"toclient condition cannot match"; flow:established; http.host; content:"example"; http.stat_msg; content:"ZZZZZZ"; sid:1;)
alert http any any => any any (msg:"control"; flow:established; http.uri; content:"index"; http.stat_msg; content:"ZZZZZZ"; sid:2;)

The status message is "OK", so neither rule can match. On main (d996d85dcf) sid 1 alerts once. sid 2, which only differs in the toserver buffer, correctly does not.

Cause

DetectRunTxInspectRule() declares a full match when its engine loop reaches the end of the list having matched at least once (src/detect.c:1495, engine == NULL && total_matches). While it inspects the toserver direction of a SIG_FLAG_TXBOTHDIR signature it steps over the toclient engines, and the only thing holding the match back is this, at src/detect.c:1481:

if (direction == 0 && engine->next == NULL) {
    // do not match yet on request only
    break;
}

That only works when the engine being stepped over is the last one in the list. Engines are sorted by progress, across both directions. For sid 1, --engine-analysis gives

http_host/toserver/http2/p1 | http_stat_msg/toclient/http2/p0 | http_stat_msg/toclient/http/p1 | http_host/toserver/http/p2

The HTTP/1 http.host engine has progress 2, the http.stat_msg engine progress 1, so a toserver engine is last. The loop steps over the toclient engine with engine->next != NULL, runs the toserver engine, matches, falls off the end and reports a full match. For sid 2, http.uri has progress 1 and a toclient engine ends the list, so the guard holds.

Any => rule whose toserver buffer has a higher progress value than its toclient buffer is affected; http.request_body (progress 3) with http.stat_code behaves the same way.

Impact

False positives: the rule fires on the request alone, before the response exists. It also means a toclient condition in such a rule has no effect at all.

Notes

Found while working on #7801, whose tests for a byte variable crossing directions failed for this reason and not for the one they were written for. Two such tests are kept on a suricata-verify branch as reproducers for the fix. The same code is in main-8.0.x (not run there).


Related issues 1 (1 open0 closed)

Related to Suricata - Feature #7801: rules: support multi-buffer byte variablesIn ReviewJeff LucovskyActions

JL Updated by Jeff Lucovsky 1 day ago Actions #1

  • Related to Feature #7801: rules: support multi-buffer byte variables added
Actions

Also available in: PDF Atom