-
Notifications
You must be signed in to change notification settings - Fork 1.7k
dns: new keywords: dns.answer.name, dns.query.name #9795
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
49a9e9b
ab16abd
b275c79
e59c9c7
6dcd77e
f1593de
848db6b
592b2da
f1d2319
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,28 @@ | ||
| DNS Keywords | ||
| ============ | ||
|
|
||
| There are some more content modifiers (If you are unfamiliar with | ||
| content modifiers, please visit the page :doc:`payload-keywords` These | ||
| ones make sure the signature checks a specific part of the | ||
| network-traffic. | ||
| Suricata supports sticky buffers as well as keywords for efficiently | ||
| matching on specific fields in DNS messages. | ||
|
|
||
| Note that sticky buffers are expected to be followed by one or more | ||
| :doc:`payload-keywords`. | ||
|
|
||
| dns.answer.name | ||
| --------------- | ||
|
|
||
| ``dns.answer.name`` is a sticky buffer that is used to look at the | ||
| name field in DNS answer resource records. | ||
|
|
||
| ``dns.answer.name`` will look at both requests and responses, so | ||
| ``flow`` is recommended to confine to a specific direction. | ||
|
|
||
| .. note:: At this time ``dns.answer.name`` is only supported for | ||
| responses, but supporting it in requests is planned. | ||
|
|
||
| The buffer being matched on contains the complete re-assembled | ||
| resource name, for example "www.suricata.io". | ||
|
|
||
| ``dns.answer.name`` supports :doc:`multi-buffer-matching`. | ||
|
|
||
| dns.opcode | ||
| ---------- | ||
|
|
@@ -32,9 +50,10 @@ Match on DNS requests where the **opcode** is NOT 0:: | |
| dns.query | ||
| --------- | ||
|
|
||
| With **dns.query** the DNS request queries are inspected. The dns.query | ||
| keyword works a bit different from the normal content modifiers. When | ||
| used in a rule all contents following it are affected by it. Example: | ||
| With **dns.query** the DNS request query names are inspected. The | ||
| dns.query keyword works a bit different from the normal content | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "this works a bit different"-bit could be removed. It's just about sticky buffer vs content modifier
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given we're at 8 maybe we should clean this up. Just refer to it as a sticky buffer and not much more? |
||
| modifiers. When used in a rule all contents following it are affected | ||
| by it. Example: | ||
|
|
||
| alert dns any any -> any any (msg:"Test dns.query option"; | ||
| dns.query; content:"google"; nocase; sid:1;) | ||
|
|
@@ -46,6 +65,10 @@ is used or it reaches the end of the rule. | |
|
|
||
| .. note:: **dns.query** is equivalent to the older **dns_query**. | ||
|
|
||
| .. note:: **dns.query** will only match on DNS request messages, to | ||
| also match on DNS response message, see | ||
| `dns.query.name`_. | ||
|
|
||
| Normalized Buffer | ||
| ~~~~~~~~~~~~~~~~~ | ||
|
|
||
|
|
@@ -71,4 +94,19 @@ DNS query on the wire (snippet):: | |
| Multiple Buffer Matching | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| ``dns.query`` supports multiple buffer matching, see :doc:`multi-buffer-matching`. | ||
| ``dns.query`` supports multiple buffer matching, see :doc:`multi-buffer-matching`. | ||
|
|
||
| dns.query.name | ||
| --------------- | ||
|
|
||
| ``dns.query.name`` is a sticky buffer that is used to look at the name | ||
| field in DNS query (question) resource records. It is nearly identical | ||
| to ``dns.query`` but supports both DNS requests and responses. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guess this makes things clear enough. |
||
|
|
||
| ``dns.query.name`` 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 "www.suricata.io". | ||
|
|
||
| ``dns.query.name`` supports :doc:`multi-buffer-matching`. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -881,6 +881,49 @@ pub unsafe extern "C" fn rs_dns_tx_get_query_name( | |
| return 0; | ||
| } | ||
|
|
||
| /// Get the DNS query name at index i. | ||
| #[no_mangle] | ||
| pub unsafe extern "C" fn SCDnsTxGetQueryName( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we break the rust style here (and previously below)?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean the off by one on the indent? Not sure how that happened, I rust formatted the new code, but didn't take in some new formatting. |
||
| tx: &mut DNSTransaction, to_client: bool, i: u32, buf: *mut *const u8, len: *mut u32, | ||
| ) -> bool { | ||
| let queries = if to_client { | ||
| tx.response.as_ref().map(|response| &response.queries) | ||
| } else { | ||
| tx.request.as_ref().map(|request| &request.queries) | ||
| }; | ||
| let index = i as usize; | ||
|
|
||
| if let Some(queries) = queries { | ||
| if let Some(query) = queries.get(index) { | ||
| if !query.name.is_empty() { | ||
| *buf = query.name.as_ptr(); | ||
| *len = query.name.len() as u32; | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| false | ||
| } | ||
|
|
||
| /// Get the DNS response answer name and index i. | ||
| #[no_mangle] | ||
| pub unsafe extern "C" fn SCDnsTxGetAnswerName( | ||
| tx: &mut DNSTransaction, i: u32, buf: *mut *const u8, len: *mut u32, | ||
| ) -> bool { | ||
| let index = i as usize; | ||
| if let Some(response) = &tx.response { | ||
| if let Some(name) = response.answers.get(index).map(|answer| &answer.name) { | ||
| if !name.is_empty() { | ||
| *buf = name.as_ptr(); | ||
| *len = name.len() as u32; | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
| false | ||
| } | ||
|
|
||
| /// Get the DNS transaction ID of a transaction. | ||
| // | ||
| /// extern uint16_t rs_dns_tx_get_tx_id(RSDNSTransaction *); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.