suricata7.0.5
加载options
(msg:“HTTP Request Example”; flow:established,to_server; http.method; content:“POST”; http.uri; content:“query.php”; bsize:>9; http.protocol; content:“HTTP/1.1”; bsize:8; http.host; content:“360”; bsize:>3; classtype:bad-unknown; sid:25; rev:1;)
SigParseOptions(...)
大致逻辑:
- 通过
;
拆分,获取单个的关键字以及值 - 通过
:
拆分,获取关键字名称以及值 - 调用
SigTableGet
函数,通过关键字名称获取对应的提前注册好的关键字节点 - 调用节点中设置的
Setup
回调函数进行处理
以下按照rule中的顺序依次进行解析
msg
"msg" -> sigmatch_table[DETECT_MSG] -> DetectMsgSetup
flow
"flow" -> sigmatch_table[DETECT_FLOW] -> DetectFlowSetup
http.method
"http.method" -> sigmatch_table[DETECT_HTTP_METHOD] -> DetectHttpMethodSetupSticky
content
"content" -> sigmatch_table[DETECT_CONTENT] -> DetectContentSetup
这里的content是关联前面http.method,通过sig->init_data->list
进行关联,SigMatch节点是挂在id=g_http_method_buffer_id的位置,如果后面还有bsize等关键字关联http.method的则会链式的继续挂在后面。如下图
http.uri
"http.uri" -> sigmatch_table[DETECT_HTTP_URI] -> DetectHttpUriSetupSticky
content
bsize
"bsize" -> sigmatch_table[DETECT_BSIZE] -> DetectBsizeSetup
http.protocol
"http.protocol" -> sigmatch_table[DETECT_AL_HTTP_PROTOCOL] -> DetectHttpProtocolSetup
content
bsize
http.host
"http.host" -> sigmatch_table[DETECT_HTTP_HOST] -> DetectHttpHostSetup
content
bsize
classtype
"classtype" -> sigmatch_table[DETECT_CLASSTYPE] -> DetectClasstypeSetup
sid
实际上代码里,sid是第一个解析的,因为每个rule都必须有sid,如果没有则可以快速的跳过。
"sid" -> sigmatch_table[DETECT_SID] -> DetectSidSetup
rev
"rev" -> sigmatch_table[DETECT_REV] -> DetectRevSetup
总结
sig->init_data->buffers中的每个节点对应一个关键字,其中的id
对应g_buffer_type_hash
中的关键字编号
到这里,第一步将rule加载到内存中算是完成。
接下来就是最关键的如何将其构建成匹配树。