suricata
detect-iprep.c
Go to the documentation of this file.
1 /* Copyright (C) 2012 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-unittest.h"
45 #include "util-unittest-helper.h"
46 #include "util-fmemopen.h"
47 
48 #include "reputation.h"
49 #include "host.h"
50 
51 #define PARSE_REGEX "\\s*(any|src|dst|both)\\s*,\\s*([A-Za-z0-9\\-\\_]+)\\s*,\\s*(\\<|\\>|\\=)\\s*,\\s*([0-9]+)\\s*"
52 static pcre *parse_regex;
53 static pcre_extra *parse_regex_study;
54 
55 static int DetectIPRepMatch (DetectEngineThreadCtx *, Packet *,
56  const Signature *, const SigMatchCtx *);
57 static int DetectIPRepSetup (DetectEngineCtx *, Signature *, const char *);
58 void DetectIPRepFree (void *);
59 void IPRepRegisterTests(void);
60 
62 {
63  sigmatch_table[DETECT_IPREP].name = "iprep";
64  sigmatch_table[DETECT_IPREP].desc = "match on the IP reputation information for a host";
65  sigmatch_table[DETECT_IPREP].url = DOC_URL DOC_VERSION "/rules/ip-reputation-rules.html#iprep";
66  sigmatch_table[DETECT_IPREP].Match = DetectIPRepMatch;
67  sigmatch_table[DETECT_IPREP].Setup = DetectIPRepSetup;
70  /* this is compatible to ip-only signatures */
72 
73  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
74 }
75 
76 static uint8_t GetHostRepSrc(Packet *p, uint8_t cat, uint32_t version)
77 {
78  uint8_t val = 0;
79  Host *h = NULL;
80 
81  if (p->flags & PKT_HOST_SRC_LOOKED_UP && p->host_src == NULL) {
82  return 0;
83  } else if (p->host_src != NULL) {
84  h = (Host *)p->host_src;
85  HostLock(h);
86  } else {
87  h = HostLookupHostFromHash(&(p->src));
88 
90 
91  if (h == NULL)
92  return 0;
93 
94  HostReference(&p->host_src, h);
95  }
96 
97  if (h->iprep == NULL) {
98  HostRelease(h);
99  return 0;
100  }
101 
102  SReputation *r = (SReputation *)h->iprep;
103 
104  /* allow higher versions as this happens during
105  * rule reload */
106  if (r->version >= version)
107  val = r->rep[cat];
108  else
109  SCLogDebug("version mismatch %u != %u", r->version, version);
110 
111  HostRelease(h);
112  return val;
113 }
114 
115 static uint8_t GetHostRepDst(Packet *p, uint8_t cat, uint32_t version)
116 {
117  uint8_t val = 0;
118  Host *h = NULL;
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  h = (Host *)p->host_dst;
124  HostLock(h);
125  } else {
126  h = HostLookupHostFromHash(&(p->dst));
127 
129 
130  if (h == NULL) {
131  return 0;
132  }
133 
134  HostReference(&p->host_dst, h);
135  }
136 
137  if (h->iprep == NULL) {
138  HostRelease(h);
139  return 0;
140  }
141 
142  SReputation *r = (SReputation *)h->iprep;
143 
144  /* allow higher versions as this happens during
145  * rule reload */
146  if (r->version >= version)
147  val = r->rep[cat];
148  else
149  SCLogDebug("version mismatch %u != %u", r->version, version);
150 
151  HostRelease(h);
152  return val;
153 }
154 
155 static inline int RepMatch(uint8_t op, uint8_t val1, uint8_t val2)
156 {
157  if (op == DETECT_IPREP_OP_GT && val1 > val2) {
158  return 1;
159  } else if (op == DETECT_IPREP_OP_LT && val1 < val2) {
160  return 1;
161  } else if (op == DETECT_IPREP_OP_EQ && val1 == val2) {
162  return 1;
163  }
164  return 0;
165 }
166 
167 /*
168  * returns 0: no match
169  * 1: match
170  * -1: error
171  */
172 static int DetectIPRepMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
173  const Signature *s, const SigMatchCtx *ctx)
174 {
175  const DetectIPRepData *rd = (const DetectIPRepData *)ctx;
176  if (rd == NULL)
177  return 0;
178 
179  uint32_t version = det_ctx->de_ctx->srep_version;
180  uint8_t val = 0;
181 
182  SCLogDebug("rd->cmd %u", rd->cmd);
183  switch(rd->cmd) {
185  val = GetHostRepSrc(p, rd->cat, version);
186  if (val == 0)
187  val = SRepCIDRGetIPRepSrc(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
188  if (val > 0) {
189  if (RepMatch(rd->op, val, rd->val) == 1)
190  return 1;
191  }
192  val = GetHostRepDst(p, rd->cat, version);
193  if (val == 0)
194  val = SRepCIDRGetIPRepDst(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  val = GetHostRepSrc(p, rd->cat, version);
202  SCLogDebug("checking src -- val %u (looking for cat %u, val %u)", val, rd->cat, rd->val);
203  if (val == 0)
204  val = SRepCIDRGetIPRepSrc(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  SCLogDebug("checking dst");
212  val = GetHostRepDst(p, rd->cat, version);
213  if (val == 0)
214  val = SRepCIDRGetIPRepDst(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
215  if (val > 0) {
216  return RepMatch(rd->op, val, rd->val);
217  }
218  break;
219 
221  val = GetHostRepSrc(p, rd->cat, version);
222  if (val == 0)
223  val = SRepCIDRGetIPRepSrc(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
224  if (val == 0 || RepMatch(rd->op, val, rd->val) == 0)
225  return 0;
226  val = GetHostRepDst(p, rd->cat, version);
227  if (val == 0)
228  val = SRepCIDRGetIPRepDst(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version);
229  if (val > 0) {
230  return RepMatch(rd->op, val, rd->val);
231  }
232  break;
233  }
234 
235  return 0;
236 }
237 
238 int DetectIPRepSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
239 {
240  DetectIPRepData *cd = NULL;
241  SigMatch *sm = NULL;
242  char *cmd_str = NULL, *name = NULL, *op_str = NULL, *value = NULL;
243  uint8_t cmd = 0;
244 #define MAX_SUBSTRINGS 30
245  int ret = 0, res = 0;
246  int ov[MAX_SUBSTRINGS];
247 
248  ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS);
249  if (ret != 5) {
250  SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for iprep", rawstr);
251  return -1;
252  }
253 
254  const char *str_ptr;
255  res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, &str_ptr);
256  if (res < 0) {
257  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
258  return -1;
259  }
260  cmd_str = (char *)str_ptr;
261 
262  res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, &str_ptr);
263  if (res < 0) {
264  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
265  goto error;
266  }
267  name = (char *)str_ptr;
268 
269  res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 3, &str_ptr);
270  if (res < 0) {
271  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
272  goto error;
273  }
274  op_str = (char *)str_ptr;
275 
276  res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 4, &str_ptr);
277  if (res < 0) {
278  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
279  goto error;
280  }
281  value = (char *)str_ptr;
282 
283  if (strcmp(cmd_str,"any") == 0) {
284  cmd = DETECT_IPREP_CMD_ANY;
285  } else if (strcmp(cmd_str,"both") == 0) {
286  cmd = DETECT_IPREP_CMD_BOTH;
287  } else if (strcmp(cmd_str,"src") == 0) {
288  cmd = DETECT_IPREP_CMD_SRC;
289  } else if (strcmp(cmd_str,"dst") == 0) {
290  cmd = DETECT_IPREP_CMD_DST;
291  } else {
292  SCLogError(SC_ERR_UNKNOWN_VALUE, "ERROR: iprep \"%s\" is not supported.", cmd_str);
293  goto error;
294  }
295 
296  //SCLogInfo("category %s", name);
297  uint8_t cat = SRepCatGetByShortname(name);
298  if (cat == 0) {
299  SCLogError(SC_ERR_UNKNOWN_VALUE, "unknown iprep category \"%s\"", name);
300  goto error;
301  }
302 
303  uint8_t op = 0;
304  uint8_t val = 0;
305 
306  if (op_str == NULL || strlen(op_str) != 1) {
307  goto error;
308  }
309 
310  switch(op_str[0]) {
311  case '<':
312  op = DETECT_IPREP_OP_LT;
313  break;
314  case '>':
315  op = DETECT_IPREP_OP_GT;
316  break;
317  case '=':
318  op = DETECT_IPREP_OP_EQ;
319  break;
320  default:
321  goto error;
322  break;
323  }
324 
325  if (value != NULL && strlen(value) > 0) {
326  int ival = atoi(value);
327  if (ival < 0 || ival > 127)
328  goto error;
329  val = (uint8_t)ival;
330  }
331 
332  cd = SCMalloc(sizeof(DetectIPRepData));
333  if (unlikely(cd == NULL))
334  goto error;
335 
336  cd->cmd = cmd;
337  cd->cat = cat;
338  cd->op = op;
339  cd->val = val;
340  SCLogDebug("cmd %u, cat %u, op %u, val %u", cd->cmd, cd->cat, cd->op, cd->val);
341 
342  pcre_free_substring(name);
343  name = NULL;
344  pcre_free_substring(cmd_str);
345  cmd_str = NULL;
346  pcre_free_substring(op_str);
347  op_str = NULL;
348  pcre_free_substring(value);
349  value = NULL;
350 
351  /* Okay so far so good, lets get this into a SigMatch
352  * and put it in the Signature. */
353  sm = SigMatchAlloc();
354  if (sm == NULL)
355  goto error;
356 
357  sm->type = DETECT_IPREP;
358  sm->ctx = (SigMatchCtx *)cd;
359 
361 
362  return 0;
363 
364 error:
365  if (name != NULL)
366  pcre_free_substring(name);
367  if (cmd_str != NULL)
368  pcre_free_substring(cmd_str);
369  if (op_str != NULL)
370  pcre_free_substring(op_str);
371  if (value != NULL)
372  pcre_free_substring(value);
373  if (cd != NULL)
374  SCFree(cd);
375  if (sm != NULL)
376  SCFree(sm);
377  return -1;
378 }
379 
380 void DetectIPRepFree (void *ptr)
381 {
382  DetectIPRepData *fd = (DetectIPRepData *)ptr;
383 
384  if (fd == NULL)
385  return;
386 
387  SCFree(fd);
388 }
389 
390 #ifdef UNITTESTS
391 static FILE *DetectIPRepGenerateCategoriesDummy(void)
392 {
393  FILE *fd = NULL;
394  const char *buffer = "1,BadHosts,Know bad hosts";
395 
396  fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
397  if (fd == NULL)
398  SCLogDebug("Error with SCFmemopen()");
399 
400  return fd;
401 }
402 
403 static FILE *DetectIPRepGenerateCategoriesDummy2(void)
404 {
405  FILE *fd = NULL;
406  const char *buffer =
407  "1,BadHosts,Know bad hosts\n"
408  "2,GoodHosts,Know good hosts\n";
409 
410  fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
411  if (fd == NULL)
412  SCLogDebug("Error with SCFmemopen()");
413 
414  return fd;
415 }
416 
417 static FILE *DetectIPRepGenerateNetworksDummy(void)
418 {
419  FILE *fd = NULL;
420  const char *buffer = "10.0.0.0/24,1,20";
421 
422  fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
423  if (fd == NULL)
424  SCLogDebug("Error with SCFmemopen()");
425 
426  return fd;
427 }
428 
429 static FILE *DetectIPRepGenerateNetworksDummy2(void)
430 {
431  FILE *fd = NULL;
432  const char *buffer =
433  "0.0.0.0/0,1,10\n"
434  "192.168.0.0/16,2,127";
435 
436  fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
437  if (fd == NULL)
438  SCLogDebug("Error with SCFmemopen()");
439 
440  return fd;
441 }
442 
443 static int DetectIPRepTest01(void)
444 {
445  ThreadVars th_v;
446  DetectEngineThreadCtx *det_ctx = NULL;
447  Signature *sig = NULL;
448  FILE *fd = NULL;
449  int result = 0, r = 0;
450  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
452 
454  memset(&th_v, 0, sizeof(th_v));
455 
456  if (de_ctx == NULL || p == NULL)
457  goto end;
458 
459  p->src.addr_data32[0] = UTHSetIPv4Address("10.0.0.1");
460  de_ctx->flags |= DE_QUIET;
461 
462  SRepInit(de_ctx);
464 
465  fd = DetectIPRepGenerateCategoriesDummy();
466  r = SRepLoadCatFileFromFD(fd);
467  if (r < 0) {
468  goto end;
469  }
470 
471  fd = DetectIPRepGenerateNetworksDummy();
472  r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd);
473  if (r < 0) {
474  goto end;
475  }
476 
477  sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:any,BadHosts,>,1; sid:1;rev:1;)");
478  if (sig == NULL) {
479  goto end;
480  }
481 
482  SigGroupBuild(de_ctx);
483  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
484 
485  p->alerts.cnt = 0;
486  p->action = 0;
487  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
488  if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) {
489  goto end;
490  }
491 
492  result = 1;
493 end:
494  UTHFreePacket(p);
495  SigGroupCleanup(de_ctx);
496  SigCleanSignatures(de_ctx);
497 
498  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
499  DetectEngineCtxFree(de_ctx);
500 
501  HostShutdown();
502  return result;
503 }
504 
505 static int DetectIPRepTest02(void)
506 {
507  ThreadVars th_v;
508  DetectEngineThreadCtx *det_ctx = NULL;
509  Signature *sig = NULL;
510  FILE *fd = NULL;
511  int result = 0, r = 0;
512  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
514 
516  memset(&th_v, 0, sizeof(th_v));
517 
518  if (de_ctx == NULL || p == NULL)
519  goto end;
520 
521  p->src.addr_data32[0] = UTHSetIPv4Address("10.0.0.1");
522  de_ctx->flags |= DE_QUIET;
523 
524  SRepInit(de_ctx);
526 
527  fd = DetectIPRepGenerateCategoriesDummy();
528  r = SRepLoadCatFileFromFD(fd);
529  if (r < 0) {
530  goto end;
531  }
532 
533  fd = DetectIPRepGenerateNetworksDummy();
534  r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd);
535  if (r < 0) {
536  goto end;
537  }
538 
539  sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:src,BadHosts,>,1; sid:1; rev:1;)");
540  if (sig == NULL) {
541  goto end;
542  }
543 
544  SigGroupBuild(de_ctx);
545  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
546 
547  p->alerts.cnt = 0;
548  p->action = 0;
549  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
550  if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) {
551  goto end;
552  }
553 
554  result = 1;
555 end:
556  UTHFreePacket(p);
557  SigGroupCleanup(de_ctx);
558  SigCleanSignatures(de_ctx);
559 
560  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
561  DetectEngineCtxFree(de_ctx);
562 
563  HostShutdown();
564  return result;
565 }
566 
567 static int DetectIPRepTest03(void)
568 {
569  ThreadVars th_v;
570  DetectEngineThreadCtx *det_ctx = NULL;
571  Signature *sig = NULL;
572  FILE *fd = NULL;
573  int result = 0, r = 0;
574  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
576 
578  memset(&th_v, 0, sizeof(th_v));
579 
580  if (de_ctx == NULL || p == NULL)
581  goto end;
582 
583  p->dst.addr_data32[0] = UTHSetIPv4Address("10.0.0.2");
584  de_ctx->flags |= DE_QUIET;
585 
586  SRepInit(de_ctx);
588 
589  fd = DetectIPRepGenerateCategoriesDummy();
590  r = SRepLoadCatFileFromFD(fd);
591  if (r < 0) {
592  goto end;
593  }
594 
595  fd = DetectIPRepGenerateNetworksDummy();
596  r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd);
597  if (r < 0) {
598  goto end;
599  }
600 
601  sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:dst,BadHosts,>,1; sid:1; rev:1;)");
602  if (sig == NULL) {
603  goto end;
604  }
605 
606  SigGroupBuild(de_ctx);
607  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
608 
609  p->alerts.cnt = 0;
610  p->action = 0;
611  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
612  if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) {
613  goto end;
614  }
615 
616  result = 1;
617 end:
618  UTHFreePacket(p);
619  SigGroupCleanup(de_ctx);
620  SigCleanSignatures(de_ctx);
621 
622  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
623  DetectEngineCtxFree(de_ctx);
624 
625  HostShutdown();
626  return result;
627 }
628 
629 static int DetectIPRepTest04(void)
630 {
631  ThreadVars th_v;
632  DetectEngineThreadCtx *det_ctx = NULL;
633  Signature *sig = NULL;
634  FILE *fd = NULL;
635  int result = 0, r = 0;
636  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
638 
640  memset(&th_v, 0, sizeof(th_v));
641 
642  if (de_ctx == NULL || p == NULL)
643  goto end;
644 
645  p->src.addr_data32[0] = UTHSetIPv4Address("10.0.0.1");
646  p->dst.addr_data32[0] = UTHSetIPv4Address("10.0.0.2");
647  de_ctx->flags |= DE_QUIET;
648 
649  SRepInit(de_ctx);
651 
652  fd = DetectIPRepGenerateCategoriesDummy();
653  r = SRepLoadCatFileFromFD(fd);
654  if (r < 0) {
655  goto end;
656  }
657 
658  fd = DetectIPRepGenerateNetworksDummy();
659  r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd);
660  if (r < 0) {
661  goto end;
662  }
663 
664  sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:both,BadHosts,>,1; sid:1; rev:1;)");
665  if (sig == NULL) {
666  goto end;
667  }
668 
669  SigGroupBuild(de_ctx);
670  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
671 
672  p->alerts.cnt = 0;
673  p->action = 0;
674  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
675  if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) {
676  goto end;
677  }
678 
679  result = 1;
680 end:
681  UTHFreePacket(p);
682  SigGroupCleanup(de_ctx);
683  SigCleanSignatures(de_ctx);
684 
685  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
686  DetectEngineCtxFree(de_ctx);
687 
688  HostShutdown();
689  return result;
690 }
691 
692 static int DetectIPRepTest05(void)
693 {
694  ThreadVars th_v;
695  DetectEngineThreadCtx *det_ctx = NULL;
696  Signature *sig = NULL;
697  FILE *fd = NULL;
698  int result = 0, r = 0;
699  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
701 
703  memset(&th_v, 0, sizeof(th_v));
704 
705  if (de_ctx == NULL || p == NULL)
706  goto end;
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  if (r < 0) {
717  goto end;
718  }
719 
720  fd = DetectIPRepGenerateNetworksDummy();
721  r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd);
722  if (r < 0) {
723  goto end;
724  }
725 
726  sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:any,BadHosts,>,1; sid:1; rev:1;)");
727  if (sig == NULL) {
728  goto end;
729  }
730 
731  SigGroupBuild(de_ctx);
732  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
733 
734  p->alerts.cnt = 0;
735  p->action = 0;
736  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
737  if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) {
738  goto end;
739  }
740 
741  result = 1;
742 end:
743  UTHFreePacket(p);
744  SigGroupCleanup(de_ctx);
745  SigCleanSignatures(de_ctx);
746 
747  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
748  DetectEngineCtxFree(de_ctx);
749 
750  HostShutdown();
751  return result == 0;
752 }
753 
754 static int DetectIPRepTest06(void)
755 {
756  ThreadVars th_v;
757  DetectEngineThreadCtx *det_ctx = NULL;
758  Signature *sig = NULL;
759  FILE *fd = NULL;
760  int result = 0, r = 0;
761  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
763 
765  memset(&th_v, 0, sizeof(th_v));
766 
767  if (de_ctx == NULL || p == NULL)
768  goto end;
769 
770  p->src.addr_data32[0] = UTHSetIPv4Address("1.0.0.1");
771  de_ctx->flags |= DE_QUIET;
772 
773  SRepInit(de_ctx);
775 
776  fd = DetectIPRepGenerateCategoriesDummy();
777  r = SRepLoadCatFileFromFD(fd);
778  if (r < 0) {
779  goto end;
780  }
781 
782  fd = DetectIPRepGenerateNetworksDummy();
783  r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd);
784  if (r < 0) {
785  goto end;
786  }
787 
788  sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:any,BadHosts,>,1; sid:1; rev:1;)");
789  if (sig == NULL) {
790  goto end;
791  }
792 
793  SigGroupBuild(de_ctx);
794  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
795 
796  p->alerts.cnt = 0;
797  p->action = 0;
798  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
799  if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) {
800  goto end;
801  }
802 
803  result = 1;
804 end:
805  UTHFreePacket(p);
806  SigGroupCleanup(de_ctx);
807  SigCleanSignatures(de_ctx);
808 
809  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
810  DetectEngineCtxFree(de_ctx);
811 
812  HostShutdown();
813  return result == 0;
814 }
815 
816 static int DetectIPRepTest07(void)
817 {
818  ThreadVars th_v;
819  DetectEngineThreadCtx *det_ctx = NULL;
820  Signature *sig = NULL;
821  FILE *fd = NULL;
822  int result = 0, r = 0;
823  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
825 
827  memset(&th_v, 0, sizeof(th_v));
828 
829  if (de_ctx == NULL || p == NULL)
830  goto end;
831 
832  p->dst.addr_data32[0] = UTHSetIPv4Address("1.0.0.2");
833  de_ctx->flags |= DE_QUIET;
834 
835  SRepInit(de_ctx);
837 
838  fd = DetectIPRepGenerateCategoriesDummy();
839  r = SRepLoadCatFileFromFD(fd);
840  if (r < 0) {
841  goto end;
842  }
843 
844  fd = DetectIPRepGenerateNetworksDummy();
845  r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd);
846  if (r < 0) {
847  goto end;
848  }
849 
850  sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:any,BadHosts,>,1; sid:1; rev:1;)");
851  if (sig == NULL) {
852  goto end;
853  }
854 
855  SigGroupBuild(de_ctx);
856  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
857 
858  p->alerts.cnt = 0;
859  p->action = 0;
860  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
861  if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) {
862  goto end;
863  }
864 
865  result = 1;
866 end:
867  UTHFreePacket(p);
868  SigGroupCleanup(de_ctx);
869  SigCleanSignatures(de_ctx);
870 
871  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
872  DetectEngineCtxFree(de_ctx);
873 
874  HostShutdown();
875  return result == 0;
876 }
877 
878 static int DetectIPRepTest08(void)
879 {
880  ThreadVars th_v;
881  DetectEngineThreadCtx *det_ctx = NULL;
882  Signature *sig = NULL;
883  FILE *fd = NULL;
884  int result = 0, r = 0;
885  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
887 
889  memset(&th_v, 0, sizeof(th_v));
890 
891  if (de_ctx == NULL || p == NULL)
892  goto end;
893 
894  p->src.addr_data32[0] = UTHSetIPv4Address("1.0.0.1");
895  p->dst.addr_data32[0] = UTHSetIPv4Address("1.0.0.2");
896  de_ctx->flags |= DE_QUIET;
897 
898  SRepInit(de_ctx);
900 
901  fd = DetectIPRepGenerateCategoriesDummy();
902  r = SRepLoadCatFileFromFD(fd);
903  if (r < 0) {
904  goto end;
905  }
906 
907  fd = DetectIPRepGenerateNetworksDummy();
908  r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd);
909  if (r < 0) {
910  goto end;
911  }
912 
913  sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:any,BadHosts,>,1; sid:1; rev:1;)");
914  if (sig == NULL) {
915  goto end;
916  }
917 
918  SigGroupBuild(de_ctx);
919  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
920 
921  p->alerts.cnt = 0;
922  p->action = 0;
923  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
924  if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) {
925  goto end;
926  }
927 
928  result = 1;
929 end:
930  UTHFreePacket(p);
931  SigGroupCleanup(de_ctx);
932  SigCleanSignatures(de_ctx);
933 
934  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
935  DetectEngineCtxFree(de_ctx);
936 
937  HostShutdown();
938  return result == 0;
939 }
940 
941 static int DetectIPRepTest09(void)
942 {
943  ThreadVars th_v;
944  DetectEngineThreadCtx *det_ctx = NULL;
945  Signature *sig = NULL;
946  FILE *fd = NULL;
947  int result = 0, r = 0;
948  Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP);
950 
952  memset(&th_v, 0, sizeof(th_v));
953 
954  if (de_ctx == NULL || p == NULL)
955  goto end;
956 
957  p->src.addr_data32[0] = UTHSetIPv4Address("192.168.0.1");
958  p->dst.addr_data32[0] = UTHSetIPv4Address("192.168.0.2");
959  de_ctx->flags |= DE_QUIET;
960 
961  SRepInit(de_ctx);
963 
964  fd = DetectIPRepGenerateCategoriesDummy2();
965  r = SRepLoadCatFileFromFD(fd);
966  if (r < 0) {
967  goto end;
968  }
969 
970  fd = DetectIPRepGenerateNetworksDummy2();
971  r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd);
972  if (r < 0) {
973  goto end;
974  }
975 
976  sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"test\"; iprep:src,BadHosts,>,9; sid:1; rev:1;)");
977  if (sig == NULL) {
978  goto end;
979  }
980 
981  SigGroupBuild(de_ctx);
982  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
983 
984  p->alerts.cnt = 0;
985  p->action = 0;
986  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
987  if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) {
988  goto end;
989  }
990 
991  result = 1;
992 end:
993  UTHFreePacket(p);
994  SigGroupCleanup(de_ctx);
995  SigCleanSignatures(de_ctx);
996 
997  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
998  DetectEngineCtxFree(de_ctx);
999 
1000  HostShutdown();
1001  return result;
1002 }
1003 #endif /* UNITTESTS */
1004 
1005 /**
1006  * \brief this function registers unit tests for IPRep
1007  */
1009 {
1010 #ifdef UNITTESTS
1011  UtRegisterTest("DetectIPRepTest01", DetectIPRepTest01);
1012  UtRegisterTest("DetectIPRepTest02", DetectIPRepTest02);
1013  UtRegisterTest("DetectIPRepTest03", DetectIPRepTest03);
1014  UtRegisterTest("DetectIPRepTest04", DetectIPRepTest04);
1015  UtRegisterTest("DetectIPRepTest05", DetectIPRepTest05);
1016  UtRegisterTest("DetectIPRepTest06", DetectIPRepTest06);
1017  UtRegisterTest("DetectIPRepTest07", DetectIPRepTest07);
1018  UtRegisterTest("DetectIPRepTest08", DetectIPRepTest08);
1019  UtRegisterTest("DetectIPRepTest09", DetectIPRepTest09);
1020 #endif /* UNITTESTS */
1021 }
void HostShutdown(void)
shutdown the flow engine
Definition: host.c:300
#define PKT_HOST_DST_LOOKED_UP
Definition: decode.h:1106
int SRepInit(DetectEngineCtx *de_ctx)
init reputation
Definition: reputation.c:579
void HostRelease(Host *h)
Definition: host.c:475
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1448
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
#define SCLogDebug(...)
Definition: util-debug.h:335
#define HOST_QUIET
Definition: host.h:93
void IPRepRegisterTests(void)
this function registers unit tests for IPRep
#define PACKET_TEST_ACTION(p, a)
Definition: decode.h:857
#define DETECT_IPREP_OP_LT
Definition: detect-iprep.h:32
#define SCFmemopen
Definition: util-fmemopen.h:52
#define unlikely(expr)
Definition: util-optimize.h:35
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
uint32_t UTHSetIPv4Address(const char *str)
return the uint32_t for a ipv4 address string
Signature * sig_list
Definition: detect.h:767
uint8_t SRepCIDRGetIPRepSrc(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version)
Definition: reputation.c:146
#define DETECT_IPREP_CMD_BOTH
Definition: detect-iprep.h:28
Address dst
Definition: decode.h:413
void SigCleanSignatures(DetectEngineCtx *de_ctx)
uint32_t srep_version
Definition: detect.h:771
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
const char * name
Definition: detect.h:1200
Signature container.
Definition: detect.h:522
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:313
struct Host_ * host_src
Definition: decode.h:557
main detection engine ctx
Definition: detect.h:761
void HostInitConfig(char quiet)
initialize the configuration
Definition: host.c:168
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
#define DE_QUIET
Definition: detect.h:292
void DetectIPRepRegister(void)
Definition: detect-iprep.c:61
uint8_t rep[SREP_MAX_CATS]
Definition: reputation.h:41
#define DETECT_IPREP_CMD_SRC
Definition: detect-iprep.h:29
uint8_t flags
Definition: detect.h:762
#define DETECT_IPREP_OP_GT
Definition: detect-iprep.h:33
Data structures and function prototypes for keeping state for the detection engine.
void(* Free)(void *)
Definition: detect.h:1191
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1669
void DetectSetupParseRegexes(const char *parse_str, pcre **parse_regex, pcre_extra **parse_regex_study)
int SRepLoadFileFromFD(SRepCIDRTree *cidr_ctx, FILE *fp)
Definition: reputation.c:435
struct Host_ * host_dst
Definition: decode.h:558
uint32_t version
Definition: reputation.h:40
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.
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1170
int SigGroupCleanup(DetectEngineCtx *de_ctx)
uint8_t type
Definition: detect.h:319
#define PKT_HOST_SRC_LOOKED_UP
Definition: decode.h:1105
#define DETECT_IPREP_CMD_ANY
Definition: detect-iprep.h:27
const char * desc
Definition: detect.h:1202
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:346
int SRepLoadCatFileFromFD(FILE *fp)
Definition: reputation.c:368
SigMatchCtx * ctx
Definition: detect.h:321
#define SCMalloc(a)
Definition: util-mem.h:222
DetectEngineCtx * de_ctx
Definition: detect.h:1127
void * iprep
Definition: host.h:69
uint8_t version
Definition: decode-gre.h:405
#define SCFree(a)
Definition: util-mem.h:322
PoolThreadReserved res
Definition: host.h:58
void DetectIPRepFree(void *)
Definition: detect-iprep.c:380
SRepCIDRTree * srepCIDR_ctx
Definition: detect.h:774
const char * url
Definition: detect.h:1203
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself...
#define HostReference(dst_h_ptr, h)
Definition: host.h:117
#define MAX_SUBSTRINGS
PacketAlerts alerts
Definition: decode.h:555
#define DETECT_IPREP_OP_EQ
Definition: detect-iprep.h:34
#define SIGMATCH_IPONLY_COMPAT
Definition: detect.h:1371
#define DOC_URL
Definition: suricata.h:86
uint8_t SRepCIDRGetIPRepDst(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version)
Definition: reputation.c:158
uint8_t SRepCatGetByShortname(char *shortname)
Definition: reputation.c:340
uint16_t cnt
Definition: decode.h:293
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:232
Per thread variable structure.
Definition: threadvars.h:57
#define ACTION_DROP
uint32_t flags
Definition: decode.h:443
Host * HostLookupHostFromHash(Address *a)
look up a host in the hash
Definition: host.c:599
#define DOC_VERSION
Definition: suricata.h:91
void SRepResetVersion(void)
Definition: reputation.c:60
uint16_t flags
Definition: detect.h:1194
#define PARSE_REGEX
Definition: detect-iprep.c:51
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
void(* RegisterTests)(void)
Definition: detect.h:1192
a single match condition for a signature
Definition: detect.h:318
#define DETECT_IPREP_CMD_DST
Definition: detect-iprep.h:30
Address src
Definition: decode.h:412
void HostLock(Host *h)
Definition: host.c:481
DetectEngineCtx * DetectEngineCtxInit(void)
uint8_t action
Definition: decode.h:544