Beispiel #1
0
void
capture_packet_time_sorter(vector_t *vector, void *item)
{
    struct timeval curts, prevts;
    int count = vector_count(vector);
    int i;

    // TODO Implement multiframe packets
    curts = packet_time(item);
    prevts = packet_time(vector_last(vector));

    // Check if the item is already sorted
    if (timeval_is_older(curts, prevts)) {
        return;
    }

    for (i = count - 2 ; i >= 0; i--) {
        // Get previous packet
        prevts = packet_time(vector_item(vector, i));
        // Check if the item is already in a sorted position
        if (timeval_is_older(curts, prevts)) {
            vector_insert(vector, item, i + 1);
            return;
        }
    }

    // Put this item at the begining of the vector
    vector_insert(vector, item, 0);
}
Beispiel #2
0
static int ps_tracker_update_udp(PS_PKT *ps_pkt, PS_TRACKER *scanner,
                                 PS_TRACKER *scanned)
{
    Packet  *p;
    snort_ip    cleared;
    IP_CLEAR(cleared);

    p = (Packet *)ps_pkt->pkt;

    if(p->icmph)
    {
        if(scanned)
        {
            ps_proto_update(&scanned->proto,0,1,CLEARED,0,0);
            scanned->priority_node = 1;
        }

        if(scanner)
        {
            ps_proto_update(&scanner->proto,0,1,CLEARED,0,0);
            scanner->priority_node = 1;
        }
    }
    else if(p->udph)
    {
        if (stream_api && (stream_api->version >= STREAM_API_VERSION5) &&
            p->ssnptr)
        {
            uint32_t direction = stream_api->get_packet_direction(p);

            if (direction == PKT_FROM_CLIENT)
            {
                if(scanned)
                {
                    ps_proto_update(&scanned->proto,1,0,
                                     GET_SRC_IP(p),p->dp, packet_time());
                }

                if(scanner)
                {
                    ps_proto_update(&scanner->proto,1,0,
                                     GET_DST_IP(p),p->dp, packet_time());
                }
            }
            else if (direction == PKT_FROM_SERVER)
            {
                if(scanned)
                    ps_proto_update(&scanned->proto,-1,0,CLEARED,0,0);

                if(scanner)
                    ps_proto_update(&scanner->proto,-1,0,CLEARED,0,0);
            }
        }
    }

    return 0;
}
Beispiel #3
0
static int ps_tracker_update_icmp(PS_PKT *ps_pkt, PS_TRACKER *scanner,
                                  PS_TRACKER *scanned)
{
    Packet  *p;
    snort_ip cleared;
    IP_CLEAR(cleared);

    p = (Packet *)ps_pkt->pkt;

    if(p->icmph)
    {
        switch(p->icmph->type)
        {
            case ICMP_ECHO:
            case ICMP_TIMESTAMP:
            case ICMP_ADDRESS:
            case ICMP_INFO_REQUEST:

                if(scanner)
                {
                    ps_proto_update(&scanner->proto,1,0,
                                     GET_DST_IP(p), 0, packet_time());
                }

                break;

            case ICMP_DEST_UNREACH:

                if(scanner)
                {
                    ps_proto_update(&scanner->proto,0,1,CLEARED,0,0);
                    scanner->priority_node = 1;
                }

                break;

            default:
                break;
        }
    }

    return 0;
}
Beispiel #4
0
/**
**  This function is passed into the hash algorithm, so that
**  we only reuse nodes that aren't priority nodes.  We have to make
**  sure that we only track so many priority nodes, otherwise we could
**  have all priority nodes and not be able to allocate more.
*/
static int ps_tracker_free(void *key, void *data)
{
    PS_TRACKER *tracker;

    if(!key || !data)
        return 0;

    tracker = (PS_TRACKER *)data;
    if(!tracker->priority_node)
        return 0;

    /*
    **  Cycle through the protos to see if it's past the time.
    **  We only get here if we ARE a priority node.
    */
    if(tracker->proto.window >= packet_time())
        return 1;

    return 0;
}
Beispiel #5
0
/**
**  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)
{
    Packet  *p;
    uint32_t session_flags;
    snort_ip cleared;
    IP_CLEAR(cleared);

    p = (Packet *)ps_pkt->pkt;

    /*
    **  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) &&
           (portscan_eval_config->include_midstream || !(session_flags & SSNFLAG_MIDSTREAM)))
        {
            if(scanned)
            {
                ps_proto_update(&scanned->proto,1,0,
                                 GET_SRC_IP(p),p->dp, packet_time());
            }

            if(scanner)
            {
                ps_proto_update(&scanner->proto,1,0,
                                 GET_DST_IP(p),p->dp, packet_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,-1,0,CLEARED,0,0);
            }

            if(scanner)
            {
                ps_proto_update(&scanner->proto,-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,0,1,CLEARED,0,0);
                scanned->priority_node = 1;
            }

            if(scanner)
            {
                ps_proto_update(&scanner->proto,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.
        */
        else if((p->packet_flags & PKT_FROM_SERVER) &&
                !(p->packet_flags & PKT_STREAM_EST))
        {
            if(scanned)
            {
                ps_update_open_ports(&scanned->proto, p->sp);
            }

            if(scanner)
            {
                if(scanner->proto.alerts == PS_ALERT_GENERATED)
                    scanner->proto.alerts = PS_ALERT_OPEN_PORT;
            }
        }
    }
    /*
    ** Stream didn't create a session on the SYN packet,
    ** so check specifically for SYN here.
    */
    else if (p->tcph && (p->tcph->th_flags == TH_SYN))
    {
        /* No session established, packet only has SYN.  SYN only
        ** packet always from client, so use dp.
        */
        if(scanned)
        {
            ps_proto_update(&scanned->proto,1,0,
                             GET_SRC_IP(p),p->dp, packet_time());
        }

        if(scanner)
        {
            ps_proto_update(&scanner->proto,1,0,
                             GET_DST_IP(p),p->dp, packet_time());
        }
    }
    /*
    ** Stream didn't create a session on the SYN packet,
    ** so check specifically for SYN & ACK here.  Clear based
    ** on the 'completion' of three-way handshake.
    */
    else if(p->tcph && (p->tcph->th_flags == (TH_SYN|TH_ACK)))
    {
        if(scanned)
        {
            ps_proto_update(&scanned->proto,-1,0,CLEARED,0,0);
        }

        if(scanner)
        {
            ps_proto_update(&scanner->proto,-1,0,CLEARED,0,0);
        }
    }
    /*
    ** No session created, clear based on the RST on non
    ** established session.
    */
    else if (p->tcph && (p->tcph->th_flags & TH_RST))
    {
        if(scanned)
        {
            ps_proto_update(&scanned->proto,0,1,CLEARED,0,0);
            scanned->priority_node = 1;
        }

        if(scanner)
        {
            ps_proto_update(&scanner->proto,0,1,CLEARED,0,0);
            scanner->priority_node = 1;
        }
    }
    /*
    **  If we are an icmp unreachable, deal with it here.
    */
    else if(p->icmph)
    {
        if(scanned)
        {
            ps_proto_update(&scanned->proto,0,1,CLEARED,0,0);
            scanned->priority_node = 1;
        }

        if(scanner)
        {
            ps_proto_update(&scanner->proto,0,1,CLEARED,0,0);
            scanner->priority_node = 1;
        }
    }
    return 0;
}