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