一 snort输出插件
1.含义:
当snort检测到相关风险,会调用输出插件输出相关信息,例如,将告警信息发送到syslog服务器或者数据库进行存储等。
2.在配置文件中定义输出插件:
snort.conf可指定多个输出插件,具体格式是output 插件名:可选项信息,例如:
output alert_syslog:log_auth log_alert #将告警信息发送到syslog服务器 log_auth为syslog的设施 log_alert为优先事项
output log_tcpdump: /opt/xx.pcap 1024 #将数据包输出tcpdump文件,文件大小限制为1024字节
output alert_mdb:default #将告警信息输出到共享内存mdb
二 输出插件注册流程
1.SnortInit完成snort所有初始化工作,包括解析命令行参数,初始化snort配置,初始化snort相关预处理插件链表,输出插件链表等;
2.SnortInit调用RegisterOutputPlugins进行输出插件注册工作,RegisterOutputPlugins为注册输出插件主入口,编程者可根据需求增加相关输出插件注册工作;
3.在改造后的snort引擎中,只有1种输出插件即alert_mdb,它具体的作用是将snort风险数据输出到mdb,供业务进程使用;
4.RegisterOutputPlugin将输出插件名称、告警类型和相关初始化函数形成结点插入到输出插件链表尾部。
三 RegisterOutputPlugin函数分析
1.输出插件结点OutputConfigFuncNode
typedef struct _OutputConfigFuncNode
{
char *keyword; // 对应snort.conf输出插件名称 比如mdb_alert
int output_type_flags; // 告警标记(告警ALERT,日志LOG,全部ALL)
union {
OutputConfigFunc fptr; // 输出插件处理函数 该函数作用是执行具体的输出工作 比如将风险数据保存到共享内存,将风险数据输出到syslog等
void *void_fptr;
} cfptr;
struct _OutputConfigFuncNode *next;
} OutputConfigFuncNode;
2.函数流程
void RegisterOutputPlugin(char *keyword, int type_flags, OutputConfigFunc oc_func)
{
OutputConfigFuncNode *node = ... // 创建新结点
if (output_config_funcs == NULL) // 指向链表首结点
{
output_config_funcs = node;
}
else
{
...
// 如果链表已经有关键词为keywoord的结点,则释放新增结点 函数返回
// 将node插件链表尾部
}
}
四 MDB输出插件初始化函数AlertMDBInit分析
1.插件可选项结构体AlertMDBData
typedef struct _AlertMDBData
{
char *mdbargs;
char **args;
int numargs;
AlertMDBConfig *config;
} AlertMDBData;
AlertMDBData是snort.conf定义输出插件的可选项,如mdb_alert插件的default,syslog:log插件的auth,log_alert等。
2.参数解析函数AlertMDBParseArgs
static AlertMDBData *AlertMBDParseArgs(struct _SnortConfig *sc, char *args)
{
data = (AlertMDBData *)SnortAlloc... // 分配新结点
...
toks = mSplit((char *)args, " \t", 1, &num_toks, "\\"); // 将参数args按照"\t"分割
for (i = 0;i < num_toks;i++)
{
const char *tok = toks[i];
...
// 获取每一个token 如果和default相同,则将data的mdbargs设置为"timestamp,sig_generator...payload"
}
...
}
3.将输出插件函数实体插入输出链表AddFuncToOutputList
void AddFuncToOutputList(SnortConfig *sc, OutputFunc o_func, OutputType type, void *arg)
{
switch(type)
{
case OUTPUT_TYPE_ALERT:
if (sc->head_tmp != NULL)
AppendOutputFuncList(o_func, arg, &sc->head_tmp->AlertList); // 插入到snort配置变量sc的链表尾部
else
AppendOutputFuncList(o_func, arg, &AlertList); // 插入到全局变量AlertList的链表尾部
...
}
...
}
4.输出插件执行实体RealAlertMDB分析
该函数定义在snort.cc中,其作用是匹配相应规则后生成风险信息塞入mdb,供业务进程使用。