frag3预处理器负责对IP分片报文进行重组。配置文件/etc/snort/snort.conf中关于frag3的配置如下。其中,全局配frag3_global设置最大的分片数量为65536。引擎frag3_engine配置了策略policy使用windows,重组过程中检测异常detect_anomalies,一个完整报文的分片重叠限制在10个,最小的分片长度为100,分片最长生存期为180秒。

# Target-based IP defragmentation.  For more inforation, see README.frag3
preprocessor frag3_global: max_frags 65536
preprocessor frag3_engine: policy windows detect_anomalies overlap_limit 10 min_fragment_length 100 timeout 180

Frag3初始化

SetupFrag3函数注册预处理器frag3_global和frag3_engine的初始化函数Frag3GlobalInit和Frag3Init。前者负责全局配置的初始化,后者负责初始化引擎。

void SetupFrag3(void)
{
    RegisterPreprocessor("frag3_global", Frag3GlobalInit);
    RegisterPreprocessor("frag3_engine", Frag3Init);

IP分片处理

核心的分片处理函数为Frag3Defrag。每个报文的分片由结构FragTracker表示,对于分片报文,先查看是否已经存在FragTracker结构。如果是报文的第一个分片,需要新建FragTracker。否则,将分片插入到现有的FragTracker结构。

最后,判断报文的所有分片是否已经到达,重组报文。

在这里插入图片描述

查找FragTracker

根据报文中的信息,组成查找所需的FRAGKEY结构。包括源IP、目的IP、IP标识ID、IP版本和协议号等。如果报文包含VLAN头部,Key值包括vlan ID值。

static FragTracker *Frag3GetTracker(Packet *p, FRAGKEY *fkey)
{
    FragTracker *returned; /* FragTracker ptr returned by the lookup */

    /* if the hash table is empty we're done
     */
    if(sfxhash_count(f_cache) == 0)
        return NULL;

    returned = (FragTracker *) sfxhash_find(f_cache, fkey);
    return returned;

创建Frag3NewTracker

对于报文的第一个分片,创建新的FragTracker结构。sfxhash_get_node函数分配一个新的哈希节点SFXHASH_NODE。

static int Frag3NewTracker(Packet *p, FRAGKEY *fkey, Frag3Context *f3context)
{
    FragTracker *tmp;
    Frag3Frag *f = NULL;
    const uint8_t *fragStart;
    SFXHASH_NODE *hnode;
    tSfPolicyId policy_id = getNapRuntimePolicy();

    fragStart = p->ip_frag_start;
    fragLength = p->ip_frag_len;

    // Try to get a new one
    if (!(hnode = sfxhash_get_node(f_cache, fkey)) || !hnode->data) {
        DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Frag3NewTracker: sfxhash_get_node() failed\n"););
        return 0;
    }
    tmp = (FragTracker *)hnode->data;
    memset(tmp, 0, sizeof(FragTracker));

涉及到的结构体如下:

在这里插入图片描述

插入新分片

Frag3Insert函数负责新IP分片的处理,包括合法性检查,重叠检查合并等。依据不同的frag_policy策略,对报文的处理有所不同。

在这里插入图片描述

分片重组

Frag3Rebuild函数负责分片重组,重组之后的报文拷贝到预先分配好的defrag_pkt或者encap_defrag_pkt结构。

static void Frag3Rebuild(FragTracker *ft, Packet *p)
{
    Frag3Frag *frag;    /* frag pointer for managing fragments */
	Packet* dpkt;
    /* walk the fragment list and rebuild the packet
     */
    for(frag = ft->fraglist; frag; frag = frag->next)
    {
        if (frag->size)  {
            ret = SafeMemcpy(rebuild_ptr+frag->offset, frag->data, frag->size,
                             rebuild_ptr, rebuild_end);
            if (ret == SAFEMEM_ERROR)  {
                /*XXX: Log message, failed to copy */
                ft->frag_flags = ft->frag_flags | FRAG_REBUILT;
                return;
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐