suricata
detect-dns-name.c
Go to the documentation of this file.
1 /* Copyright (C) 2025 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * Detect keyword for DNS rrnames:
22  * - dns.queries.rrname
23  * - dns.answers.rrname
24  * - dns.authorities.name
25  * - dns.additionals.name
26  */
27 
28 #include "detect.h"
29 #include "detect-parse.h"
30 #include "detect-engine.h"
32 #include "detect-engine-helper.h"
33 #include "detect-dns-name.h"
34 #include "rust.h"
35 
36 enum DnsSection {
37  DNS_QUERY = 0,
41 };
42 
43 static int query_buffer_id = 0;
44 static int answer_buffer_id = 0;
45 static int authority_buffer_id = 0;
46 static int additional_buffer_id = 0;
47 
48 static int DetectSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str, int id)
49 {
50  if (DetectBufferSetActiveList(de_ctx, s, id) < 0) {
51  return -1;
52  }
54  return -1;
55  }
56 
57  return 0;
58 }
59 
60 static int SetupQueryBuffer(DetectEngineCtx *de_ctx, Signature *s, const char *str)
61 {
62  return DetectSetup(de_ctx, s, str, query_buffer_id);
63 }
64 
65 static int SetupAnswerBuffer(DetectEngineCtx *de_ctx, Signature *s, const char *str)
66 {
67  return DetectSetup(de_ctx, s, str, answer_buffer_id);
68 }
69 
70 static int SetupAdditionalsBuffer(DetectEngineCtx *de_ctx, Signature *s, const char *str)
71 {
72  return DetectSetup(de_ctx, s, str, additional_buffer_id);
73 }
74 
75 static int SetupAuthoritiesBuffer(DetectEngineCtx *de_ctx, Signature *s, const char *str)
76 {
77  return DetectSetup(de_ctx, s, str, authority_buffer_id);
78 }
79 
80 static InspectionBuffer *GetBuffer(DetectEngineThreadCtx *det_ctx,
81  const DetectEngineTransforms *transforms, Flow *f, uint8_t flags, void *txv, int list_id,
82  uint32_t index, enum DnsSection what)
83 {
84  InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, index);
85  if (buffer == NULL) {
86  return NULL;
87  }
88  if (buffer->initialized) {
89  return buffer;
90  }
91 
92  bool to_client = (flags & STREAM_TOSERVER) == 0;
93  const uint8_t *data = NULL;
94  uint32_t data_len = 0;
95 
96  bool ok = false;
97  switch (what) {
98  case DNS_QUERY:
99  ok = SCDnsTxGetQueryName(txv, to_client, index, &data, &data_len);
100  break;
101  case DNS_ANSWER:
102  ok = SCDnsTxGetAnswerName(txv, to_client, index, &data, &data_len);
103  break;
104  case DNS_AUTHORITY:
105  ok = SCDnsTxGetAuthorityName(txv, index, &data, &data_len);
106  break;
107  case DNS_ADDITIONAL:
108  ok = SCDnsTxGetAdditionalName(txv, index, &data, &data_len);
109  break;
110  default:
111  DEBUG_VALIDATE_BUG_ON("unhandled dns rrname type");
113  return NULL;
114  }
115 
116  if (ok) {
117  InspectionBufferSetupMulti(buffer, transforms, data, data_len);
118  buffer->flags = DETECT_CI_FLAGS_SINGLE;
119  return buffer;
120  }
121 
123  return NULL;
124 }
125 
126 static InspectionBuffer *GetQueryBuffer(DetectEngineThreadCtx *det_ctx,
127  const DetectEngineTransforms *transforms, Flow *f, uint8_t flags, void *txv, int list_id,
128  uint32_t index)
129 {
130  return GetBuffer(det_ctx, transforms, f, flags, txv, list_id, index, DNS_QUERY);
131 }
132 
133 static InspectionBuffer *GetAnswerBuffer(DetectEngineThreadCtx *det_ctx,
134  const DetectEngineTransforms *transforms, Flow *f, uint8_t flags, void *txv, int list_id,
135  uint32_t index)
136 {
137  return GetBuffer(det_ctx, transforms, f, flags, txv, list_id, index, DNS_ANSWER);
138 }
139 
140 static InspectionBuffer *GetAuthorityBuffer(DetectEngineThreadCtx *det_ctx,
141  const DetectEngineTransforms *transforms, Flow *f, uint8_t flags, void *txv, int list_id,
142  uint32_t index)
143 {
144  return GetBuffer(det_ctx, transforms, f, flags, txv, list_id, index, DNS_AUTHORITY);
145 }
146 
147 static InspectionBuffer *GetAdditionalBuffer(DetectEngineThreadCtx *det_ctx,
148  const DetectEngineTransforms *transforms, Flow *f, uint8_t flags, void *txv, int list_id,
149  uint32_t index)
150 {
151  return GetBuffer(det_ctx, transforms, f, flags, txv, list_id, index, DNS_ADDITIONAL);
152 }
153 
154 static int Register(const char *keyword, const char *desc, const char *doc,
155  int (*Setup)(DetectEngineCtx *, Signature *, const char *),
157 {
158  int keyword_id = SCDetectHelperNewKeywordId();
159  sigmatch_table[keyword_id].name = keyword;
160  sigmatch_table[keyword_id].desc = desc;
161  sigmatch_table[keyword_id].url = doc;
162  sigmatch_table[keyword_id].Setup = Setup;
163  sigmatch_table[keyword_id].flags |= SIGMATCH_NOOPT;
165 
166  DetectAppLayerMultiRegister(keyword, ALPROTO_DNS, SIG_FLAG_TOSERVER, 0, GetBufferFn, 2, 1);
167  DetectAppLayerMultiRegister(keyword, ALPROTO_DNS, SIG_FLAG_TOCLIENT, 0, GetBufferFn, 2, 1);
168 
169  DetectBufferTypeSetDescriptionByName(keyword, keyword);
171 
172  return DetectBufferTypeGetByName(keyword);
173 }
174 
176 {
177  query_buffer_id = Register("dns.queries.rrname", "DNS query rrname sticky buffer",
178  "/rules/dns-keywords.html#dns.queries.rrname", SetupQueryBuffer, GetQueryBuffer);
179  answer_buffer_id = Register("dns.answers.rrname", "DNS answer rrname sticky buffer",
180  "/rules/dns-keywords.html#dns.answers.rrname", SetupAnswerBuffer, GetAnswerBuffer);
181  additional_buffer_id =
182  Register("dns.additionals.rrname", "DNS additionals rrname sticky buffer",
183  "/rules/dns-keywords.html#dns-additionals-rrname", SetupAdditionalsBuffer,
184  GetAdditionalBuffer);
185  authority_buffer_id = Register("dns.authorities.rrname", "DNS authorities rrname sticky buffer",
186  "/rules/dns-keywords.html#dns-authorities-rrname", SetupAuthoritiesBuffer,
187  GetAuthorityBuffer);
188 }
DNS_ANSWER
@ DNS_ANSWER
Definition: detect-dns-name.c:38
SigTableElmt_::url
const char * url
Definition: detect.h:1323
DetectSignatureSetAppProto
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:1782
detect-engine.h
SIGMATCH_INFO_STICKY_BUFFER
#define SIGMATCH_INFO_STICKY_BUFFER
Definition: detect.h:1528
SigTableElmt_::desc
const char * desc
Definition: detect.h:1322
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:153
SCDetectHelperNewKeywordId
int SCDetectHelperNewKeywordId(void)
Definition: detect-engine-helper.c:97
ALPROTO_DNS
@ ALPROTO_DNS
Definition: app-layer-protos.h:47
SigTableElmt_::name
const char * name
Definition: detect.h:1320
InspectionBuffer::initialized
bool initialized
Definition: detect.h:379
DetectEngineTransforms
Definition: detect.h:410
DetectBufferSetActiveList
int DetectBufferSetActiveList(DetectEngineCtx *de_ctx, Signature *s, const int list)
Definition: detect-engine.c:1377
InspectionMultiBufferGetDataPtr
InspectionBuffer *(* InspectionMultiBufferGetDataPtr)(struct DetectEngineThreadCtx_ *det_ctx, const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, const int list_id, const uint32_t local_id)
Definition: detect.h:421
InspectionBuffer
Definition: detect.h:375
DNS_AUTHORITY
@ DNS_AUTHORITY
Definition: detect-dns-name.c:39
DnsSection
DnsSection
Definition: detect-dns-name.c:36
Flow_
Flow data structure.
Definition: flow.h:354
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1314
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:855
DetectBufferTypeSupportsMultiInstance
void DetectBufferTypeSupportsMultiInstance(const char *name)
Definition: detect-engine.c:1064
rust.h
InspectionBuffer::flags
uint8_t flags
Definition: detect.h:380
detect-dns-name.h
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:270
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1305
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1114
DetectAppLayerMultiRegister
void DetectAppLayerMultiRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectionMultiBufferGetDataPtr GetData, int priority, int tx_min_progress)
Definition: detect-engine.c:2245
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:269
InspectionBufferSetupMultiEmpty
void InspectionBufferSetupMultiEmpty(InspectionBuffer *buffer)
setup the buffer empty
Definition: detect-engine.c:1609
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
DetectEngineThreadCtx_
Definition: detect.h:1110
detect.h
DetectDnsNameRegister
void DetectDnsNameRegister(void)
Definition: detect-dns-name.c:175
detect-engine-helper.h
detect-engine-content-inspection.h
DNS_QUERY
@ DNS_QUERY
Definition: detect-dns-name.c:37
DETECT_CI_FLAGS_SINGLE
#define DETECT_CI_FLAGS_SINGLE
Definition: detect-engine-content-inspection.h:49
flags
uint8_t flags
Definition: decode-gre.h:0
InspectionBufferSetupMulti
void InspectionBufferSetupMulti(InspectionBuffer *buffer, const DetectEngineTransforms *transforms, const uint8_t *data, const uint32_t data_len)
setup the buffer with our initial data
Definition: detect-engine.c:1622
str
#define str(s)
Definition: suricata-common.h:300
detect-parse.h
Signature_
Signature container.
Definition: detect.h:614
DNS_ADDITIONAL
@ DNS_ADDITIONAL
Definition: detect-dns-name.c:40
InspectionBufferMultipleForListGet
InspectionBuffer * InspectionBufferMultipleForListGet(DetectEngineThreadCtx *det_ctx, const int list_id, const uint32_t local_id)
for a InspectionBufferMultipleForList get a InspectionBuffer
Definition: detect-engine.c:1541
SIGMATCH_NOOPT
#define SIGMATCH_NOOPT
Definition: detect.h:1504
DetectBufferTypeSetDescriptionByName
void DetectBufferTypeSetDescriptionByName(const char *name, const char *desc)
Definition: detect-engine.c:1211
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102