mirror of https://github.com/OISF/suricata
Support vars lookup from conf file. Current patch support address and port group vars lookup
parent
951b4d5cf4
commit
dc44700ce5
@ -0,0 +1,419 @@
|
||||
/** Copyright (c) 2009 Open Information Security Foundation.
|
||||
* \author Anoop Saldanha <poonaatsoc@gmail.com>
|
||||
*/
|
||||
|
||||
#include "eidps-common.h"
|
||||
#include "conf.h"
|
||||
#include "conf-yaml-loader.h"
|
||||
|
||||
#include "detect.h"
|
||||
#include "detect-content.h"
|
||||
#include "detect-parse.h"
|
||||
#include "detect-engine.h"
|
||||
#include "detect-engine-mpm.h"
|
||||
|
||||
#include "util-rule-vars.h"
|
||||
#include "util-enum.h"
|
||||
#include "util-debug.h"
|
||||
#include "util-unittest.h"
|
||||
|
||||
/** An enum-string map, that maps the different vars type in the yaml conf
|
||||
* type with the mapping path in the yaml conf file */
|
||||
SCEnumCharMap sc_rule_vars_type_map[ ] = {
|
||||
{ "vars.address-groups", SC_RULE_VARS_ADDRESS_GROUPS },
|
||||
{ "vars.port-groups", SC_RULE_VARS_PORT_GROUPS }
|
||||
};
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* \brief Retrieves a value for a yaml mapping. The sequence from the yaml
|
||||
* conf file, from which the conf value has to be retrieved can be
|
||||
* specified by supplying a SCRuleVarsType enum. The string mapping
|
||||
* for each of the SCRuleVarsType is present in sc_rule_vars_type_map.
|
||||
*
|
||||
* \param conf_var_name Pointer to a character string containing the conf var
|
||||
* name, whose value has to be retrieved from the yaml
|
||||
* conf file.
|
||||
* \param conf_vars_type Holds an enum value that indicates the kind of yaml
|
||||
* mapping that has to be retrieved. Can be one of the
|
||||
* values in SCRuleVarsType.
|
||||
*
|
||||
* \retval conf_var_name_value Pointer to the string containing the conf value
|
||||
* on success; NULL on failure.
|
||||
*/
|
||||
char *SCRuleVarsGetConfVar(const char *conf_var_name,
|
||||
SCRuleVarsType conf_vars_type)
|
||||
{
|
||||
SCEnter();
|
||||
|
||||
const char *conf_var_type_name = NULL;
|
||||
char *conf_var_full_name = NULL;
|
||||
char *conf_var_full_name_value = NULL;
|
||||
|
||||
if (conf_var_name == NULL)
|
||||
goto end;
|
||||
(conf_var_name[0] == '$') ? conf_var_name++ : conf_var_name;
|
||||
conf_var_type_name = SCMapEnumValueToName(conf_vars_type,
|
||||
sc_rule_vars_type_map);
|
||||
if (conf_var_type_name == NULL)
|
||||
goto end;
|
||||
|
||||
/* the + 2 is for the '.' and the string termination character '\0' */
|
||||
conf_var_full_name = (char *)malloc(strlen(conf_var_type_name) +
|
||||
strlen(conf_var_name) + 2);
|
||||
if (conf_var_full_name == NULL) {
|
||||
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (snprintf(conf_var_full_name,
|
||||
strlen(conf_var_type_name) + strlen(conf_var_name) + 2, "%s.%s",
|
||||
conf_var_type_name, conf_var_name) < 0) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ConfGet(conf_var_full_name, &conf_var_full_name_value) != 1)
|
||||
goto end;
|
||||
|
||||
SCLogDebug("Value obtained from the yaml conf file, for the var "
|
||||
"\"%s\" is \"%s\"", conf_var_name, conf_var_full_name_value);
|
||||
|
||||
end:
|
||||
if (conf_var_full_name != NULL)
|
||||
free(conf_var_full_name);
|
||||
SCReturnCharPtr(conf_var_full_name_value);
|
||||
}
|
||||
|
||||
|
||||
/**********************************Unittests***********************************/
|
||||
|
||||
static const char *dummy_conf_string =
|
||||
"default-log-dir: /var/log/eidps\n"
|
||||
"\n"
|
||||
"logging:\n"
|
||||
"\n"
|
||||
" default-log-level: debug\n"
|
||||
"\n"
|
||||
" default-format: \"<%t> - <%l>\"\n"
|
||||
"\n"
|
||||
" default-startup-message: Your IDS has started.\n"
|
||||
"\n"
|
||||
" default-output-filter:\n"
|
||||
"\n"
|
||||
" output:\n"
|
||||
"\n"
|
||||
" - interface: console\n"
|
||||
" log-level: info\n"
|
||||
"\n"
|
||||
" - interface: file\n"
|
||||
" filename: /var/log/eidps.log\n"
|
||||
"\n"
|
||||
" - interface: syslog\n"
|
||||
" facility: local5\n"
|
||||
" format: \"%l\"\n"
|
||||
"\n"
|
||||
"pfring:\n"
|
||||
"\n"
|
||||
" interface: eth0\n"
|
||||
"\n"
|
||||
" clusterid: 99\n"
|
||||
"\n"
|
||||
"vars:\n"
|
||||
"\n"
|
||||
" address-groups:\n"
|
||||
"\n"
|
||||
" HOME_NET: \"[192.168.0.0/16,10.8.0.0/16,127.0.0.1,2001:888:"
|
||||
"13c5:5AFE::/64,2001:888:13c5:CAFE::/64]\"\n"
|
||||
"\n"
|
||||
" EXTERNAL_NET: \"[!192.168.0.0/16,2000::/3]\"\n"
|
||||
"\n"
|
||||
" HTTP_SERVERS: \"!192.168.0.0/16\"\n"
|
||||
"\n"
|
||||
" SMTP_SERVERS: \"!192.168.0.0/16\"\n"
|
||||
"\n"
|
||||
" SQL_SERVERS: \"!192.168.0.0/16\"\n"
|
||||
"\n"
|
||||
" DNS_SERVERS: any\n"
|
||||
"\n"
|
||||
" TELNET_SERVERS: any\n"
|
||||
"\n"
|
||||
" AIM_SERVERS: any\n"
|
||||
"\n"
|
||||
" port-groups:\n"
|
||||
"\n"
|
||||
" HTTP_PORTS: \"80:81,88\"\n"
|
||||
"\n"
|
||||
" SHELLCODE_PORTS: 80\n"
|
||||
"\n"
|
||||
" ORACLE_PORTS: 1521\n"
|
||||
"\n"
|
||||
" SSH_PORTS: 22\n"
|
||||
"\n";
|
||||
|
||||
/**
|
||||
* \test Check that valid address and port group vars are correctly retrieved
|
||||
* from the configuration.
|
||||
*/
|
||||
int SCRuleVarsPositiveTest01(void)
|
||||
{
|
||||
int result = 1;
|
||||
|
||||
ConfCreateContextBackup();
|
||||
ConfInit();
|
||||
ConfYamlLoadString((u_char *)dummy_conf_string, strlen(dummy_conf_string));
|
||||
|
||||
/* check for address-groups */
|
||||
result &= (SCRuleVarsGetConfVar("$HOME_NET", SC_RULE_VARS_ADDRESS_GROUPS) != NULL &&
|
||||
strcmp(SCRuleVarsGetConfVar("$HOME_NET", SC_RULE_VARS_ADDRESS_GROUPS),
|
||||
"[192.168.0.0/16,10.8.0.0/16,127.0.0.1,2001:888:13c5:"
|
||||
"5AFE::/64,2001:888:13c5:CAFE::/64]") == 0);
|
||||
result &= (SCRuleVarsGetConfVar("$EXTERNAL_NET", SC_RULE_VARS_ADDRESS_GROUPS) != NULL &&
|
||||
strcmp(SCRuleVarsGetConfVar("$EXTERNAL_NET", SC_RULE_VARS_ADDRESS_GROUPS),
|
||||
"[!192.168.0.0/16,2000::/3]") == 0);
|
||||
result &= (SCRuleVarsGetConfVar("$HTTP_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS) != NULL &&
|
||||
strcmp(SCRuleVarsGetConfVar("$HTTP_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS),
|
||||
"!192.168.0.0/16") == 0);
|
||||
result &= (SCRuleVarsGetConfVar("$SMTP_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS) != NULL &&
|
||||
strcmp(SCRuleVarsGetConfVar("$SMTP_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS),
|
||||
"!192.168.0.0/16") == 0);
|
||||
result &= (SCRuleVarsGetConfVar("$SQL_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS) != NULL &&
|
||||
strcmp(SCRuleVarsGetConfVar("$SQL_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS),
|
||||
"!192.168.0.0/16") == 0);
|
||||
result &= (SCRuleVarsGetConfVar("$DNS_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS) != NULL &&
|
||||
strcmp(SCRuleVarsGetConfVar("$DNS_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS),
|
||||
"any") == 0);
|
||||
result &= (SCRuleVarsGetConfVar("$TELNET_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS) != NULL &&
|
||||
strcmp(SCRuleVarsGetConfVar("$TELNET_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS),
|
||||
"any") == 0);
|
||||
result &= (SCRuleVarsGetConfVar("$AIM_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS) != NULL &&
|
||||
strcmp(SCRuleVarsGetConfVar("$AIM_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS),
|
||||
"any") == 0);
|
||||
|
||||
/* check for port-groups */
|
||||
result &= (SCRuleVarsGetConfVar("$HTTP_PORTS", SC_RULE_VARS_PORT_GROUPS) != NULL &&
|
||||
strcmp(SCRuleVarsGetConfVar("$HTTP_PORTS", SC_RULE_VARS_PORT_GROUPS),
|
||||
"80:81,88") == 0);
|
||||
result &= (SCRuleVarsGetConfVar("$SHELLCODE_PORTS", SC_RULE_VARS_PORT_GROUPS) != NULL &&
|
||||
strcmp(SCRuleVarsGetConfVar("$SHELLCODE_PORTS", SC_RULE_VARS_PORT_GROUPS),
|
||||
"80") == 0);
|
||||
result &= (SCRuleVarsGetConfVar("$ORACLE_PORTS", SC_RULE_VARS_PORT_GROUPS) != NULL &&
|
||||
strcmp(SCRuleVarsGetConfVar("$ORACLE_PORTS", SC_RULE_VARS_PORT_GROUPS),
|
||||
"1521") == 0);
|
||||
result &= (SCRuleVarsGetConfVar("$SSH_PORTS", SC_RULE_VARS_PORT_GROUPS) != NULL &&
|
||||
strcmp(SCRuleVarsGetConfVar("$SSH_PORTS", SC_RULE_VARS_PORT_GROUPS),
|
||||
"22") == 0);
|
||||
|
||||
ConfDeInit();
|
||||
ConfRestoreContextBackup();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \test Check that invalid address and port groups are properly handled by the
|
||||
* API.
|
||||
*/
|
||||
int SCRuleVarsNegativeTest02(void)
|
||||
{
|
||||
int result = 1;
|
||||
|
||||
ConfCreateContextBackup();
|
||||
ConfInit();
|
||||
ConfYamlLoadString((u_char *)dummy_conf_string, strlen(dummy_conf_string));
|
||||
|
||||
result &= (SCRuleVarsGetConfVar("$HOME_NETW", SC_RULE_VARS_ADDRESS_GROUPS) == NULL);
|
||||
result &= (SCRuleVarsGetConfVar("$home_net", SC_RULE_VARS_ADDRESS_GROUPS) == NULL);
|
||||
|
||||
result &= (SCRuleVarsGetConfVar("$TOMCAT_PORTSW", SC_RULE_VARS_PORT_GROUPS) == NULL);
|
||||
result &= (SCRuleVarsGetConfVar("$tomcat_ports", SC_RULE_VARS_PORT_GROUPS) == NULL);
|
||||
|
||||
ConfDeInit();
|
||||
ConfRestoreContextBackup();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \test Check that Signatures with valid address and port groups are parsed
|
||||
* without any errors by the Signature parsing API.
|
||||
*/
|
||||
int SCRuleVarsPositiveTest03(void)
|
||||
{
|
||||
int result = 0;
|
||||
Signature *s = NULL;
|
||||
DetectEngineCtx *de_ctx = NULL;
|
||||
|
||||
ConfCreateContextBackup();
|
||||
ConfInit();
|
||||
ConfYamlLoadString((u_char *)dummy_conf_string, strlen(dummy_conf_string));
|
||||
|
||||
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
|
||||
goto end;
|
||||
de_ctx->flags |= DE_QUIET;
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp $HTTP_SERVERS any -> any any (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp $SMTP_SERVERS any -> $HTTP_SERVERS any (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp $AIM_SERVERS any -> $AIM_SERVERS any (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp $TELNET_SERVERS any -> any $SSH_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp $TELNET_SERVERS any -> any !$SSH_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp $TELNET_SERVERS 80 -> any !$SSH_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp $TELNET_SERVERS !80 -> any !$SSH_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp !$HTTP_SERVERS !80 -> any !$SSH_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp 192.168.1.2 any -> any $HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp !192.168.1.2 any -> any $HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp !192.168.1.2 any -> any !$HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp !192.168.1.2 any -> !$HTTP_SERVERS !$HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp !192.168.1.2 $HTTP_PORTS -> !$HTTP_SERVERS !$HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp [!192.168.24.0/23,!167.12.0.0/24] any -> any $HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp ![192.168.24.0/23,!167.12.0.0/24] any -> any $HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp [$HOME_NET,!192.168.1.2] $HTTP_PORTS -> !$HTTP_SERVERS !$HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp [[192.168.1.3,$EXTERNAL_NET],192.168.2.5] $HTTP_PORTS -> !$HTTP_SERVERS !$HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp [[192.168.1.3,$EXTERNAL_NET],192.168.2.5] $HTTP_PORTS -> !$HTTP_SERVERS [80,[!$HTTP_PORTS,$ORACLE_PORTS]] (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp [![192.168.1.3,$EXTERNAL_NET],[$HTTP_SERVERS,!$HOME_NET],192.168.2.5] $HTTP_PORTS -> !$HTTP_SERVERS [80,[!$HTTP_PORTS,$ORACLE_PORTS]] (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s == NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
result = 1;
|
||||
|
||||
end:
|
||||
ConfDeInit();
|
||||
ConfRestoreContextBackup();
|
||||
|
||||
if (de_ctx != NULL)
|
||||
DetectEngineCtxFree(de_ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \test Check that Signatures with invalid address and port groups, are
|
||||
* are invalidated by the Singature parsing API.
|
||||
*/
|
||||
int SCRuleVarsNegativeTest04(void)
|
||||
{
|
||||
int result = 0;
|
||||
Signature *s = NULL;
|
||||
DetectEngineCtx *de_ctx = NULL;
|
||||
|
||||
ConfCreateContextBackup();
|
||||
ConfInit();
|
||||
ConfYamlLoadString((u_char *)dummy_conf_string, strlen(dummy_conf_string));
|
||||
|
||||
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
|
||||
goto end;
|
||||
de_ctx->flags |= DE_QUIET;
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp $HTTP_SERVER any -> any any (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s != NULL)
|
||||
goto end;
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp $http_servers any -> any any (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s != NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp $http_servers any -> any $HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s != NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
s = SigInit(de_ctx, "alert tcp !$TELNET_SERVERS !80 -> any !$SSH_PORTS (msg:\"Rule Vars Test\"; sid:1;)");
|
||||
if (s != NULL)
|
||||
goto end;
|
||||
SigFree(s);
|
||||
|
||||
result = 1;
|
||||
|
||||
end:
|
||||
ConfDeInit();
|
||||
ConfRestoreContextBackup();
|
||||
|
||||
if (de_ctx != NULL)
|
||||
DetectEngineCtxFree(de_ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
void SCRuleVarsRegisterTests(void)
|
||||
{
|
||||
|
||||
#ifdef UNITTESTS
|
||||
UtRegisterTest("SCRuleVarsPositiveTest01", SCRuleVarsPositiveTest01, 1);
|
||||
UtRegisterTest("SCRuleVarsNegativeTest02", SCRuleVarsNegativeTest02, 1);
|
||||
UtRegisterTest("SCRuleVarsPositiveTest03", SCRuleVarsPositiveTest03, 1);
|
||||
UtRegisterTest("SCRuleVarsNegativeTest04", SCRuleVarsNegativeTest04, 1);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
/** Copyright (c) 2009 Open Information Security Foundation.
|
||||
* \author Anoop Saldanha <poonaatsoc@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_RULE_VARS_H__
|
||||
#define __UTIL_RULE_VARS_H__
|
||||
|
||||
/** Enum indicating the various vars type in the yaml conf file */
|
||||
typedef enum {
|
||||
SC_RULE_VARS_ADDRESS_GROUPS,
|
||||
SC_RULE_VARS_PORT_GROUPS,
|
||||
} SCRuleVarsType;
|
||||
|
||||
char *SCRuleVarsGetConfVar(const char *, SCRuleVarsType);
|
||||
void SCRuleVarsRegisterTests(void);
|
||||
|
||||
#endif /* __UTIL_RULE_VARS_H__ */
|
||||
Loading…
Reference in New Issue