4.3 Snort 實例
本節提供一個動態預處理器和動態規則的簡單示例。
4.3.1 預處理器實例
下面是一個簡單的預處理器示例。如果TCP端口與配置的端口匹配,此預處理器總是對數據包發出警報。
以下代碼是在spp_example中定義的。和與libsf_dynamic_preproc.a一起編譯。使用pkg-config,到lib_sfdynamic_preprocessor_example.so中。
定義所需的元數據變量。
#define GENERATOR_EXAMPLE 256
extern DynamicPreprocessorData _dpd;
const int MAJOR_VERSION = 1;
const int MINOR_VERSION = 0;
const int BUILD_VERSION = 0;
const char *PREPROC_NAME = "SF_Dynamic_Example_Preprocessor";
#define ExampleSetup DYNAMIC_PREPROC_SETUP
定義Setup函數來注冊初始化函數。
void ExampleInit(unsigned char *);
void ExampleProcess(void *, void *);
void ExampleSetup()
{
_dpd.registerPreproc("dynamic_example", ExampleInit);
DEBUG_WRAP(_dpd.debugMsg(DEBUG_PLUGIN, "Preprocessor: Example is setup\n"););
}
用于解析’ snort.conf ‘中的關鍵字的初始化函數。
u_int16_t portToCheck;
void ExampleInit(unsigned char *args)
{
char *arg;
char *argEnd;
unsigned long port;
_dpd.logMsg("Example dynamic preprocessor configuration\n");
arg = strtok(args, " \t\n\r");
if(!strcasecmp("port", arg))
{
arg = strtok(NULL, "\t\n\r");
if (!arg)
{
_dpd.fatalMsg("ExamplePreproc: Missing port\n");
}
port = strtoul(arg, &argEnd, 10);
if (port < 0 || port > 65535)
{
_dpd.fatalMsg("ExamplePreproc: Invalid port %d\n", port);
}
portToCheck = port;
_dpd.logMsg(" Port: %d\n", portToCheck);
}
else
{
_dpd.fatalMsg("ExamplePreproc: Invalid option %s\n", arg);
}
/* Register the preprocessor function, Transport layer, ID 10000 */
_dpd.addPreproc(ExampleProcess, PRIORITY_TRANSPORT, 10000);
DEBUG_WRAP(_dpd.debugMsg(DEBUG_PLUGIN, "Preprocessor: Example is initialized\n"););
}
處理數據包并在端口匹配時記錄警報的函數。
#define SRC_PORT_MATCH 1
#define SRC_PORT_MATCH_STR "example_preprocessor: src port match"
#define DST_PORT_MATCH 2
#define DST_PORT_MATCH_STR "example_preprocessor: dest port match"
void ExampleProcess(void *pkt, void *context)
{
SFSnortPacket *p = (SFSnortPacket *)pkt;
if (!p->ip4_header || p->ip4_header->proto != IPPROTO_TCP || !p->tcp_header)
{
/* Not for me, return */
return;
}
if (p->src_port == portToCheck)
{
/* Source port matched, log alert */
_dpd.alertAdd(GENERATOR_EXAMPLE, SRC_PORT_MATCH,
1, 0, 3, SRC_PORT_MATCH_STR, 0);
return;
}
if (p->dst_port == portToCheck)
{
/* Destination port matched, log alert */
_dpd.alertAdd(GENERATOR_EXAMPLE, DST_PORT_MATCH,
1, 0, 3, DST_PORT_MATCH_STR, 0);
return;
}
}
4.3.2 規則
下面是一個簡單規則示例,取自當前規則集SID 109。實現它是為了與snort提供的檢測引擎一起工作。
正常格式的snort規則:
alert tcp $HOME_NET 12345:12346 -> $EXTERNAL_NET any
(msg:"BACKDOOR netbus active"; flow:from_server,established;
content:"NetBus"; reference:arachnids,401; classtype:misc-activity;
sid:109; rev:5;)
這是這個規則庫的元數據,在detection_lib_metta .h中定義。
/* Version for this rule library */
#define DETECTION_LIB_MAJOR_VERSION 1
#define DETECTION_LIB_MINOR_VERSION 0
#define DETECTION_LIB_BUILD_VERSION 1
#define DETECTION_LIB_NAME "Snort_Dynamic_Rule_Example"
/* Required version and name of the engine */
#define REQ_ENGINE_LIB_MAJOR_VERSION 1
#define REQ_ENGINE_LIB_MINOR_VERSION 0
#define REQ_ENGINE_LIB_NAME "SF_SNORT_DETECTION_ENGINE"
該規則的每個數據結構的定義在sid109.c中。
數據結構的聲明。
Flow 選項
定義FlowFlags結構及其對應的RuleOption。對于文本版本,流是from_server,已建立。
static FlowFlags sid109flow =
{
FLOW_ESTABLISHED|FLOW_TO_CLIENT
};
static RuleOption sid109option1 =
{
OPTION_TYPE_FLOWFLAGS,
{
&sid109flow
}
};
Content選項
定義ContentInfo結構及其對應的RuleOption。根據文本版本,內容是“NetBus”,沒有深度或偏移量,區分大小寫和非相關。默認情況下在規格化緩沖區上搜索。
注意:此內容將用于快速模式匹配器,因為它是該規則最長的內容選項,并且沒有內容具有CONTENT_FAST_PATTERN標記。
static ContentInfo sid109content =
{
"NetBus", /* pattern to search for */
0, /* depth */
0, /* offset */
CONTENT_BUF_NORMALIZED, /* flags */
NULL, /* holder for boyer/moore info */
NULL, /* holder for byte representation of "NetBus" */
0, /* holder for length of byte representation */
0 /* holder for increment length */
};
static RuleOption sid109option2 =
{
OPTION_TYPE_CONTENT,
{
&sid109content
}
};
Rule and Meta Data
定義的引用。
static RuleReference sid109ref_arachnids =
{
"arachnids", /* Type */
"401" /* value */
};
static RuleReference *sid109refs[] =
{
&sid109ref_arachnids,
NULL
};
規則選項列表。規則選項按照指定的順序計算。
RuleOption *sid109options[] =
{
&sid109option1,
&sid109option2,
NULL
};
規則本身,包含協議頭、元數據(sid、分類、消息等)。
Rule sid109 =
{
/* protocol header, akin to => tcp any any -> any any */
{
IPPROTO_TCP, /* proto */
HOME_NET, /* source IP */
"12345:12346", /* source port(s) */
0, /* Direction */
EXTERNAL_NET, /* destination IP */
ANY_PORT, /* destination port */
},
/* metadata */
{
3, /* genid -- use 3 to distinguish a C rule */
109, /* sigid */
5, /* revision */
"misc-activity", /* classification */
0, /* priority */
"BACKDOOR netbus active", /* message */
sid109refs /* ptr to references */
},
sid109options, /* ptr to rule options */
NULL, /* Use internal eval func */
0, /* Holder, not yet initialized, used internally */
0, /* Holder, option count, used internally */
0, /* Holder, no alert, used internally for flowbits */
NULL /* Holder, rule data, used internally */
此規則庫定義的規則列表
NULL終止的規則列表。InitializeDetection遍歷列表中的每個規則,并初始化內容、流位、pcre等。
extern Rule sid109;
extern Rule sid637;
Rule *rules[] =
{
&sid109,
&sid637,
NULL
};
Snort安裝使用中文手冊