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

📄 portscan.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
            return 0;        if(ipset_contains(g_ps_init.watch_ip, &scanned, &(p->dp), IPV4_FAMILY))            return 0;#endif        return 1;    }    return 0;}/***  NAME**    ps_tracker_init::*//****  Right now all we do is memset, but just in case we want to do more**  initialization has been extracted.*/static int ps_tracker_init(PS_TRACKER *tracker){    memset(tracker, 0x00, g_ps_tracker_size);    return 0;}/***  NAME**    ps_tracker_get::*//****  Get a tracker node by either finding one or starting a new one.  We may**  return NULL, in which case we wait till the next packet.*/static int ps_tracker_get(PS_TRACKER **ht, PS_HASH_KEY *key){    int iRet;    *ht = (PS_TRACKER *)sfxhash_find(g_hash, (void *)key);    if(!(*ht))    {        iRet = sfxhash_add(g_hash, (void *)key, NULL);        if(iRet == SFXHASH_OK)        {            *ht = (PS_TRACKER *)sfxhash_mru(g_hash);            if(!(*ht))                return -1;            ps_tracker_init(*ht);        }        else        {            return -1;        }    }    return 0;}static int ps_tracker_lookup(PS_PKT *ps_pkt, PS_TRACKER **scanner,                             PS_TRACKER **scanned){    PS_HASH_KEY key;    Packet     *p;    if(!ps_pkt->pkt)        return -1;    p = (Packet *)ps_pkt->pkt;    /*    **  Let's lookup the host that is being scanned, taking into account    **  the pkt may be reversed.    */    if(g_ps_init.detect_scan_type &             (PS_TYPE_PORTSCAN | PS_TYPE_DECOYSCAN | PS_TYPE_DISTPORTSCAN))    {        IP_CLEAR(key.scanner);                if(ps_pkt->reverse_pkt)            IP_COPY_VALUE(key.scanned, GET_SRC_IP(p));        else            IP_COPY_VALUE(key.scanned, GET_DST_IP(p));        /*        **  Get the scanned tracker.        */        if(ps_tracker_get(scanned, &key))            return -1;    }    /*    **  Let's lookup the host that is scanning.    */    if(g_ps_init.detect_scan_type & PS_TYPE_PORTSWEEP)    {        IP_CLEAR(key.scanned);                if(ps_pkt->reverse_pkt)            IP_COPY_VALUE(key.scanner, GET_DST_IP(p));        else            IP_COPY_VALUE(key.scanner, GET_SRC_IP(p));        /*        **  Get the scanner tracker        */        if(ps_tracker_get(scanner, &key))            return -1;    }    return 0;}/***  NAME**    ps_get_proto_index::*//****  This logic finds the index to the proto array based on the**  portscan configuration.  We need special logic because the **  index of the protocol changes based on the configuration.*/static int ps_get_proto_index(PS_PKT *ps_pkt, int *proto_index, int *proto){    Packet *p;    int     found = 0;    if(!ps_pkt || !ps_pkt->pkt || !proto_index || !proto)        return -1;    p = (Packet *)ps_pkt->pkt;    *proto_index = 0;    *proto = 0;    if(!found && g_ps_init.detect_scans & PS_PROTO_TCP)    {        if(p->tcph)         {            found = 1;            *proto = PS_PROTO_TCP;        }        else if(p->icmph && p->icmph->type == ICMP_DEST_UNREACH &&                p->icmph->code == ICMP_PORT_UNREACH && p->orig_tcph)        {            found = 1;            *proto = PS_PROTO_TCP;        }        else         {            (*proto_index)++;        }    }    if(!found && g_ps_init.detect_scans & PS_PROTO_UDP)    {        if(p->udph)        {             found = 1;            *proto = PS_PROTO_UDP;        }        else if(p->icmph && p->icmph->type == ICMP_DEST_UNREACH &&                p->icmph->code == ICMP_PORT_UNREACH && p->orig_udph)        {            found = 1;            *proto = PS_PROTO_UDP;        }        else         {            (*proto_index)++;        }    }    if(!found && g_ps_init.detect_scans & PS_PROTO_IP)    {        if(IPH_IS_VALID(p) && !p->icmph)        {            found = 1;            *proto = PS_PROTO_IP;        }        else if(p->icmph && p->icmph->type == ICMP_DEST_UNREACH &&                p->icmph->code == ICMP_PROT_UNREACH)        {            found = 1;            *proto = PS_PROTO_IP;        }        else        {            (*proto_index)++;        }    }    if(!found && g_ps_init.detect_scans & PS_PROTO_ICMP)    {        if(p->icmph)         {            found = 1;            *proto = PS_PROTO_ICMP;        }        else         {            (*proto_index)++;        }    }    if(!found)    {        *proto = 0;        *proto_index = 0;        return -1;    }    return 0;}/***  NAME**    ps_proto_update_window::*//****  Update the proto time windows based on the portscan sensitivity**  level.*/static int ps_proto_update_window(PS_PROTO *proto, time_t pkt_time){    time_t interval;    switch(g_ps_init.sense_level)    {        case PS_SENSE_LOW:            //interval = 15;            interval = 60;            break;        case PS_SENSE_MEDIUM:            //interval = 15;            interval = 90;            break;        case PS_SENSE_HIGH:            interval = 600;            break;        default:            return -1;    }    /*    **  If we are outside of the window, reset our ps counters.    */    if(pkt_time > proto->window)    {        memset(proto, 0x00, sizeof(PS_PROTO));        proto->window = pkt_time + interval;        return 0;    }    return 0;}/***  NAME**    ps_proto_update::*//****  This function updates the PS_PROTO structure.****  @param PS_PROTO pointer to structure to update**  @param int      number to increment portscan counter**  @param u_long   IP address of other host**  @param u_short  port/ip_proto to track**  @param time_t   time the packet was received. update windows.*/static int ps_proto_update(PS_PROTO *proto, int ps_cnt, int pri_cnt, ip_p ip,        u_short port, time_t pkt_time){    if(!proto)        return 0;    /*    **  If the ps_cnt is negative, that means we are just taking off    **  for valid connection, and we don't want to do anything else,    **  like update ip/port, etc.    */    if(ps_cnt < 0)    {        proto->connection_count += ps_cnt;        if(proto->connection_count < 0)            proto->connection_count = 0;        return 0;    }    /*    **  If we are updating a priority cnt, it means we already did the    **  unique port and IP on the connection packet.    **    **  Priority points are only added for invalid response packets.    */    if(pri_cnt)    {        proto->priority_count += pri_cnt;        if(proto->priority_count < 0)            proto->priority_count = 0;        return 0;    }    /*    **  Do time check first before we update the counters, so if    **  we need to reset them we do it before we update them.    */    if(ps_proto_update_window(proto, pkt_time))        return -1;    /*    **  Update ps counter    */    proto->connection_count += ps_cnt;    if(proto->connection_count < 0)        proto->connection_count = 0;#ifdef SUP_IP6    if(!IP_EQUALITY(&proto->u_ips, ip))#else    if(!IP_EQUALITY(proto->u_ips, ip))#endif    {        proto->u_ip_count++;        IP_COPY_VALUE(proto->u_ips, ip);    }    /* we need to do the IP comparisons in host order */#ifndef SUP_IP6    ip = ntohl(ip);#endif#ifdef SUP_IP6    if(sfip_is_set(&proto->low_ip))    {        if(IP_GREATER(&proto->low_ip, ip))            IP_COPY_VALUE(proto->low_ip, ip);    }#else    if(IS_SET(proto->low_ip))    {        if(IP_GREATER(proto->low_ip, ip))            IP_COPY_VALUE(proto->low_ip, ip);    }#endif    else    {        IP_COPY_VALUE(proto->low_ip, ip);    }    if(IS_SET(proto->high_ip))    {#ifdef SUP_IP6        if(IP_LESSER(&proto->high_ip, ip))#else        if(IP_LESSER(proto->high_ip, ip))#endif            IP_COPY_VALUE(proto->high_ip, ip);    }    else    {        IP_COPY_VALUE(proto->high_ip, ip);    }    if(proto->u_ports != port)    {        proto->u_port_count++;        proto->u_ports = port;    }        if(proto->low_p)    {        if(proto->low_p > port)            proto->low_p = port;    }    else    {        proto->low_p = port;    }    if(proto->high_p)    {        if(proto->high_p < port)            proto->high_p = port;    }    else    {        proto->high_p = port;    }    return 0;}static int ps_update_open_ports(PS_PROTO *proto, unsigned short port){    int iCtr;        for(iCtr = 0; iCtr < proto->open_ports_cnt; iCtr++)    {        if(port == proto->open_ports[iCtr])            return 0;    }        if(iCtr < (PS_OPEN_PORTS - 1))    {        proto->open_ports[iCtr] = port;        proto->open_ports_cnt++;        if(proto->alerts == PS_ALERT_GENERATED)        {            proto->alerts = PS_ALERT_OPEN_PORT;        }    }    return 0;}    /***  NAME**    ps_tracker_update_tcp::*//****  Determine how to update the portscan counter depending on the type**  of TCP packet we have.****  We are concerned with three types of TCP packets:**  **    - initiating TCP packets (we don't care about flags)**    - TCP 3-way handshake packets (we decrement the counter)**    - TCP reset packets on unestablished streams.*/static int ps_tracker_update_tcp(PS_PKT *ps_pkt, PS_TRACKER *scanner,        PS_TRACKER *scanned, int proto_idx){    Packet  *p;    time_t  pkt_time;    FLOW    *flow;    u_int32_t session_flags;    ip_t cleared;    IP_CLEAR(cleared);        p = (Packet *)ps_pkt->pkt;    pkt_time = packet_timeofday();    flow = (FLOW *)p->flow;    /*    **  Handle the initiating packet.    **    **  If this what stream4 considers to be a valid initiator, then    **  we will use the available stream4 information.  Otherwise, we    **  can just revert to flow and look for initiators and responders.    **    **  For Stream5, depending on the configuration, there might not    **  be a session created only based on the SYN packet.  Stream5    **  by default has code that helps deal with SYN flood attacks,    **  and may simply ignore the SYN.  In this case, we fall through    **  to the checks for specific TCP header files (SYN, SYN-ACK, RST).    **    **  The "midstream" logic below says that, if we include sessions    **  picked up midstream, then we don't care about the MIDSTREAM flag.    **  Otherwise, only consider streams not picked up midstream.    */    if(p->ssnptr && stream_api)    {        session_flags = stream_api->get_session_flags(p->ssnptr);        if((session_flags & SSNFLAG_SEEN_CLIENT) &&            !(session_flags & SSNFLAG_SEEN_SERVER) &&           (g_include_midstream || !(session_flags & SSNFLAG_MIDSTREAM)))        {            if(scanned)            {                ps_proto_update(&scanned->proto[proto_idx],1,0,                                 GET_SRC_IP(p),p->dp, pkt_time);            }            if(scanner)            {                ps_proto_update(&scanner->proto[proto_idx],1,0,                                 GET_DST_IP(p),p->dp, pkt_time);            }        }        /*        **  Handle the final packet of the three-way handshake.        */        else if(p->packet_flags & PKT_STREAM_TWH)        {            if(scanned)            {                ps_proto_update(&scanned->proto[proto_idx],-1,0,CLEARED,0,0);            }            if(scanner)            {                ps_proto_update(&scanner->proto[proto_idx],-1,0,CLEARED,0,0);            }        }        /*        **  RST packet on unestablished streams        */        else if((p->packet_flags & PKT_FROM_SERVER) &&                (p->tcph && (p->tcph->th_flags & TH_RST)) &&                (!(p->packet_flags & PKT_STREAM_EST) ||                (session_flags & SSNFLAG_MIDSTREAM)))        {            if(scanned)            {                ps_proto_update(&scanned->proto[proto_idx],0,1,CLEARED,0,0);                scanned->priority_node = 1;            }            if(scanner)            {                ps_proto_update(&scanner->proto[proto_idx],0,1,CLEARED,0,0);                scanner->priority_node = 1;            }        }        /*        **  We only get here on the server's response to the intial        **  client connection.        **        **  That's why we use the sp, because that's the port that is        **  open.

⌨️ 快捷键说明

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