一 snort规则头与规则体(规则选项)
1.snort规则:alter tcp $EXTERNAL_NET any <> $HOME_NET 0(msg:"BAD-TRAFFIC tcp port 0 traffic";flow:stateless;classtype:misc-activity;sid:524;rev:8;)
2.规则头:括号前面的部分,包括动作类型,协议,端口,IP,数据流向
3.规则体,也叫规则选项,是规则中最复杂的部分,是括号里的部分,包括消息,snort关键词,规则id,版本等信息。
二 snort三维链表
三维链表的数据结构分别代码分别位于rules.h和treenodes.h
1.第一层次:RuleListNode(一维)
typedef struct _RuleListNode
{
ListHead *RuleList; // 指向第二次链表
...
char *name; // alert log等关键词
struct _RuleListNode *next; // 串成链表
} RuleListNode;
2.第二层次:ListHead(一维)
typedef struct _ListHead
{
struct _OutputFuncNode *LogList;
struct _OutputFuncNode *AlertList;
struct _RuleListNode *ruleListNode; // 指向第一层结点
} ListHead;
ListHead包括输出函数链表指针和指向第一层结点指针
3.第三层次:RuleTreeNode(二维)
typedef struct _RuleTreeNode
{
...
// 以下几项 源IP 目的IP 协议 端口都出现在规则头里
IpAddrSet *sip;
IpAddrSet *dip;
int proto;
PortObject * src_portobject;
PortObject * dst_portobject;
...
struct _ListHead *listhead; // 指向第二层次结点
...
} RuleTreeNode;
4.第四层次:OptTreeNode(三维)
typedef struct _OptTreeNode
{
...
struct _RuleTreeNode *RTN_activation_ptr;
struct _RuleTreeNode **proto_nodes; // 指向上层结点
...
三 创建首次链表CreateDefaultRules(parser.c)
static void CreateDefaultRules(SnortConfig *sc)
{
...
CreateRuleType(sc, RULE_LIST_TYPE_ACTIVATION, RULE_TYPE_ACTIVATE, 1, &sc->Activation); // 创建activate链表
...
}
static ListHead * CreateRuleType(SnortConfig *sc, char *name, RuleType mode, int rval, ListHead *head)
{
RuleListNode *node;
...
node = (RuleListNode *)SnortAlloc(sizeof(RuleListNode));
...
#以下代码将node挂到sc->rule_lists 将Head挂到node->RuleList
}
四 从snortg规则文件解析规则创建三维链表ParseConfigFile(parser.c)
static void ParseConfigFile(SnortConfig *sc, SnortPolicy *p, char *fname)
{
...
for (node = sc->rule_list;node != NULL;node = node->next)
{
// 查询相同关键词的结点
}
...
if (node->mode == RULE_TYPE_DROP)
...
ParseRule(sc, p, args, RULE_TYPE__ALERT, node->RuleList); // 创建低维链表
...
}