diff --git a/doc/userguide/output/eve/eve-json-format.rst b/doc/userguide/output/eve/eve-json-format.rst index 92193453af..27ceed012d 100644 --- a/doc/userguide/output/eve/eve-json-format.rst +++ b/doc/userguide/output/eve/eve-json-format.rst @@ -999,6 +999,118 @@ Example of a DNS answer with "grouped" format:: } } +Event type: LLMNR +----------------- + +LLMNR (Link-Local Multicast Name Resolution, RFC 4795) is a protocol +that allows hosts on the same local link to perform name resolution. +It uses DNS message format, but operates on multicast (224.0.0.252 for +IPv4, ff02::1:3 for IPv6) over UDP and TCP port 5355. + +Suricata logs both requests and responses as separate events. For UDP, +queries are sent to multicast and responses come back as unicast from +the responder's IP, resulting in separate flows. + +Fields +~~~~~~ + +Outline of fields seen in LLMNR events: + +* "type": Indicating LLMNR message type, can be "request" or "response" +* "id": On-wire LLMNR transaction identifier +* "queries": A list of query objects, each containing "rrname" and "rrtype" +* "answers": A list of answer objects, each containing "rrname", "rrtype" with "rdata" +* "authorities": A list of authority objects +* "additionals": A list of additional objects + +Examples +~~~~~~~~ + +Example of an LLMNR request for the A record of "hs2011":: + + "llmnr": { + "type": "request", + "tx_id": 0, + "id": 49985, + "opcode": 0, + "queries": [ + { + "rrname": "hs2011", + "rrtype": "a" + } + ] + } + +Example of an LLMNR response with an A record answer:: + + "llmnr": { + "type": "response", + "tx_id": 0, + "id": 49985, + "opcode": 0, + "queries": [ + { + "rrname": "hs2011", + "rrtype": "a" + } + ], + "answers": [ + { + "rrname": "HS2011", + "a": "192.168.10.101" + } + ] + } + +Example of an LLMNR NXDOMAIN response:: + + "llmnr": { + "type": "response", + "tx_id": 0, + "id": 12345, + "opcode": 0, + "rcode": "NXDOMAIN", + "queries": [ + { + "rrname": "unknown-host", + "rrtype": "a" + } + ] + } + +Example of an LLMNR response with NS authority and additional records:: + + "llmnr": { + "type": "response", + "tx_id": 0, + "id": 54321, + "opcode": 0, + "queries": [ + { + "rrname": "server.local", + "rrtype": "a" + } + ], + "answers": [ + { + "rrname": "server.local", + "a": "192.168.1.100" + } + ], + "authorities": [ + { + "rrname": "local", + "ns": "ns.local" + } + ], + "additionals": [ + { + "rrname": "ns.local", + "a": "192.168.1.200" + } + ] + } + Event type: FTP --------------- diff --git a/doc/userguide/rules/index.rst b/doc/userguide/rules/index.rst index 8433702ee0..04ea736c9d 100644 --- a/doc/userguide/rules/index.rst +++ b/doc/userguide/rules/index.rst @@ -16,6 +16,7 @@ Suricata Rules file-keywords dns-keywords mdns-keywords + llmnr-keywords tls-keywords ssh-keywords ja-keywords diff --git a/doc/userguide/rules/llmnr-keywords.rst b/doc/userguide/rules/llmnr-keywords.rst new file mode 100644 index 0000000000..83ab7e3ffd --- /dev/null +++ b/doc/userguide/rules/llmnr-keywords.rst @@ -0,0 +1,105 @@ +LLMNR Keywords +============== + +Suricata supports sticky buffers for matching on specific fields +in LLMNR (Link-Local Multicast Name Resolution) messages. + +Note that sticky buffers are expected to be followed by one or more +:doc:`payload-keywords`. + +llmnr.queries.rrname +-------------------- + +``llmnr.queries.rrname`` is a sticky buffer that is used to look at the +name field in LLMNR query resource records. + +``llmnr.queries.rrname`` will look at both requests and responses, so +``flow`` is recommended to confine to a specific direction. + +The buffer being matched on contains the complete re-assembled +resource name, for example "workstation.local". + +``llmnr.queries.rrname`` supports :doc:`multi-buffer-matching`. + +.. container:: example-rule + + alert llmnr any any -> any 5355 (msg:"LLMNR query for workstation"; \ + flow:to_server; llmnr.queries.rrname; content:"workstation"; nocase; sid:1;) + +llmnr.answers.rrname +-------------------- + +``llmnr.answers.rrname`` is a sticky buffer that is used to look at the +name field in LLMNR answer resource records. + +``llmnr.answers.rrname`` will look at both requests and responses, so +``flow`` is recommended to confine to a specific direction. + +The buffer being matched on contains the complete re-assembled +resource name, for example "server.local". + +``llmnr.answers.rrname`` supports :doc:`multi-buffer-matching`. + +.. container:: example-rule + + alert llmnr any 5355 -> any any (msg:"LLMNR answer for server.local"; \ + flow:to_client; llmnr.answers.rrname; content:"server.local"; sid:2;) + +llmnr.authorities.rrname +------------------------ + +``llmnr.authorities.rrname`` is a sticky buffer that is used to look at the +rrname field in LLMNR authority resource records. + +``llmnr.authorities.rrname`` will look at both requests and responses, +so ``flow`` is recommended to confine to a specific direction. + +The buffer being matched on contains the complete re-assembled +resource name, for example "local". + +``llmnr.authorities.rrname`` supports :doc:`multi-buffer-matching`. + +.. container:: example-rule + + alert llmnr any 5355 -> any any (msg:"LLMNR authority record check"; \ + llmnr.authorities.rrname; content:"local"; sid:3;) + +llmnr.additionals.rrname +------------------------ + +``llmnr.additionals.rrname`` is a sticky buffer that is used to look at +the rrname field in LLMNR additional resource records. + +``llmnr.additionals.rrname`` will look at both requests and responses, +so ``flow`` is recommended to confine to a specific direction. + +The buffer being matched on contains the complete re-assembled +resource name, for example "ns.local". + +``llmnr.additionals.rrname`` supports :doc:`multi-buffer-matching`. + +.. container:: example-rule + + alert llmnr any any -> any 5355 (msg:"LLMNR additional record check"; \ + llmnr.additionals.rrname; content:"ns.local"; sid:4;) + +llmnr.response.rrname +--------------------- + +``llmnr.response.rrname`` is a sticky buffer that is used to inspect +all the rrname fields in a response, in the queries, answers, +additionals and authorities. Additionally it will also inspect rdata +fields that have the same format as an rrname (hostname). + +``rdata`` types that will be inspected are: + +* CNAME +* PTR +* MX +* NS +* SOA + +.. container:: example-rule + + alert llmnr any 5355 -> any any (msg:"LLMNR response contains suspicious domain"; \ + flow:to_client; llmnr.response.rrname; content:"malicious"; nocase; sid:5;) diff --git a/doc/userguide/upgrade.rst b/doc/userguide/upgrade.rst index 5b9c00acf1..c835bb1c69 100644 --- a/doc/userguide/upgrade.rst +++ b/doc/userguide/upgrade.rst @@ -44,6 +44,7 @@ Major Changes be ``bypass``, ``track-only`` or ``full``. - Default value for ``stream.reassembly.depth`` when the value is not specified in suricata.yaml is now 1 MiB instead of 0/unlimited. +- LLMNR protocol parser, logger and sticky buffers are implemented. Logging Changes ~~~~~~~~~~~~~~~