suricata
detect-email.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 #include "detect-engine.h"
19 #include "detect-engine-buffer.h"
20 #include "detect-engine-helper.h"
21 #include "detect-parse.h"
22 #include "app-layer-smtp.h"
23 #include "detect-email.h"
24 #include "rust.h"
26 
27 static int g_mime_email_from_buffer_id = 0;
28 static int g_mime_email_subject_buffer_id = 0;
29 static int g_mime_email_to_buffer_id = 0;
30 static int g_mime_email_cc_buffer_id = 0;
31 static int g_mime_email_date_buffer_id = 0;
32 static int g_mime_email_message_id_buffer_id = 0;
33 static int g_mime_email_x_mailer_buffer_id = 0;
34 static int g_mime_email_url_buffer_id = 0;
35 static int g_mime_email_received_buffer_id = 0;
36 
37 static int DetectMimeEmailFromSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
38 {
39  if (SCDetectBufferSetActiveList(de_ctx, s, g_mime_email_from_buffer_id) < 0)
40  return -1;
41 
43  return -1;
44 
45  return 0;
46 }
47 
48 static bool GetMimeEmailFromData(
49  const void *txv, const uint8_t _flow_flags, const uint8_t **data, uint32_t *data_len)
50 {
51  SMTPTransaction *tx = (SMTPTransaction *)txv;
52  if (tx->mime_state == NULL)
53  return false;
54  return (SCDetectMimeEmailGetData(tx->mime_state, data, data_len, "from") == 1);
55 }
56 
57 static int DetectMimeEmailSubjectSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
58 {
59  if (SCDetectBufferSetActiveList(de_ctx, s, g_mime_email_subject_buffer_id) < 0)
60  return -1;
61 
63  return -1;
64 
65  return 0;
66 }
67 
68 static bool GetMimeEmailSubjectData(
69  const void *txv, const uint8_t _flow_flags, const uint8_t **data, uint32_t *data_len)
70 {
71  SMTPTransaction *tx = (SMTPTransaction *)txv;
72  if (tx->mime_state == NULL)
73  return false;
74  return (SCDetectMimeEmailGetData(tx->mime_state, data, data_len, "subject") == 1);
75 }
76 
77 static int DetectMimeEmailToSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
78 {
79  if (SCDetectBufferSetActiveList(de_ctx, s, g_mime_email_to_buffer_id) < 0)
80  return -1;
81 
83  return -1;
84 
85  return 0;
86 }
87 
88 static bool GetMimeEmailToData(
89  const void *txv, const uint8_t _flow_flags, const uint8_t **data, uint32_t *data_len)
90 {
91  SMTPTransaction *tx = (SMTPTransaction *)txv;
92  if (tx->mime_state == NULL)
93  return false;
94  return (SCDetectMimeEmailGetData(tx->mime_state, data, data_len, "to") == 1);
95 }
96 
97 static int DetectMimeEmailCcSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
98 {
99  if (SCDetectBufferSetActiveList(de_ctx, s, g_mime_email_cc_buffer_id) < 0)
100  return -1;
101 
103  return -1;
104 
105  return 0;
106 }
107 
108 static bool GetMimeEmailCcData(
109  const void *txv, const uint8_t _flow_flags, const uint8_t **data, uint32_t *data_len)
110 {
111  SMTPTransaction *tx = (SMTPTransaction *)txv;
112  if (tx->mime_state == NULL)
113  return false;
114  return (SCDetectMimeEmailGetData(tx->mime_state, data, data_len, "cc") == 1);
115 }
116 
117 static int DetectMimeEmailDateSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
118 {
119  if (SCDetectBufferSetActiveList(de_ctx, s, g_mime_email_date_buffer_id) < 0)
120  return -1;
121 
123  return -1;
124 
125  return 0;
126 }
127 
128 static bool GetMimeEmailDateData(
129  const void *txv, const uint8_t _flow_flags, const uint8_t **data, uint32_t *data_len)
130 {
131  SMTPTransaction *tx = (SMTPTransaction *)txv;
132  if (tx->mime_state == NULL)
133  return false;
134  return (SCDetectMimeEmailGetData(tx->mime_state, data, data_len, "date") == 1);
135 }
136 
137 static int DetectMimeEmailMessageIdSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
138 {
139  if (SCDetectBufferSetActiveList(de_ctx, s, g_mime_email_message_id_buffer_id) < 0)
140  return -1;
141 
143  return -1;
144 
145  return 0;
146 }
147 
148 static bool GetMimeEmailMessageIdData(
149  const void *txv, const uint8_t _flow_flags, const uint8_t **data, uint32_t *data_len)
150 {
151  SMTPTransaction *tx = (SMTPTransaction *)txv;
152  if (tx->mime_state == NULL)
153  return false;
154  return (SCDetectMimeEmailGetData(tx->mime_state, data, data_len, "message-id") == 1);
155 }
156 
157 static int DetectMimeEmailXMailerSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
158 {
159  if (SCDetectBufferSetActiveList(de_ctx, s, g_mime_email_x_mailer_buffer_id) < 0)
160  return -1;
161 
163  return -1;
164 
165  return 0;
166 }
167 
168 static bool GetMimeEmailXMailerData(
169  const void *txv, const uint8_t _flow_flags, const uint8_t **data, uint32_t *data_len)
170 {
171  SMTPTransaction *tx = (SMTPTransaction *)txv;
172  if (tx->mime_state == NULL)
173  return false;
174  return (SCDetectMimeEmailGetData(tx->mime_state, data, data_len, "x-mailer") == 1);
175 }
176 
177 static int DetectMimeEmailUrlSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
178 {
179  if (SCDetectBufferSetActiveList(de_ctx, s, g_mime_email_url_buffer_id) < 0)
180  return -1;
181 
183  return -1;
184 
185  return 0;
186 }
187 
188 static bool GetMimeEmailUrlData(DetectEngineThreadCtx *det_ctx, const void *txv,
189  const uint8_t flags, uint32_t idx, const uint8_t **buf, uint32_t *buf_len)
190 {
191  SMTPTransaction *tx = (SMTPTransaction *)txv;
192  if (tx->mime_state == NULL) {
193  return false;
194  }
195 
196  if (SCDetectMimeEmailGetUrl(tx->mime_state, buf, buf_len, idx) != 1) {
197  return false;
198  }
199  return true;
200 }
201 
202 static int DetectMimeEmailReceivedSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
203 {
204  if (SCDetectBufferSetActiveList(de_ctx, s, g_mime_email_received_buffer_id) < 0)
205  return -1;
206 
208  return -1;
209 
210  return 0;
211 }
212 
213 static bool GetMimeEmailReceivedData(DetectEngineThreadCtx *det_ctx, const void *txv,
214  const uint8_t flags, uint32_t idx, const uint8_t **buf, uint32_t *buf_len)
215 {
216  SMTPTransaction *tx = (SMTPTransaction *)txv;
217 
218  if (tx->mime_state == NULL) {
219  return false;
220  }
221 
222  if (SCDetectMimeEmailGetDataArray(tx->mime_state, buf, buf_len, "received", idx) != 1) {
223  return false;
224  }
225  return true;
226 }
227 
229 {
230  SCSigTableAppLiteElmt kw = { 0 };
231 
232  kw.name = "email.from";
233  kw.desc = "'From' field from an email";
234  kw.url = "/rules/email-keywords.html#email.from";
235  kw.Setup = DetectMimeEmailFromSetup;
238  g_mime_email_from_buffer_id = SCDetectHelperBufferMpmRegister(
239  "email.from", "MIME EMAIL FROM", ALPROTO_SMTP, STREAM_TOSERVER, GetMimeEmailFromData);
240 
241  kw.name = "email.subject";
242  kw.desc = "'Subject' field from an email";
243  kw.url = "/rules/email-keywords.html#email.subject";
244  kw.Setup = DetectMimeEmailSubjectSetup;
247  g_mime_email_subject_buffer_id = SCDetectHelperBufferMpmRegister("email.subject",
248  "MIME EMAIL SUBJECT", ALPROTO_SMTP, STREAM_TOSERVER, GetMimeEmailSubjectData);
249 
250  kw.name = "email.to";
251  kw.desc = "'To' field from an email";
252  kw.url = "/rules/email-keywords.html#email.to";
253  kw.Setup = DetectMimeEmailToSetup;
256  g_mime_email_to_buffer_id = SCDetectHelperBufferMpmRegister(
257  "email.to", "MIME EMAIL TO", ALPROTO_SMTP, STREAM_TOSERVER, GetMimeEmailToData);
258 
259  kw.name = "email.cc";
260  kw.desc = "'Cc' field from an email";
261  kw.url = "/rules/email-keywords.html#email.cc";
262  kw.Setup = DetectMimeEmailCcSetup;
265  g_mime_email_cc_buffer_id = SCDetectHelperBufferMpmRegister(
266  "email.cc", "MIME EMAIL CC", ALPROTO_SMTP, STREAM_TOSERVER, GetMimeEmailCcData);
267 
268  kw.name = "email.date";
269  kw.desc = "'Date' field from an email";
270  kw.url = "/rules/email-keywords.html#email.date";
271  kw.Setup = DetectMimeEmailDateSetup;
274  g_mime_email_date_buffer_id = SCDetectHelperBufferMpmRegister(
275  "email.date", "MIME EMAIL DATE", ALPROTO_SMTP, STREAM_TOSERVER, GetMimeEmailDateData);
276 
277  kw.name = "email.message_id";
278  kw.desc = "'Message-Id' field from an email";
279  kw.url = "/rules/email-keywords.html#email.message_id";
280  kw.Setup = DetectMimeEmailMessageIdSetup;
283  g_mime_email_message_id_buffer_id = SCDetectHelperBufferMpmRegister("email.message_id",
284  "MIME EMAIL Message-Id", ALPROTO_SMTP, STREAM_TOSERVER, GetMimeEmailMessageIdData);
285 
286  kw.name = "email.x_mailer";
287  kw.desc = "'X-Mailer' field from an email";
288  kw.url = "/rules/email-keywords.html#email.x_mailer";
289  kw.Setup = DetectMimeEmailXMailerSetup;
292  g_mime_email_x_mailer_buffer_id = SCDetectHelperBufferMpmRegister("email.x_mailer",
293  "MIME EMAIL X-Mailer", ALPROTO_SMTP, STREAM_TOSERVER, GetMimeEmailXMailerData);
294 
295  kw.name = "email.url";
296  kw.desc = "'Url' extracted from an email";
297  kw.url = "/rules/email-keywords.html#email.url";
298  kw.Setup = DetectMimeEmailUrlSetup;
301  g_mime_email_url_buffer_id = SCDetectHelperMultiBufferMpmRegister(
302  "email.url", "MIME EMAIL URL", ALPROTO_SMTP, STREAM_TOSERVER, GetMimeEmailUrlData);
303 
304  kw.name = "email.received";
305  kw.desc = "'Received' field from an email";
306  kw.url = "/rules/email-keywords.html#email.received";
307  kw.Setup = DetectMimeEmailReceivedSetup;
310  g_mime_email_received_buffer_id = SCDetectHelperMultiBufferMpmRegister("email.received",
311  "MIME EMAIL RECEIVED", ALPROTO_SMTP, STREAM_TOSERVER, GetMimeEmailReceivedData);
312 }
DetectEmailRegister
void DetectEmailRegister(void)
Definition: detect-email.c:228
detect-engine.h
SCSigTableAppLiteElmt::url
const char * url
keyword documentation url
Definition: detect-engine-helper.h:55
SIGMATCH_INFO_STICKY_BUFFER
#define SIGMATCH_INFO_STICKY_BUFFER
Definition: detect.h:1636
detect-email.h
SCSigTableAppLiteElmt::name
const char * name
keyword name
Definition: detect-engine-helper.h:51
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:919
rust.h
SCDetectBufferSetActiveList
int SCDetectBufferSetActiveList(DetectEngineCtx *de_ctx, Signature *s, const int list)
Definition: detect-engine-buffer.c:29
SCDetectHelperBufferMpmRegister
int SCDetectHelperBufferMpmRegister(const char *name, const char *desc, AppProto alproto, uint8_t direction, InspectionSingleBufferGetDataPtr GetData)
Definition: detect-engine-helper.c:47
SCSigTableAppLiteElmt::desc
const char * desc
keyword description
Definition: detect-engine-helper.h:53
SCDetectSignatureSetAppProto
int SCDetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:2212
SCSigTableAppLiteElmt
App-layer light version of SigTableElmt.
Definition: detect-engine-helper.h:49
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
DetectEngineThreadCtx_
Definition: detect.h:1211
ALPROTO_SMTP
@ ALPROTO_SMTP
Definition: app-layer-protos.h:38
detect-engine-helper.h
SMTPTransaction_
Definition: app-layer-smtp.h:72
SCDetectHelperKeywordRegister
uint16_t SCDetectHelperKeywordRegister(const SCSigTableAppLiteElmt *kw)
Definition: detect-engine-helper.c:103
detect-engine-content-inspection.h
flags
uint8_t flags
Definition: decode-gre.h:0
SCSigTableAppLiteElmt::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
function callback to parse and setup keyword in rule
Definition: detect-engine-helper.h:59
SCDetectHelperMultiBufferMpmRegister
int SCDetectHelperMultiBufferMpmRegister(const char *name, const char *desc, AppProto alproto, uint8_t direction, InspectionMultiBufferGetDataPtr GetData)
Definition: detect-engine-helper.c:80
detect-engine-buffer.h
detect-parse.h
Signature_
Signature container.
Definition: detect.h:657
SCSigTableAppLiteElmt::flags
uint16_t flags
flags SIGMATCH_*
Definition: detect-engine-helper.h:57
SIGMATCH_NOOPT
#define SIGMATCH_NOOPT
Definition: detect.h:1611
app-layer-smtp.h
SMTPTransaction_::mime_state
MimeStateSMTP * mime_state
Definition: app-layer-smtp.h:85