snort代碼處理流程

http://www.cppblog.com/iniwf/archive/2012/05/18/77468.html


SnortMain
-SnortInit
--RegisterPreprocessors  註冊處理函數
--RegisterRuleOptions
---SetupPatternMatch
----RegisterRuleOption("content", PayloadSearchInit, NULL, OPT_TYPE_DETECTION, NULL);
-----fpl = AddOptFuncToList(CheckANDPatternMatch, otn);
--ParseSnortConf 如果“配置文件”不爲空,則執行此函數
---sfPolicyAdd  按照文件名,添加一個tSfPolicy。
---sfSetDefaultPolicy  對應有policy_id,設置爲default的policy_id。
---ParseConfigFile
----ParseRule
規則頭由RuleTreeNode(RTN)結構表示
-----ProcessIP 解析IP
-----ParsePortList 端口
-----ProcessHeadNode 設置規則頭的匹配函數
------SetupRTNFuncList
-------PortToFunc 端口檢查函數掛入RuleFpList鏈表
-------AddrToFunc IP檢查掛入RuleFpList鏈表
-------AddRuleFuncToList(RuleListEnd, rtn); 最後掛一個RuleListEnd
規則選項由OptTreeNode(OTN)表示
-----ParseRuleOptions
------GetOTN
--ParseRules
---ParseConfigFile,同上
---PortTablesFinish
----finish_portlist_table
--fpCreateFastPacketDetection
---fpCreatePortGroups
----fpCreatePortObject2PortGroup
-----fpAddPortGroupRule  按照端口組,添加規則
------fpFinishPortGroupRule
-------mpseAddPatternWithSnortConfig
-----fpFinishPortGroup  
------mpsePrepPatternsWithSnortConf 按照端口組,編譯規則AC狀態機
-------acsmCompileWithSnortConf
--------pmx_create_tree 生成以detection_option_tree_root_t爲根的樹。節點爲detection_option_tree_node_t
------otn_create_tree(otn, &pg->pgNonContentTree); 把無content的規則加入狀態樹。
-SnortStartThreads
--ReloadConfigThread
---ReloadConfig
----ParseSnortConf,同上
----ParseRules 同上
-PacketLoop
--PacketCallback
---ProcessPacket
----Preprocess
-----Detect
------fpEvalPacket
-------fpEvalHeaderTcp
--------prmFindRuleGroupTcp  找端口group
---------prmFindRuleGroup
--------fpEvalHeaderSW
---------mpseSearch
----------rule_tree_match 特徵匹配後,做精確匹配
-----------detection_option_tree_evaluate
------------detection_option_node_evaluate
-------------CheckANDPatternMatch,uniSearchCI或uniSearch
--------fpFinalSelectEvent


OTN存儲在hash表中

RTN獨立存儲,和OTN關聯;多個OTN可能對應同一個RTN。


alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any  -------------------------------- 存儲到RTN中
(msg:"DELETED BROWSER-PLUGINS Microsoft Internet Explorer RDS.Dataspace ActiveX object code execution attempt"; 
flow:to_client,established; file_data; 
content:"BD96C556-65A3-11D0-983A-00C04FC29E36"; fast_pattern:only;  ---------------------------- 對應一個PMD
content:"Shell.application"; nocase; 
pcre:"/(\w+)\s*?\x3D\s*?document\x2Ecreateelement.*?\1\x2EsetAttribute.*?BD96C556-65A3-11D0-983A-00C04FC29E36.*?\1\x2EcreateObject\x28[\x22\x27]Shell\x2EApplication/smi"; 
reference:bugtraq,17462; 
reference:cve,2006-0003; 
reference:url,technet.microsoft.com/en-us/security/bulletin/MS06-014; 
classtype:attempted-user; 
sid:21081; 
rev:9;)      ------------------------ 整個存儲到OTN中


typedef struct _PatternMatchData
{
    int offset;             /* pattern search start offset */
    int depth;              /* pattern search depth */


    int distance;           /* offset to start from based on last match */
    u_int within;           /* this pattern must be found
                               within X bytes of last match*/


    int8_t offset_var;      /* byte_extract variable indices for offset, */
    int8_t depth_var;       /* depth, distance, within */
    int8_t distance_var;
    int8_t within_var;


    int rawbytes;           /* Search the raw bytes rather than any decoded app
                               buffer */
    int replace_depth;      /* >=0 is offset to start of replace */


    int nocase;             /* Toggle case insensitity */
    int use_doe;            /* Use the doe_ptr for relative pattern searching */
    HTTP_BUFFER http_buffer;/* Index of the URI buffer */
    int buffer_func;        /* buffer function CheckAND or CheckUri */
    u_int pattern_size;     /* size of app layer pattern */
    u_int replace_size;     /* size of app layer replace pattern */
    char *replace_buf;      /* app layer pattern to replace with */
    char *pattern_buf;      /* app layer pattern to match on */
    int (*search)(const char *, int, struct _PatternMatchData *);  /* search function */
    int *skip_stride; /* B-M skip array */
    int *shift_stride; /* B-M shift array */
    u_int pattern_max_jump_size; /* Maximum distance we can jump to search for
                                  * this pattern again. */
    OptFpList *fpl;         /* Pointer to the OTN FPList for this pattern */
                            /* Needed to be able to set the isRelative flag */


    /* Set if fast pattern matcher found a content in the packet,
       but the rule option specifies a negated content. Only
       applies to negative contents that are not relative */
    struct
    {
        struct timeval ts;
        uint64_t packet_number;
        uint32_t rebuild_flag;


    } last_check;


    /* For fast_pattern arguments */
    uint8_t fp;
    uint8_t fp_only;
    uint16_t fp_offset;
    uint16_t fp_length;


    uint8_t exception_flag; /* search for "not this pattern" */


    /* Used in ds_list - do not try to iterate after parsing a rule
     * since the detection option tree will eliminate duplicates and
     * the list may have missing pmds */
    struct _PatternMatchData *prev; /* ptr to previous match struct */
    struct _PatternMatchData *next; /* ptr to next match struct */


} PatternMatchData;


typedef struct _OptFpList
{
    /* context data for this test */
    void *context; ------------- 如果是content類型,存儲的即是PMD.


    int (*OptTestFunc)(void *option_data, Packet *p);


    struct _OptFpList *next;


    unsigned char isRelative;
    option_type_t type;


} OptFpList;


typedef struct _RuleTreeNode
{
    RuleFpList *rule_func; /* match functions.. (Bidirectional etc.. ) */  -------- 檢查ip、端口等的函數鏈表。


    int head_node_number;


    RuleType type;


    IpAddrSet *sip;
    IpAddrSet *dip;


    int proto;


    PortObject * src_portobject;
    PortObject * dst_portobject;


    uint32_t flags;     /* control flags */


    /* stuff for dynamic rules activation/deactivation */
    int active_flag;
    int activation_counter;
    int countdown;
    ActivateListNode *activate_list;


#if 0
    struct _RuleTreeNode *right;  /* ptr to the next RTN in the list */


    /** list of rule options to associate with this rule node */
    OptTreeNode *down;   
#endif


    /**points to global parent RTN list (Drop/Alert) which contains this 
     * RTN.
     */
    struct _ListHead *listhead;


    /**reference count from otn. Multiple OTNs can reference this RTN with the same
     * policy.
     */
    unsigned int otnRefCount;



} RuleTreeNode;


typedef struct _OptTreeNode
{
    /* plugin/detection functions go here */
    OptFpList *opt_func;
    RspFpList *rsp_func;  /* response functions */
    OutputFuncNode *outputFuncs; /* per sid enabled output functions */


    /* the ds_list is absolutely essential for the plugin system to work,
       it allows the plugin authors to associate "dynamic" data structures
       with the rule system, letting them link anything they can come up 
       with to the rules list */
    void *ds_list[PLUGIN_MAX];   /* list of plugin data struct pointers */ -------------------- PLUGIN_PATTERN_MATCH,存儲PMD


    int chain_node_number;


    int evalIndex;       /* where this rule sits in the evaluation sets */


    int proto;           /* protocol, added for integrity checks 
                            during rule parsing */


    int session_flag;    /* record session data */


    char *logto;         /* log file in which to write packets which 
                            match this rule*/
    /* metadata about signature */
    SigInfo sigInfo;


    uint8_t stateless;  /* this rule can fire regardless of session state */
    uint8_t established; /* this rule can only fire if it is established */
    uint8_t unestablished;


    Event event_data;


    void* detection_filter; /* if present, evaluated last, after header checks */
    TagData *tag;


    /* stuff for dynamic rules activation/deactivation */
    int active_flag;
    int activation_counter;
    int countdown;
    int activates;
    int activated_by;


    struct _OptTreeNode *OTN_activation_ptr;
    struct _RuleTreeNode *RTN_activation_ptr;


    struct _OptTreeNode *next;


    struct _OptTreeNode *nextSoid;


    /* ptr to list of RTNs (head part) */
    struct _RuleTreeNode **proto_nodes;


    /**number of proto_nodes. */
    unsigned short proto_node_num;


    uint8_t failedCheckBits;
    char generated;


    uint16_t longestPatternLen;


    int rule_state; /* Enabled or Disabled */


#ifdef PERF_PROFILING
    uint64_t ticks;
    uint64_t ticks_match;
    uint64_t ticks_no_match;
    uint64_t checks;
    uint64_t matches;
    uint64_t alerts;
    uint8_t noalerts;
#endif


    int pcre_flag; /* PPM */
    uint64_t ppm_suspend_time; /* PPM */
    uint64_t ppm_disable_cnt; /*PPM */


    uint32_t num_detection_opts;


    /**unique index generated in ruleIndexMap.
     */
    int ruleIndex;


    /* List of preprocessor registered fast pattern contents */
    void *preproc_fp_list;


} OptTreeNode;



/*
*   Aho-Corasick State Machine Struct - one per group of pattterns
*/
typedef struct {


    int acsmMaxStates;
    int acsmNumStates;


    ACSM_PATTERN2    * acsmPatterns;     ----------- 模式鏈表。(第1步得到的)
    acstate_t        * acsmFailState;
    ACSM_PATTERN2   ** acsmMatchList;    ----------- 有些終止狀態,即匹配成功。此處存儲ACSM_PATTERN2的匹配鏈表。(2)


    /* list of transitions in each state, this is used to build the nfa & dfa */
    /* after construction we convert to sparse or full format matrix and free */
    /* the transition lists */
    trans_node_t ** acsmTransTable;     ------------ 根據所有“模式”,得出其“轉換表”。如果acsmMatchList的第N列存在終止狀態,則acsmTransTable的第N列爲空,添加(2)


    acstate_t ** acsmNextState; ----------- 把acsmTransTable中的每列“模式”進行轉換,每一列嘗試壓縮存儲爲“數組鏈表”。生成它之後會把acsmMatchList和acsmFailState都刪掉。(3)
    int          acsmFormat;
    int          acsmSparseMaxRowNodes;
    int          acsmSparseMaxZcnt;


    int          acsmNumTrans;
    int          acsmAlphabetSize;
    int          acsmFSA;
    int          numPatterns;         ------------- 模式個數
    void         (*userfree)(void *p);
    void         (*optiontreefree)(void **p);
    void         (*neg_list_free)(void **p);
    PMQ q;
    int sizeofstate;     ------ acsmNumStates個數決定了用幾個字節存儲acsmNextState的每一列的每一個“模式”。
    int compress_states;


}ACSM_STRUCT2;


typedef
struct _acsm_pattern2
{
    struct  _acsm_pattern2 *next;


    unsigned char         *patrn;      -------- 匹配字符
    unsigned char         *casepatrn;  -------- 大寫的匹配字符
    int      n; ------------匹配字符的長度
    int      nocase;
    int      offset;
    int      depth;
    int      negative;
    void   *udata; ------------------ 爲PMX,存儲
    int      iid;
    void   * rule_option_tree; ------------------- build tree之後存儲輸出信息。爲detection_option_tree_root_t *.
    void   * neg_list;


} ACSM_PATTERN2;


typedef struct _OptTreeNode
{
    /* plugin/detection functions go here */
    OptFpList *opt_func;--------包含OptFpList鏈表,RULE_OPTION_TYPE_CONTENT對應的OptFpList裏面再包含一個PMD。
    void *ds_list[PLUGIN_MAX];   /* list of plugin data struct pointers */------------- 裏面包含多個鏈表,按類型分。如PLUGIN_PATTERN_MATCH的鏈表裏面包含所有PMD鏈表。
} ----------- 一個OTN對應一個單包rule,包含所有PMD。


/* same as the rule header FP list */
typedef struct _OptFpList
{
    /* context data for this test */
    void *context;       ----------------- 執行PMD
    int (*OptTestFunc)(void *option_data, Packet *p); ------- 對應的處理回調函數,如CheckUriPatternMatch
    struct _OptFpList *next;   ---------------  鏈表
    unsigned char isRelative;
    option_type_t type; ---------- 執行爲content類型,如RULE_OPTION_TYPE_CONTENT。
} OptFpList;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章