Skip to content

Commit

Permalink
detect: improve tx_id guessing for unidirectional protocols
Browse files Browse the repository at this point in the history
So we get:
1. request arrives - buffered due to not ackd
2. response arrives, acks request - request is now parsed, response isn't
3. ack for response, response parsed. Then detect runs for request,
generates alert. We now have 2 txs. txid will be 0 from AppLayerParserGetTransactionInspectId

But txid 1 is unidirectional in the other way, so we can use txid 0
metadata for logging

Ticket: 7449
  • Loading branch information
catenacyber committed Dec 18, 2024
1 parent 27433df commit 1b99567
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
25 changes: 23 additions & 2 deletions src/detect.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,28 @@ static inline void DetectRunPrefilterPkt(
#endif
}

static bool isOnlyTxInDirection(Flow *f, uint64_t txid, uint8_t dir)
{
uint64_t tx_cnt = AppLayerParserGetTxCnt(f, f->alstate);
if (tx_cnt == txid + 1) {
// only live tx
return true;
}
if (tx_cnt == txid + 2) {
// 2 live txs, one after us
void *tx = AppLayerParserGetTx(f->proto, f->alproto, f->alstate, txid + 1);
if (tx) {
AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, tx);
// test if the other tx is unidirectional in the other way
if (txd &&
(AppLayerParserGetTxDetectFlags(txd, dir) & APP_LAYER_TX_SKIP_INSPECT_FLAG)) {
return true;
}
}
}
return false;
}

static inline void DetectRulePacketRules(
ThreadVars * const tv,
DetectEngineCtx * const de_ctx,
Expand Down Expand Up @@ -821,8 +843,7 @@ static inline void DetectRulePacketRules(
uint8_t dir = (p->flowflags & FLOW_PKT_TOCLIENT) ? STREAM_TOCLIENT : STREAM_TOSERVER;
txid = AppLayerParserGetTransactionInspectId(pflow->alparser, dir);
if ((s->alproto != ALPROTO_UNKNOWN && pflow->proto == IPPROTO_UDP) ||
(de_ctx->guess_applayer &&
AppLayerParserGetTxCnt(pflow, pflow->alstate) == txid + 1)) {
(de_ctx->guess_applayer && isOnlyTxInDirection(pflow, txid, dir))) {
// if there is a UDP specific app-layer signature,
// or only one live transaction
// try to use the good tx for the packet direction
Expand Down
8 changes: 4 additions & 4 deletions suricata.yaml.in
Original file line number Diff line number Diff line change
Expand Up @@ -1705,10 +1705,10 @@ detect:
inspection-recursion-limit: 3000
# maximum number of times a tx will get logged for rules without app-layer keywords
# stream-tx-log-limit: 4
# try to tie an app-layer transaction for rules without app-layer keywords
# if there is only one live transaction for the flow
# allows to log app-layer metadata in alert
# but the transaction may not be the relevant one.
# Try to guess an app-layer transaction for rules without app-layer keywords,
# ONLY IF there is just one live transaction for the flow.
# This allows logging app-layer metadata in alert - the transaction may not
# be the relevant one for the alert.
# guess-applayer-tx: no
# If set to yes, the loading of signatures will be made after the capture
# is started. This will limit the downtime in IPS mode.
Expand Down

0 comments on commit 1b99567

Please sign in to comment.