suricata
detect-iprep.c
Go to the documentation of this file.
1 /* Copyright (C) 2012-2021 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  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Implements the iprep keyword
24  */
25 
26 #include "suricata-common.h"
27 #include "decode.h"
28 #include "detect.h"
29 #include "threads.h"
30 #include "flow.h"
31 #include "flow-bit.h"
32 #include "flow-util.h"
33 #include "detect-iprep.h"
34 #include "util-spm.h"
35 
36 #include "app-layer-parser.h"
37 
38 #include "detect-parse.h"
39 #include "detect-engine.h"
40 #include "detect-engine-mpm.h"
41 #include "detect-engine-state.h"
42 
43 #include "util-debug.h"
44 #include "util-byte.h"
45 #include "util-unittest.h"
46 #include "util-unittest-helper.h"
47 #include "util-fmemopen.h"
48 #include "util-validate.h"
49 
50 #include "reputation.h"
51 #include "host.h"
52 
53 #define PARSE_REGEX "\\s*(any|src|dst|both)\\s*,\\s*([A-Za-z0-9\\-\\_]+)\\s*,\\s*(\\<|\\>|\\=)\\s*,\\s*([0-9]+)\\s*"
54 static DetectParseRegex parse_regex;
55 
56 static int DetectIPRepMatch (DetectEngineThreadCtx *, Packet *,
57  const Signature *, const SigMatchCtx *);
58 static int DetectIPRepSetup (DetectEngineCtx *, Signature *, const char *);
59 void DetectIPRepFree (DetectEngineCtx *, void *);
60 #ifdef UNITTESTS
61 static void IPRepRegisterTests(void);
62 #endif
63 
65 {
66  sigmatch_table[DETECT_IPREP].name = "iprep";
67  sigmatch_table[DETECT_IPREP].desc = "match on the IP reputation information for a host";
68  sigmatch_table[DETECT_IPREP].url = "/rules/ip-reputation-rules.html#iprep";
69  sigmatch_table[DETECT_IPREP].Match = DetectIPRepMatch;
70  sigmatch_table[DETECT_IPREP].Setup = DetectIPRepSetup;
72 #ifdef UNITTESTS
73  sigmatch_table[DETECT_IPREP].RegisterTests = IPRepRegisterTests;
74 #endif
75  /* this is compatible to ip-only signatures */
77 
78  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
79 }
80 
81 static inline uint8_t GetRep(const SReputation *r, const uint8_t cat, const uint32_t version)
82 {
83  /* allow higher versions as this happens during
84  * rule reload */
85  if (r != NULL && r->version >= version) {
86  return r->rep[cat];
87  }
88  return 0;
89 }
90 
91 static uint8_t GetHostRepSrc(Packet *p, uint8_t cat, uint32_t version)
92 {
93  if (p->flags & PKT_HOST_SRC_LOOKED_UP && p->host_src == NULL) {
94  return 0;
95  } else if (p->host_src != NULL) {
96  Host *h = (Host *)p->host_src;
97  HostLock(h);
98  /* use_cnt: 1 for having iprep, 1 for packet ref */
99  DEBUG_VALIDATE_BUG_ON(h->iprep != NULL && SC_ATOMIC_GET(h->use_cnt) < 2);
100  uint8_t val = GetRep(h->iprep, cat, version);
101  HostUnlock(h);
102  return val;
103  } else {
104  Host *h = HostLookupHostFromHash(&(p->src));
106  if (h == NULL)
107  return 0;
108  HostReference(&p->host_src, h);
109  /* use_cnt: 1 for having iprep, 1 for HostLookupHostFromHash,
110  * 1 for HostReference to packet */
111  DEBUG_VALIDATE_BUG_ON(h->iprep != NULL && SC_ATOMIC_GET(h->use_cnt) < 3);
112  uint8_t val = GetRep(h->iprep, cat, version);
113  HostRelease(h); /* use_cnt >= 2: 1 for iprep, 1 for packet ref */
114  return val;
115  }
116 }
117 
118 static uint8_t GetHostRepDst(Packet *p, uint8_t cat, uint32_t version)
119 {
120  if (p->flags & PKT_HOST_DST_LOOKED_UP && p->host_dst == NULL) {
121  return 0;
122  } else if (p->host_dst != NULL) {
123  Host *h = (Host *)p->host_dst;
124  HostLock(h);
125  /* use_cnt: 1 for having iprep, 1 for packet ref */
126  DEBUG_VALIDATE_BUG_ON(h->iprep != NULL && SC_ATOMIC_GET(h->use_cnt) < 2);
127  uint8_t val = GetRep(h->iprep, cat, version);
128  HostUnlock(h);
129  return val;
130  } else {
131  Host *h = HostLookupHostFromHash(&(p->dst));
133  if (h == NULL)
134  return 0;
135  HostReference(&p->host_dst, h);
136  /* use_cnt: 1 for having iprep, 1 for HostLookupHostFromHash,
137  * 1 for HostReference to packet */
138  DEBUG_VALIDATE_BUG_ON(h->iprep != NULL && SC_ATOMIC_GET(h->use_cnt) < 3);
139  uint8_t val = GetRep(h->iprep, cat, version);
140  HostRelease(h); /* use_cnt >= 2: 1 for iprep, 1 for packet ref */
141  return val;
142  }
143 }
144 
145 static inline int RepMatch(uint8_t op, uint8_t val1, uint8_t val2)
146 {
147  if (op == DETECT_IPREP_OP_GT && val1 > val2) {
148  return 1;
149  } else if (op == DETECT_IPREP_OP_LT && val1 < val2) {
150  return 1;
151  } else if (op == DETECT_IPREP_OP_EQ && val1 == val2) {
152  return 1;
153  }
154  return 0;
155 }
156 
157 /*
158  * returns 0: no match
159  * 1: match
160  * -1: error
161  */
162 static int DetectIPRepMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
163  const Signature *s, const SigMatchCtx *ctx)
164 {
165  const DetectIPRepData *rd = (const DetectIPRepData *)ctx;
166  if (rd == NULL)
167  return 0;
168 
169  uint32_t version = det_ctx->de_ctx->srep_version;
170  uint8_t val = 0;
171 
172  SCLogDebug("rd->cmd %u", rd->cmd);
173  switch(rd->cmd) {
175  val = GetHostRepSrc(p, rd->cat, version);
176  if (val == 0)
177  val = SRepCIDRGetIPRepSrc(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
178  if (val > 0) {
179  if (RepMatch(rd->op, val, rd->val) == 1)
180  return 1;
181  }
182  val = GetHostRepDst(p, rd->cat, version);
183  if (val == 0)
184  val = SRepCIDRGetIPRepDst(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
185  if (val > 0) {
186  return RepMatch(rd->op, val, rd->val);
187  }
188  break;
189 
191  val = GetHostRepSrc(p, rd->cat, version);
192  SCLogDebug("checking src -- val %u (looking for cat %u, val %u)", val, rd->cat, rd->val);
193  if (val == 0)
194  val = SRepCIDRGetIPRepSrc(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
195  if (val > 0) {
196  return RepMatch(rd->op, val, rd->val);
197  }
198  break;
199 
201  SCLogDebug("checking dst");
202  val = GetHostRepDst(p, rd->cat, version);
203  if (val == 0)
204  val = SRepCIDRGetIPRepDst(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
205  if (val > 0) {
206  return RepMatch(rd->op, val, rd->val);
207  }
208  break;
209 
211  val = GetHostRepSrc(p, rd->cat, version);
212  if (val == 0)
213  val = SRepCIDRGetIPRepSrc(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
214  if (val == 0 || RepMatch(rd->op, val, rd->val) == 0)
215  return 0;
216  val = GetHostRepDst(p, rd->cat, version);
217  if (val == 0)
218  val = SRepCIDRGetIPRepDst(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
219  if (val > 0) {
220  return RepMatch(rd->op, val, rd->val);
221  }
222  break;
223  }
224 
225  return 0;
226 }
227 
228 int DetectIPRepSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
229 {
230  DetectIPRepData *cd = NULL;
231  SigMatch *sm = NULL;
232  char *cmd_str = NULL, *name = NULL, *op_str = NULL, *value = NULL;
233  uint8_t cmd = 0;
234  int ret = 0, res = 0;
235  size_t pcre2_len;
236 
237  ret = DetectParsePcreExec(&parse_regex, rawstr, 0, 0);
238  if (ret != 5) {
239  SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for iprep", rawstr);
240  return -1;
241  }
242 
243  const char *str_ptr;
244  res = pcre2_substring_get_bynumber(parse_regex.match, 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
245  if (res < 0) {
246  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
247  return -1;
248  }
249  cmd_str = (char *)str_ptr;
250 
251  res = pcre2_substring_get_bynumber(parse_regex.match, 2, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
252  if (res < 0) {
253  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
254  goto error;
255  }
256  name = (char *)str_ptr;
257 
258  res = pcre2_substring_get_bynumber(parse_regex.match, 3, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
259  if (res < 0) {
260  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
261  goto error;
262  }
263  op_str = (char *)str_ptr;
264 
265  res = pcre2_substring_get_bynumber(parse_regex.match, 4, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
266  if (res < 0) {
267  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
268  goto error;
269  }
270  value = (char *)str_ptr;
271 
272  if (strcmp(cmd_str,"any") == 0) {
273  cmd = DETECT_IPREP_CMD_ANY;
274  } else if (strcmp(cmd_str,"both") == 0) {
275  cmd = DETECT_IPREP_CMD_BOTH;
276  } else if (strcmp(cmd_str,"src") == 0) {
277  cmd = DETECT_IPREP_CMD_SRC;
278  } else if (strcmp(cmd_str,"dst") == 0) {
279  cmd = DETECT_IPREP_CMD_DST;
280  } else {
281  SCLogError(SC_ERR_UNKNOWN_VALUE, "ERROR: iprep \"%s\" is not supported.", cmd_str);
282  goto error;
283  }
284 
285  //SCLogInfo("category %s", name);
286  uint8_t cat = SRepCatGetByShortname(name);
287  if (cat == 0) {
288  SCLogError(SC_ERR_UNKNOWN_VALUE, "unknown iprep category \"%s\"", name);
289  goto error;
290  }
291 
292  uint8_t op = 0;
293  uint8_t val = 0;
294 
295  if (op_str == NULL || strlen(op_str) != 1) {
296  goto error;
297  }
298 
299  switch(op_str[0]) {
300  case '<':
301  op = DETECT_IPREP_OP_LT;
302  break;
303  case '>':
304  op = DETECT_IPREP_OP_GT;
305  break;
306  case '=':
307  op = DETECT_IPREP_OP_EQ;
308  break;
309  default:
310  goto error;
311  break;
312  }
313 
314  if (value != NULL && strlen(value) > 0) {
315  if (StringParseU8RangeCheck(&val, 10, 0, (const char *)value, 0, 127) < 0)
316  goto error;
317  }
318 
319  cd = SCMalloc(sizeof(DetectIPRepData));
320  if (unlikely(cd == NULL))
321  goto error;
322 
323  cd->cmd = cmd;
324  cd->cat = cat;
325  cd->op = op;
326  cd->val = val;
327  SCLogDebug("cmd %u, cat %u, op %u, val %u", cd->cmd, cd->cat, cd->op, cd->val);
328 
329  pcre2_substring_free((PCRE2_UCHAR *)name);
330  name = NULL;
331  pcre2_substring_free((PCRE2_UCHAR *)cmd_str);
332  cmd_str = NULL;
333  pcre2_substring_free((PCRE2_UCHAR *)op_str);
334  op_str = NULL;
335  pcre2_substring_free((PCRE2_UCHAR *)value);
336  value = NULL;
337 
338  /* Okay so far so good, lets get this into a SigMatch
339  * and put it in the Signature. */
340  sm = SigMatchAlloc();
341  if (sm == NULL)
342  goto error;
343 
344  sm->type = DETECT_IPREP;
345  sm->ctx = (SigMatchCtx *)cd;
346 
348 
349  return 0;
350 
351 error:
352  if (name != NULL)
353  pcre2_substring_free((PCRE2_UCHAR *)name);
354  if (cmd_str != NULL)
355  pcre2_substring_free((PCRE2_UCHAR *)cmd_str);
356  if (op_str != NULL)
357  pcre2_substring_free((PCRE2_UCHAR *)op_str);
358  if (value != NULL)
359  pcre2_substring_free((PCRE2_UCHAR *)value);
360  if (cd != NULL)
361  SCFree(cd);
362  if (sm != NULL)
363  SCFree(sm);
364  return -1;
365 }
366 
368 {
369  DetectIPRepData *fd = (DetectIPRepData *)ptr;
370 
371  if (fd == NULL)
372  return;
373 
374  SCFree(fd);
375 }
376 
377 #ifdef UNITTESTS
378 static FILE *DetectIPRepGenerateCategoriesDummy(void)
379 {
380  FILE *fd = NULL;
381  const char *buffer = "1,BadHosts,Know bad hosts";
382 
383  fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
384  if (fd == NULL)
385  SCLogDebug("Error with SCFmemopen()");
386 
387  return fd;
388 }
389 
390 static FILE *DetectIPRepGenerateCategoriesDummy2(void)
391 {
392  FILE *fd = NULL;
393  const char *buffer =
394  "1,BadHosts,Know bad hosts\n"
395  "2,GoodHosts,Know good hosts\n";
396 
397  fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
398  if (fd == NULL)
399  SCLogDebug("Error with SCFmemopen()");
400 
401  return fd;
402 }
403 
404 static FILE *DetectIPRepGenerateNetworksDummy(void)
405 {
406  FILE *fd = NULL;
407  const char *buffer = "10.0.0.0/24,1,20";
408 
409  fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
410  if (fd == NULL)
411  SCLogDebug("Error with SCFmemopen()");
412 
413  return fd;
414 }
415 
416 static FILE *DetectIPRepGenerateNetworksDummy2(void)
417 {
418  FILE *fd = NULL;
419  const char *buffer =
420  "0.0.0.0/0,1,10\n"
421  "192.168.0.0/16,2,127";
422 
423  fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
424  if (fd == NULL)
425  SCLogDebug("Error with SCFmemopen()");
426 
427  return fd;
428 }
429 
430 static int DetectIPRepTest01(void)
431 {
432  ThreadVars th_v;
433  DetectEngineThreadCtx *det_ctx = NULL;
434  Signature *sig = NULL;
435  FILE *fd = NULL;
436  int r = 0;
437  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
439 
441  memset(&th_v, 0, sizeof(th_v));
442 
444  FAIL_IF_NULL(p);
445 
446  p->src.addr_data32[0] = UTHSetIPv4Address("10.0.0.1");
447  de_ctx->flags |= DE_QUIET;
448 
449  SRepInit(de_ctx);
451 
452  fd = DetectIPRepGenerateCategoriesDummy();
453  r = SRepLoadCatFileFromFD(fd);
454  FAIL_IF(r < 0);
455 
456  fd = DetectIPRepGenerateNetworksDummy();
458  FAIL_IF(r < 0);
459 
460  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value "
461  "badhost\"; iprep:any,BadHosts,>,1; sid:1;rev:1;)");
462  FAIL_IF_NULL(sig);
463 
465  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
466 
467  p->alerts.cnt = 0;
468  p->action = 0;
469  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
470 
471  FAIL_IF(p->alerts.cnt != 1);
472  FAIL_IF(PacketTestAction(p, ACTION_DROP));
473 
474  UTHFreePacket(p);
475 
476  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
478 
479  HostShutdown();
480  PASS;
481 }
482 
483 static int DetectIPRepTest02(void)
484 {
485  ThreadVars th_v;
486  DetectEngineThreadCtx *det_ctx = NULL;
487  Signature *sig = NULL;
488  FILE *fd = NULL;
489  int r = 0;
490  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
492 
494  memset(&th_v, 0, sizeof(th_v));
495 
497  FAIL_IF_NULL(p);
498 
499  p->src.addr_data32[0] = UTHSetIPv4Address("10.0.0.1");
500  de_ctx->flags |= DE_QUIET;
501 
502  SRepInit(de_ctx);
504 
505  fd = DetectIPRepGenerateCategoriesDummy();
506  r = SRepLoadCatFileFromFD(fd);
507  FAIL_IF(r < 0);
508 
509  fd = DetectIPRepGenerateNetworksDummy();
511  FAIL_IF(r < 0);
512 
513  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value "
514  "badhost\"; iprep:src,BadHosts,>,1; sid:1; rev:1;)");
515  FAIL_IF_NULL(sig);
516 
518  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
519 
520  p->alerts.cnt = 0;
521  p->action = 0;
522  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
523  FAIL_IF(p->alerts.cnt != 1);
524  FAIL_IF(PacketTestAction(p, ACTION_DROP));
525 
526  UTHFreePacket(p);
527 
528  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
530 
531  HostShutdown();
532  PASS;
533 }
534 
535 static int DetectIPRepTest03(void)
536 {
537  ThreadVars th_v;
538  DetectEngineThreadCtx *det_ctx = NULL;
539  Signature *sig = NULL;
540  FILE *fd = NULL;
541  int r = 0;
542  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
544 
546  memset(&th_v, 0, sizeof(th_v));
547 
549  FAIL_IF_NULL(p);
550 
551  p->dst.addr_data32[0] = UTHSetIPv4Address("10.0.0.2");
552  de_ctx->flags |= DE_QUIET;
553 
554  SRepInit(de_ctx);
556 
557  fd = DetectIPRepGenerateCategoriesDummy();
558  r = SRepLoadCatFileFromFD(fd);
559  FAIL_IF(r < 0);
560 
561  fd = DetectIPRepGenerateNetworksDummy();
563  FAIL_IF(r < 0);
564 
565  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value "
566  "badhost\"; iprep:dst,BadHosts,>,1; sid:1; rev:1;)");
567  FAIL_IF_NULL(sig);
568 
570  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
571 
572  p->alerts.cnt = 0;
573  p->action = 0;
574  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
575  FAIL_IF(p->alerts.cnt != 1);
576  FAIL_IF(PacketTestAction(p, ACTION_DROP));
577 
578  UTHFreePacket(p);
579 
580  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
582 
583  HostShutdown();
584  PASS;
585 }
586 
587 static int DetectIPRepTest04(void)
588 {
589  ThreadVars th_v;
590  DetectEngineThreadCtx *det_ctx = NULL;
591  Signature *sig = NULL;
592  FILE *fd = NULL;
593  int r = 0;
594  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
596 
598  memset(&th_v, 0, sizeof(th_v));
599 
601  FAIL_IF_NULL(p);
602 
603  p->src.addr_data32[0] = UTHSetIPv4Address("10.0.0.1");
604  p->dst.addr_data32[0] = UTHSetIPv4Address("10.0.0.2");
605  de_ctx->flags |= DE_QUIET;
606 
607  SRepInit(de_ctx);
609 
610  fd = DetectIPRepGenerateCategoriesDummy();
611  r = SRepLoadCatFileFromFD(fd);
612  FAIL_IF(r < 0);
613 
614  fd = DetectIPRepGenerateNetworksDummy();
616  FAIL_IF(r < 0);
617 
618  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value "
619  "badhost\"; iprep:both,BadHosts,>,1; sid:1; rev:1;)");
620  FAIL_IF_NULL(sig);
621 
623  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
624 
625  p->alerts.cnt = 0;
626  p->action = 0;
627  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
628  FAIL_IF(p->alerts.cnt != 1);
629  FAIL_IF(PacketTestAction(p, ACTION_DROP));
630 
631  UTHFreePacket(p);
632 
633  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
635 
636  HostShutdown();
637  PASS;
638 }
639 
640 static int DetectIPRepTest05(void)
641 {
642  ThreadVars th_v;
643  DetectEngineThreadCtx *det_ctx = NULL;
644  Signature *sig = NULL;
645  FILE *fd = NULL;
646  int r = 0;
647  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
649 
651  memset(&th_v, 0, sizeof(th_v));
652 
654  FAIL_IF_NULL(p);
655 
656  p->src.addr_data32[0] = UTHSetIPv4Address("1.0.0.1");
657  de_ctx->flags |= DE_QUIET;
658 
659  SRepInit(de_ctx);
661 
662  fd = DetectIPRepGenerateCategoriesDummy();
663  r = SRepLoadCatFileFromFD(fd);
664  FAIL_IF(r < 0);
665 
666  fd = DetectIPRepGenerateNetworksDummy();
668  FAIL_IF(r < 0);
669 
670  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value "
671  "badhost\"; iprep:any,BadHosts,>,1; sid:1; rev:1;)");
672  FAIL_IF_NULL(sig);
673 
675  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
676 
677  p->alerts.cnt = 0;
678  p->action = 0;
679  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
680  FAIL_IF(p->alerts.cnt != 0);
681  FAIL_IF(PacketTestAction(p, ACTION_DROP));
682 
683  UTHFreePacket(p);
684 
685  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
687 
688  HostShutdown();
689  PASS;
690 }
691 
692 static int DetectIPRepTest06(void)
693 {
694  ThreadVars th_v;
695  DetectEngineThreadCtx *det_ctx = NULL;
696  Signature *sig = NULL;
697  FILE *fd = NULL;
698  int r = 0;
699  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
701 
703  memset(&th_v, 0, sizeof(th_v));
704 
706  FAIL_IF_NULL(p);
707 
708  p->src.addr_data32[0] = UTHSetIPv4Address("1.0.0.1");
709  de_ctx->flags |= DE_QUIET;
710 
711  SRepInit(de_ctx);
713 
714  fd = DetectIPRepGenerateCategoriesDummy();
715  r = SRepLoadCatFileFromFD(fd);
716  FAIL_IF(r < 0);
717 
718  fd = DetectIPRepGenerateNetworksDummy2();
720  FAIL_IF(r < 0);
721 
722  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value "
723  "badhost\"; iprep:any,BadHosts,>,1; sid:1; rev:1;)");
724  FAIL_IF_NULL(sig);
725 
727  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
728 
729  p->alerts.cnt = 0;
730  p->action = 0;
731  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
732  FAIL_IF(p->alerts.cnt != 1);
733  FAIL_IF(PacketTestAction(p, ACTION_DROP));
734 
735  UTHFreePacket(p);
736 
737  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
739 
740  HostShutdown();
741  PASS;
742 }
743 
744 static int DetectIPRepTest07(void)
745 {
746  ThreadVars th_v;
747  DetectEngineThreadCtx *det_ctx = NULL;
748  Signature *sig = NULL;
749  FILE *fd = NULL;
750  int r = 0;
751  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
753 
755  memset(&th_v, 0, sizeof(th_v));
756 
758  FAIL_IF_NULL(p);
759 
760  p->dst.addr_data32[0] = UTHSetIPv4Address("1.0.0.2");
761  de_ctx->flags |= DE_QUIET;
762 
763  SRepInit(de_ctx);
765 
766  fd = DetectIPRepGenerateCategoriesDummy();
767  r = SRepLoadCatFileFromFD(fd);
768  FAIL_IF(r < 0);
769 
770  fd = DetectIPRepGenerateNetworksDummy2();
772  FAIL_IF(r < 0);
773 
774  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value "
775  "badhost\"; iprep:any,BadHosts,>,1; sid:1; rev:1;)");
776  FAIL_IF_NULL(sig);
777 
779  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
780 
781  p->alerts.cnt = 0;
782  p->action = 0;
783  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
784  FAIL_IF(p->alerts.cnt != 1);
785  FAIL_IF(PacketTestAction(p, ACTION_DROP));
786 
787  UTHFreePacket(p);
788 
789  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
791 
792  HostShutdown();
793  PASS;
794 }
795 
796 static int DetectIPRepTest08(void)
797 {
798  ThreadVars th_v;
799  DetectEngineThreadCtx *det_ctx = NULL;
800  Signature *sig = NULL;
801  FILE *fd = NULL;
802  int r = 0;
803  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
805 
807  memset(&th_v, 0, sizeof(th_v));
808 
810  FAIL_IF_NULL(p);
811 
812  p->src.addr_data32[0] = UTHSetIPv4Address("1.0.0.1");
813  p->dst.addr_data32[0] = UTHSetIPv4Address("1.0.0.2");
814  de_ctx->flags |= DE_QUIET;
815 
816  SRepInit(de_ctx);
818 
819  fd = DetectIPRepGenerateCategoriesDummy();
820  r = SRepLoadCatFileFromFD(fd);
821  FAIL_IF(r < 0);
822 
823  fd = DetectIPRepGenerateNetworksDummy();
825  FAIL_IF(r < 0);
826 
827  sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value "
828  "badhost\"; iprep:any,BadHosts,>,1; sid:1; rev:1;)");
829  FAIL_IF_NULL(sig);
830 
832  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
833 
834  p->alerts.cnt = 0;
835  p->action = 0;
836  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
837  FAIL_IF(p->alerts.cnt != 0);
838  FAIL_IF(PacketTestAction(p, ACTION_DROP));
839 
840  UTHFreePacket(p);
841 
842  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
844 
845  HostShutdown();
846  PASS;
847 }
848 
849 static int DetectIPRepTest09(void)
850 {
851  ThreadVars th_v;
852  DetectEngineThreadCtx *det_ctx = NULL;
853  Signature *sig = NULL;
854  FILE *fd = NULL;
855  int r = 0;
856  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
858 
860  memset(&th_v, 0, sizeof(th_v));
861 
863  FAIL_IF_NULL(p);
864 
865  p->src.addr_data32[0] = UTHSetIPv4Address("192.168.0.1");
866  p->dst.addr_data32[0] = UTHSetIPv4Address("192.168.0.2");
867  de_ctx->flags |= DE_QUIET;
868 
869  SRepInit(de_ctx);
871 
872  fd = DetectIPRepGenerateCategoriesDummy2();
873  r = SRepLoadCatFileFromFD(fd);
874  FAIL_IF(r < 0);
875 
876  fd = DetectIPRepGenerateNetworksDummy2();
878  FAIL_IF(r < 0);
879 
881  "alert tcp any any -> any any (msg:\"test\"; iprep:src,BadHosts,>,9; sid:1; rev:1;)");
882  FAIL_IF_NULL(sig);
883 
885  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
886 
887  p->alerts.cnt = 0;
888  p->action = 0;
889  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
890  FAIL_IF(p->alerts.cnt != 1);
891  FAIL_IF(PacketTestAction(p, ACTION_DROP));
892 
893  UTHFreePacket(p);
894 
895  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
897 
898  HostShutdown();
899  PASS;
900 }
901 
902 /**
903  * \brief this function registers unit tests for IPRep
904  */
905 void IPRepRegisterTests(void)
906 {
907  UtRegisterTest("DetectIPRepTest01", DetectIPRepTest01);
908  UtRegisterTest("DetectIPRepTest02", DetectIPRepTest02);
909  UtRegisterTest("DetectIPRepTest03", DetectIPRepTest03);
910  UtRegisterTest("DetectIPRepTest04", DetectIPRepTest04);
911  UtRegisterTest("DetectIPRepTest05", DetectIPRepTest05);
912  UtRegisterTest("DetectIPRepTest06", DetectIPRepTest06);
913  UtRegisterTest("DetectIPRepTest07", DetectIPRepTest07);
914  UtRegisterTest("DetectIPRepTest08", DetectIPRepTest08);
915  UtRegisterTest("DetectIPRepTest09", DetectIPRepTest09);
916 }
917 #endif /* UNITTESTS */
util-byte.h
host.h
DetectParseRegex::match
pcre2_match_data * match
Definition: detect-parse.h:45
SigTableElmt_::url
const char * url
Definition: detect.h:1270
HostUnlock
void HostUnlock(Host *h)
Definition: host.c:491
SReputation_
Definition: reputation.h:39
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
DetectIPRepData_
Definition: detect-iprep.h:36
DETECT_IPREP_CMD_SRC
#define DETECT_IPREP_CMD_SRC
Definition: detect-iprep.h:29
PKT_HOST_DST_LOOKED_UP
#define PKT_HOST_DST_LOOKED_UP
Definition: decode.h:1196
SigTableElmt_::desc
const char * desc
Definition: detect.h:1269
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, const char *str, int start_offset, int options)
Definition: detect-parse.c:2474
util-fmemopen.h
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1257
SReputation_::rep
uint8_t rep[SREP_MAX_CATS]
Definition: reputation.h:41
flow-util.h
DetectParseRegex
Definition: detect-parse.h:42
SigTableElmt_::name
const char * name
Definition: detect.h:1267
SRepCatGetByShortname
uint8_t SRepCatGetByShortname(char *shortname)
Definition: reputation.c:341
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
Packet_::host_src
struct Host_ * host_src
Definition: decode.h:584
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
PacketAlerts_::cnt
uint16_t cnt
Definition: decode.h:306
Packet_::flags
uint32_t flags
Definition: decode.h:462
Packet_::action
uint8_t action
Definition: decode.h:571
threads.h
HostRelease
void HostRelease(Host *h)
Definition: host.c:480
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1261
UTHSetIPv4Address
uint32_t UTHSetIPv4Address(const char *str)
return the uint32_t for a ipv4 address string
Definition: util-unittest-helper.c:132
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:811
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2433
DETECT_IPREP_CMD_ANY
#define DETECT_IPREP_CMD_ANY
Definition: detect-iprep.h:27
flow-bit.h
DetectEngineCtx_::srep_version
uint32_t srep_version
Definition: detect.h:821
DE_QUIET
#define DE_QUIET
Definition: detect.h:295
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:337
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1790
SC_ERR_PCRE_GET_SUBSTRING
@ SC_ERR_PCRE_GET_SUBSTRING
Definition: util-error.h:34
SCFmemopen
#define SCFmemopen
Definition: util-fmemopen.h:52
Packet_::host_dst
struct Host_ * host_dst
Definition: decode.h:585
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1252
Packet_::alerts
PacketAlerts alerts
Definition: decode.h:582
util-unittest.h
util-unittest-helper.h
DETECT_IPREP_OP_EQ
#define DETECT_IPREP_OP_EQ
Definition: detect-iprep.h:34
decode.h
util-debug.h
SC_ERR_PCRE_MATCH
@ SC_ERR_PCRE_MATCH
Definition: util-error.h:32
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
detect-iprep.h
DetectEngineThreadCtx_
Definition: detect.h:1060
DetectEngineCtx_::srepCIDR_ctx
SRepCIDRTree * srepCIDR_ctx
Definition: detect.h:824
SC_ERR_UNKNOWN_VALUE
@ SC_ERR_UNKNOWN_VALUE
Definition: util-error.h:159
DETECT_IPREP_CMD_DST
#define DETECT_IPREP_CMD_DST
Definition: detect-iprep.h:30
SRepLoadCatFileFromFD
int SRepLoadCatFileFromFD(FILE *fp)
Definition: reputation.c:369
PKT_HOST_SRC_LOOKED_UP
#define PKT_HOST_SRC_LOOKED_UP
Definition: decode.h:1195
res
PoolThreadReserved res
Definition: stream-tcp-private.h:0
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2597
detect-engine-mpm.h
DetectIPRepData_::op
int8_t op
Definition: detect-iprep.h:39
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-iprep.c:53
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:89
app-layer-parser.h
HostLock
void HostLock(Host *h)
Definition: host.c:486
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:324
DetectIPRepData_::val
uint8_t val
Definition: detect-iprep.h:40
Packet_
Definition: decode.h:427
HostReference
#define HostReference(dst_h_ptr, h)
Definition: host.h:117
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1235
reputation.h
DETECT_IPREP_OP_LT
#define DETECT_IPREP_OP_LT
Definition: detect-iprep.h:32
SRepLoadFileFromFD
int SRepLoadFileFromFD(SRepCIDRTree *cidr_ctx, FILE *fp)
Definition: reputation.c:436
DetectIPRepFree
void DetectIPRepFree(DetectEngineCtx *, void *)
Definition: detect-iprep.c:367
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:235
DetectIPRepData_::cat
int8_t cat
Definition: detect-iprep.h:38
StringParseU8RangeCheck
int StringParseU8RangeCheck(uint8_t *res, int base, size_t len, const char *str, uint8_t min, uint8_t max)
Definition: util-byte.c:457
SRepCIDRGetIPRepDst
uint8_t SRepCIDRGetIPRepDst(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version)
Definition: reputation.c:159
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1948
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:316
Host_::iprep
void * iprep
Definition: host.h:69
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2420
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3142
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3354
SigMatch_::type
uint16_t type
Definition: detect.h:322
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
util-spm.h
HOST_QUIET
#define HOST_QUIET
Definition: host.h:93
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
version
uint8_t version
Definition: decode-gre.h:1
HostShutdown
void HostShutdown(void)
shutdown the flow engine
Definition: host.c:309
SReputation_::version
uint32_t version
Definition: reputation.h:40
util-validate.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SRepInit
int SRepInit(DetectEngineCtx *de_ctx)
init reputation
Definition: reputation.c:581
SCFree
#define SCFree(p)
Definition: util-mem.h:61
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:485
DETECT_IPREP_OP_GT
#define DETECT_IPREP_OP_GT
Definition: detect-iprep.h:33
detect-parse.h
Signature_
Signature container.
Definition: detect.h:548
SigMatch_
a single match condition for a signature
Definition: detect.h:321
SRepResetVersion
void SRepResetVersion(void)
Definition: reputation.c:62
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2394
HostLookupHostFromHash
Host * HostLookupHostFromHash(Address *a)
look up a host in the hash
Definition: host.c:604
DETECT_IPREP_CMD_BOTH
#define DETECT_IPREP_CMD_BOTH
Definition: detect-iprep.h:28
DetectEngineThreadCtx_::de_ctx
DetectEngineCtx * de_ctx
Definition: detect.h:1192
Packet_::dst
Address dst
Definition: decode.h:432
HostInitConfig
void HostInitConfig(bool quiet)
initialize the configuration
Definition: host.c:175
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:812
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:376
flow.h
DetectIPRepRegister
void DetectIPRepRegister(void)
Definition: detect-iprep.c:64
Host_
Definition: host.h:58
DetectIPRepData_::cmd
uint8_t cmd
Definition: detect-iprep.h:37
SIGMATCH_IPONLY_COMPAT
#define SIGMATCH_IPONLY_COMPAT
Definition: detect.h:1455
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
SigMatchAppendSMToList
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:349
SRepCIDRGetIPRepSrc
uint8_t SRepCIDRGetIPRepSrc(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version)
Definition: reputation.c:147
Packet_::src
Address src
Definition: decode.h:431
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1259
DETECT_IPREP
@ DETECT_IPREP
Definition: detect-engine-register.h:214