⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spp_dns.c

📁 入侵检测SNORT.最近更新的基于网络检测的IDS.希望能给大家带来方便.
💻 C
📖 第 1 页 / 共 4 页
字号:
        /* Fall through */    case DNS_RESP_STATE_Q_CLASS_PART:        dnsSessionData->curr_q.dns_class |= (u_int8_t)*data;        data++;        bytes_unused--;        dnsSessionData->curr_rec_state = DNS_RESP_STATE_Q_COMPLETE;        if (bytes_unused == 0)        {            return bytes_unused;        }        /* Fall through */    default:        /* Continue -- we're beyond this question */        break;    }    return bytes_unused;}u_int16_t ParseDNSAnswer(const unsigned char *data,                         u_int16_t data_size,                         u_int16_t bytes_unused,                         DNSSessionData *dnsSessionData){    u_int16_t bytes_used = 0;    u_int16_t new_bytes_unused = 0;    if (bytes_unused == 0)    {        return bytes_unused;    }    if (dnsSessionData->curr_rec_state < DNS_RESP_STATE_RR_NAME_COMPLETE)    {        new_bytes_unused = ParseDNSName(data, bytes_unused, dnsSessionData);        bytes_used = bytes_unused - new_bytes_unused;        if (dnsSessionData->curr_txt.name_state == DNS_RESP_STATE_NAME_COMPLETE)        {            dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_TYPE;            bzero(&dnsSessionData->curr_txt, sizeof(DNSNameState));            data = data + bytes_used;        }        bytes_unused = new_bytes_unused;        if (bytes_unused == 0)        {            /* ran out of data */            return bytes_unused;        }    }        switch (dnsSessionData->curr_rec_state)    {    case DNS_RESP_STATE_RR_TYPE:        dnsSessionData->curr_rr.type = (u_int8_t)*data << 8;        data++;        bytes_unused--;        dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_TYPE_PART;        if (bytes_unused == 0)        {            return bytes_unused;        }        /* Fall through */    case DNS_RESP_STATE_RR_TYPE_PART:        dnsSessionData->curr_rr.type |= (u_int8_t)*data;        data++;        bytes_unused--;        dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_CLASS;        if (bytes_unused == 0)        {            return bytes_unused;        }        /* Fall through */    case DNS_RESP_STATE_RR_CLASS:        dnsSessionData->curr_rr.dns_class = (u_int8_t)*data << 8;        data++;        bytes_unused--;        dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_CLASS_PART;        if (bytes_unused == 0)        {            return bytes_unused;        }        /* Fall through */    case DNS_RESP_STATE_RR_CLASS_PART:        dnsSessionData->curr_rr.dns_class |= (u_int8_t)*data;        data++;        bytes_unused--;        dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_TTL;        if (bytes_unused == 0)        {            return bytes_unused;        }        /* Fall through */    case DNS_RESP_STATE_RR_TTL:        dnsSessionData->curr_rr.ttl = (u_int8_t)*data << 24;        data++;        bytes_unused--;        dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_TTL_PART;        dnsSessionData->bytes_seen_curr_rec = 1;        if (bytes_unused == 0)        {            return bytes_unused;        }        /* Fall through */    case DNS_RESP_STATE_RR_TTL_PART:        while (dnsSessionData->bytes_seen_curr_rec < 4)        {            dnsSessionData->bytes_seen_curr_rec++;            dnsSessionData->curr_rr.ttl |=                 (u_int8_t)*data << (4-dnsSessionData->bytes_seen_curr_rec)*8;            data++;            bytes_unused--;            if (bytes_unused == 0)            {                return bytes_unused;            }        }        dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_RDLENGTH;        if (bytes_unused == 0)        {            return bytes_unused;        }    case DNS_RESP_STATE_RR_RDLENGTH:        dnsSessionData->curr_rr.length = (u_int8_t)*data << 8;        data++;        bytes_unused--;        dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_RDLENGTH_PART;        if (bytes_unused == 0)        {            return bytes_unused;        }        /* Fall through */    case DNS_RESP_STATE_RR_RDLENGTH_PART:        dnsSessionData->curr_rr.length |= (u_int8_t)*data;        data++;        bytes_unused--;        dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_RDATA_START;        if (bytes_unused == 0)        {            return bytes_unused;        }        /* Fall through */    default:        /* Continue -- we're beyond this answer */        break;    }    return bytes_unused;}/* The following check is to look for an attempt to exploit * a vulnerability in the DNS client, per MS 06-041. * * For details, see: * http://www.microsoft.com/technet/security/bulletin/ms06-007.mspx * http://cve.mitre.org/cgi-bin/cvename.cgi?name=2006-3441 * * Vulnerability Research by Lurene Grenier, Judy Novak, * and Brian Caswell. */u_int16_t CheckRRTypeTXTVuln(const unsigned char *data,                       u_int16_t bytes_unused,                       DNSSessionData *dnsSessionData){    u_int16_t bytes_required = dnsSessionData->curr_txt.txt_len - dnsSessionData->curr_txt.txt_bytes_seen;    while (dnsSessionData->curr_txt.name_state != DNS_RESP_STATE_RR_NAME_COMPLETE)    {        if (dnsSessionData->bytes_seen_curr_rec == dnsSessionData->curr_rr.length)        {            /* Done with the name */            dnsSessionData->curr_txt.name_state = DNS_RESP_STATE_RR_NAME_COMPLETE;            /* Got to the end of the rdata in this packet! */            dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_COMPLETE;            return bytes_unused;        }        if (bytes_unused == 0)        {            return bytes_unused;        }        switch (dnsSessionData->curr_txt.name_state)        {        case DNS_RESP_STATE_RR_NAME_SIZE:            dnsSessionData->curr_txt.txt_len = (u_int8_t)*data;            dnsSessionData->curr_txt.txt_count++;            dnsSessionData->curr_txt.total_txt_len += dnsSessionData->curr_txt.txt_len + 1; /* include the NULL */            if (!dnsSessionData->curr_txt.alerted)            {                u_int32_t overflow_check = (dnsSessionData->curr_txt.txt_count * 4) +                                           (dnsSessionData->curr_txt.total_txt_len * 2) + 4;                /* if txt_count * 4 + total_txt_len * 2 + 4 > FFFF, vulnerability! */                if (overflow_check > 0xFFFF)                {                    if (dns_config.enabled_alerts & DNS_ALERT_RDATA_OVERFLOW)                    {                        /* Alert on obsolete DNS RR types */                        DNS_ALERT(DNS_EVENT_RDATA_OVERFLOW, DNS_EVENT_RDATA_OVERFLOW_STR);                    }                    dnsSessionData->curr_txt.alerted = 1;                }            }            data++;            bytes_unused--;            dnsSessionData->bytes_seen_curr_rec++;            if (dnsSessionData->curr_txt.txt_len > 0)            {                dnsSessionData->curr_txt.name_state = DNS_RESP_STATE_RR_NAME;                dnsSessionData->curr_txt.txt_bytes_seen = 0;                bytes_required = dnsSessionData->curr_txt.txt_len;            }            else            {                continue;            }            if (bytes_unused == 0)            {                return bytes_unused;            }            /* Fall through */        case DNS_RESP_STATE_RR_NAME:            if (bytes_required <= bytes_unused)            {                bytes_unused -= bytes_required;                dnsSessionData->bytes_seen_curr_rec += bytes_required;                data += bytes_required;                dnsSessionData->curr_txt.txt_bytes_seen += bytes_required;                if (bytes_unused == 0)                {                    return bytes_unused;                }            }            else            {                dnsSessionData->curr_txt.txt_bytes_seen += bytes_unused;                dnsSessionData->bytes_seen_curr_rec += bytes_unused;                return 0;            }            break;        }                /* Go to the next portion of the name */        dnsSessionData->curr_txt.name_state = DNS_RESP_STATE_RR_NAME_SIZE;    }    return bytes_unused;}u_int16_t SkipDNSRData(const unsigned char *data,                       u_int16_t bytes_unused,                       DNSSessionData *dnsSessionData){    u_int16_t bytes_required = dnsSessionData->curr_rr.length - dnsSessionData->bytes_seen_curr_rec;    if (bytes_required <= bytes_unused)    {        bytes_unused -= bytes_required;        data += bytes_required;        dnsSessionData->bytes_seen_curr_rec += bytes_required;    }    else    {        dnsSessionData->bytes_seen_curr_rec += bytes_unused;        return 0;    }    /* Got to the end of the rdata in this packet! */    dnsSessionData->curr_rec_state = DNS_RESP_STATE_RR_COMPLETE;    return bytes_unused;}u_int16_t ParseDNSRData(SFSnortPacket *p,                        const unsigned char *data,                        u_int16_t bytes_unused,                        DNSSessionData *dnsSessionData){    if (bytes_unused == 0)    {        return bytes_unused;    }    switch (dnsSessionData->curr_rr.type)    {    case DNS_RR_TYPE_TXT:        /* Check for RData Overflow */        bytes_unused = CheckRRTypeTXTVuln(data, bytes_unused, dnsSessionData);        break;    case DNS_RR_TYPE_MD:    case DNS_RR_TYPE_MF:        if (dns_config.enabled_alerts & DNS_ALERT_OBSOLETE_TYPES)        {            /* Alert on obsolete DNS RR types */            DNS_ALERT(DNS_EVENT_OBSOLETE_TYPES, DNS_EVENT_OBSOLETE_TYPES_STR);        }        bytes_unused = SkipDNSRData(data, bytes_unused, dnsSessionData);        break;    case DNS_RR_TYPE_MB:    case DNS_RR_TYPE_MG:    case DNS_RR_TYPE_MR:    case DNS_RR_TYPE_NULL:    case DNS_RR_TYPE_MINFO:        if (dns_config.enabled_alerts & DNS_ALERT_EXPERIMENTAL_TYPES)        {            /* Alert on experimental DNS RR types */            DNS_ALERT(DNS_EVENT_EXPERIMENTAL_TYPES, DNS_EVENT_EXPERIMENTAL_TYPES_STR);        }        bytes_unused = SkipDNSRData(data, bytes_unused, dnsSessionData);        break;    case DNS_RR_TYPE_A:    case DNS_RR_TYPE_NS:    case DNS_RR_TYPE_CNAME:    case DNS_RR_TYPE_SOA:    case DNS_RR_TYPE_WKS:    case DNS_RR_TYPE_PTR:    case DNS_RR_TYPE_HINFO:    case DNS_RR_TYPE_MX:        bytes_unused = SkipDNSRData(data, bytes_unused, dnsSessionData);        break;    default:        /* Not one of the known types.  Stop looking at this session         * as DNS. */        dnsSessionData->flags |= DNS_FLAG_NOT_DNS;        break;    }    return bytes_unused;}void ParseDNSResponseMessage(SFSnortPacket *p, DNSSessionData *dnsSessionData){    u_int16_t bytes_unused = p->payload_size;    int i;    const unsigned char *data = p->payload;    while (bytes_unused)    {        /* Parse through the DNS Header */        if (dnsSessionData->state < DNS_RESP_STATE_QUESTION)        {            /* Length only applies on a TCP packet, skip to header ID             * if at beginning of a UDP Response.             */            if ((dnsSessionData->state == DNS_RESP_STATE_LENGTH) &&                (p->udp_header))            {                dnsSessionData->state = DNS_RESP_STATE_HDR_ID;            }            bytes_unused = ParseDNSHeader(data, bytes_unused, dnsSessionData);            if (bytes_unused > 0)            {                data = p->payload + (p->payload_size - bytes_unused);            }            else            {                /* No more data */                return;            }            dnsSessionData->curr_rec_state = DNS_RESP_STATE_Q_NAME;            dnsSessionData->curr_rec = 0;        }        /* Print out the header (but only once -- when we're ready to parse the Questions */#ifdef DEBUG        if ((dnsSessionData->curr_rec_state == DNS_RESP_STATE_Q_NAME) &&            (dnsSessionData->curr_rec == 0))        {            DebugMessage(DEBUG_DNS,                            "DNS Header: length %d, id 0x%x, flags 0x%x, "                            "questions %d, answers %d, authorities %d, additionals %d\n",                            dnsSessionData->length, dnsSessionData->hdr.id,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -