Project

General

Profile

Actions

Bug #7406

closed

eve: Alerts with app_proto=tls no longer logs the tls app data

Added by tug tugtug about 1 month ago. Updated 16 days ago.

Status:
Closed
Priority:
High
Target version:
Affected Versions:
Effort:
Difficulty:
Label:
C

Description

Prior to change of fixes to ticket #6846, the application data is reported in almost every alerts, now the application data is barely included in the alert events.

Upon reviewing the recent updates, I've identified two significant changes that compromise the consistency and accuracy of application data reporting:
1. Inconsistent reporting for multiple alerts that belong to a single packet.
With PACKET_ALERT_FLAG_TX, a UDP DNS packet will no longer include the DNS section in the connection alert, while the DNS alert will. Although this change may seem logical, it constitutes a breaking change in a minor version update.

2. Missing reporting of application data in TLS Alerts
The application data for TLS (and potentially other protocols) is no longer reported in the TLS alert. As one can see from the below code, the sslsession is the alstate set to the flow, but it would never translates to PACKET_ALERT_FLAG_TX.

        uint64_t txid = PACKET_ALERT_NOTX;
        if ((alert_flags & PACKET_ALERT_FLAG_STREAM_MATCH) ||
                (s->alproto != ALPROTO_UNKNOWN && pflow->proto == IPPROTO_UDP)) {
            // if there is a stream match (TCP), or
            // a UDP specific app-layer signature,
            // try to use the last tx
            if (pflow->alstate) {
                txid = AppLayerParserGetTxCnt(pflow, pflow->alstate) - 1;
                alert_flags |= PACKET_ALERT_FLAG_TX;
            }
        }

Related issues 1 (0 open1 closed)

Related to Suricata - Bug #7199: detect: missing app-layer metadata in alertsClosedPhilippe AntoineActions
Actions #1

Updated by Philippe Antoine about 1 month ago

  • Related to Bug #7199: detect: missing app-layer metadata in alerts added
Actions #2

Updated by Philippe Antoine about 1 month ago

What rules are you using ?

You should still get DNS metadata if you use dns keywords (and same for TLS)

Actions #3

Updated by tug tugtug about 1 month ago ยท Edited

This is the simplified version of my rules:

reject ip $HOME_NET any -> any any (msg:"Blocked - Has Blocked"; flow: to_server; flowbits:isset,HAS.BLOCKED.ALERT; noalert; classtype:block; sid:1; rev:1; gid:1111;)
reject tls $HOME_NET any -> any any (msg:"Blocked - TLS"; flow:to_server; flowbits:isnotset,HAS.ALLOWED.ALERT.TLS; flowbits:isnotset,HAS.BLOCKED.ALERT; luajit:tls.lua; flowbits:set,HAS.BLOCKED.ALERT; classtype:block-tls; sid:5; rev:2; gid:1111;)
reject dns $HOME_NET any -> any any (msg:"Blocked - DNS"; flow:to_server; luajit:dns.lua; flowbits:set,HAS.BLOCKED.ALERT; flowbits:set,HAS.BLOCKED.ALERT.DNS; classtype:block-dns; sid:2; rev:3; gid:131415;)
alert ip $HOME_NET any -> any any (msg:"Allowed Connection Attempt"; flow:to_server,not_established; flowbits:isset,CONNECTION_ATTEMPT; flowbits:isnotset,HAS.BLOCKED.ALERT; flowbits:set,HAS.ALLOWED.ALERT; flowbits:unset,CONNECTION_ATTEMPT; classtype:allow; sid:4; rev:5;)
alert dns $HOME_NET any -> any any (msg:"Access Control Allowed - DNS"; flow:to_server; flowbits:isnotset,HAS.BLOCKED.ALERT; flowbits:isnotset,HAS.BLOCKED.ALERT.DNS; dns.query; bsize:>0; flowbits:set,HAS.ALLOWED.ALERT; classtype:allow; sid:6; rev:4;)
alert tls $HOME_NET any -> any any (msg:"Allowed - TLS"; flow:to_server;  flowbits:isnotset,HAS.BLOCKED.ALERT; flowbits:isnotset,HAS.ALLOWED.ALERT.TLS; flowbits:set,HAS.ALLOWED.ALERT.TLS; classtype:allow; sid:7; rev:2;)

Tls:

In the test of tls, the lua would return allow for both the ip and tls.
I added below print above the AlertQueueAppend in DetectRulePacketRules :

SCLogInfo("AlertQueueAppend with %lu, flags 0x%x, alstate %p", txid, alert_flags, pflow ? pflow->alstate : NULL);

The tls packets tested were a simple google.com session handshake.


The logs look like this:
  • For the connection/ip alert:
    [30] 22/11/2024 -- 19:58:41 - (detect.c:831) <Info> (DetectRulePacketRules) -- AlertQueueAppend with 18446744073709551615, flags 0x0, alstate (nil)
    
  • For the tls:
    [30] 22/11/2024 -- 19:58:41 - (detect.c:831) <Info> (DetectRulePacketRules) -- AlertQueueAppend with 18446744073709551615, flags 0x0, alstate 0x7668e8405e40
    

Dns

With the same log above + a similar log in DetectRunTx before AlertQueueAppend, and the dns lua would block.

The dns udp packet:

0000   45 00 00 37 4a d6 40 00 40 11 c3 c9 0a 0a 0c 02
0010   0a 0a 0c 01 89 95 00 35 00 23 18 82 ec 36 01 00
0020   00 01 00 00 00 00 00 00 05 63 68 65 61 74 03 63
0030   6f 6d 00 00 01 00 01

The logs look like this:

  • For the connection/ip alert:
    [30] 22/11/2024 -- 20:10:15 - (detect.c:831) <Info> (DetectRulePacketRules) -- AlertQueueAppend with 18446744073709551615, flags 0x0, alstate 0x7d662c401e90
    
  • For the dns alert:
    [30] 22/11/2024 -- 20:10:15 - (detect.c:1606) <Info> (DetectRunTx) -- Tx AlertQueueAppend with 0, flags 0xa
    

So for the ip/connection alert, the PACKET_ALERT_FLAG_TX is not set, and thus no dns app data. I mentioned this might be the new expected behaviour as the ip rule does not contain the dns keyword, but it is still a backward incompatible change that would break many eve log dependent services. I don't see why we couldn't log the application data in this case, as it is a single packet.

Actions #5

Updated by tug tugtug about 1 month ago

I have tested the patch, the patch crashes when pflow is NULL. Since the condition would never get the flag set when pflow->alstate is NULL, I moved the pflow and pflow->alstate check outside, this is more readable than before and avoids the crashes.
This fix now works for both of my cases.

        if (pflow && pflow->alstate) {
            if ((alert_flags & PACKET_ALERT_FLAG_STREAM_MATCH) ||
                (s->alproto != ALPROTO_UNKNOWN && pflow->proto == IPPROTO_UDP) ||
                (AppLayerParserGetTxCnt(pflow, pflow->alstate) == 1))
            {
                // if there is a stream match (TCP), or
                // a UDP specific app-layer signature,
                // or only one transaction
                // try to use the good tx for the packet direction
                uint8_t dir =
                        (p->flowflags & FLOW_PKT_TOCLIENT) ? STREAM_TOCLIENT : STREAM_TOSERVER;
                txid = AppLayerParserGetTransactionInspectId(pflow->alparser, dir);
                alert_flags |= PACKET_ALERT_FLAG_TX;
            }
        }

Actions #6

Updated by Philippe Antoine 30 days ago

Indeed, I saw that as well and did https://github.com/OISF/suricata/pull/12158

Actions #7

Updated by tug tugtug 30 days ago

Yeah, I found it on github and made a comment there too. I just think the if layout can be re-organized a bit to be more readable.

Actions #8

Updated by Philippe Antoine 30 days ago

  • Target version changed from TBD to 8.0.0-beta1

Thanks for testing the fix

Actions #9

Updated by tug tugtug 30 days ago

thanks a lot for the prompt fix! https://github.com/OISF/suricata/pull/12161 LGTM.

Actions #10

Updated by Philippe Antoine 25 days ago

  • Status changed from New to In Review
Actions #11

Updated by Philippe Antoine 16 days ago

  • Status changed from In Review to Closed
Actions

Also available in: Atom PDF