Пример #1
0
/**
 * \brief Add IPv4 header data, to be stored in the Additional Data
 * field of the IDMEF alert (see section 4.2.4.6 of RFC 4765).
 *
 * \return 0 if ok
 */
static int PacketToDataV4(Packet *p, PacketAlert *pa, idmef_alert_t *alert)
{
    SCEnter();

    AddIntData(alert, "ip_ver", IPV4_GET_RAW_VER(p->ip4h));
    AddIntData(alert, "ip_hlen", IPV4_GET_RAW_HLEN(p->ip4h));
    AddIntData(alert, "ip_tos", IPV4_GET_RAW_IPTOS(p->ip4h));
    AddIntData(alert, "ip_len", ntohs(IPV4_GET_RAW_IPLEN(p->ip4h)));

    AddIntData(alert, "ip_id", ntohs(IPV4_GET_RAW_IPID(p->ip4h)));

    AddIntData(alert, "ip_off", ntohs(IPV4_GET_RAW_IPOFFSET(p->ip4h)));

    AddIntData(alert, "ip_ttl", IPV4_GET_RAW_IPTTL(p->ip4h));
    AddIntData(alert, "ip_proto", IPV4_GET_RAW_IPPROTO(p->ip4h));

    AddIntData(alert, "ip_sum", ntohs(p->ip4h->ip_csum));

    SCReturnInt(0);
}
Пример #2
0
int Unified2IPv4TypeAlert (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq)
{
    Unified2AlertThread *aun = (Unified2AlertThread *)data;
    Unified2AlertFileHeader hdr;
    AlertIPv4Unified2 *phdr = (AlertIPv4Unified2 *)(aun->data +
                                sizeof(Unified2AlertFileHeader));
    AlertIPv4Unified2 gphdr;
    PacketAlert *pa;
    int offset, length;
    int ret;
    unsigned int event_id;

    if (p->alerts.cnt == 0)
        return 0;

    length = (sizeof(Unified2AlertFileHeader) + sizeof(AlertIPv4Unified2));
    offset = length;

    memset(aun->data, 0, aun->datalen);

    hdr.type = htonl(UNIFIED2_IDS_EVENT_TYPE);
    hdr.length = htonl(sizeof(AlertIPv4Unified2));

    /* fill the gphdr structure with the data of the packet */
    memset(&gphdr, 0, sizeof(gphdr));
    gphdr.sensor_id = htonl(sensor_id);
    gphdr.event_id = 0;
    gphdr.event_second =  htonl(p->ts.tv_sec);
    gphdr.event_microsecond = htonl(p->ts.tv_usec);
    gphdr.src_ip = p->ip4h->s_ip_src.s_addr;
    gphdr.dst_ip = p->ip4h->s_ip_dst.s_addr;
    gphdr.protocol = IPV4_GET_RAW_IPPROTO(p->ip4h);

    if(p->action & ACTION_DROP)
        gphdr.packet_action = UNIFIED2_BLOCKED_FLAG;
    else
        gphdr.packet_action = 0;

    /* TODO inverse order if needed, this should be done on a
     * alert basis */
    switch(gphdr.protocol)  {
        case IPPROTO_ICMP:
            if(p->icmpv4h)  {
                gphdr.sp = htons(p->icmpv4h->type);
                gphdr.dp = htons(p->icmpv4h->code);
            }
            break;
        case IPPROTO_UDP:
        case IPPROTO_TCP:
        case IPPROTO_SCTP:
            gphdr.sp = htons(p->sp);
            gphdr.dp = htons(p->dp);
            break;
        default:
            gphdr.sp = 0;
            gphdr.dp = 0;
            break;
    }

    uint16_t i = 0;
    for (; i < p->alerts.cnt + 1; i++) {
        if (i < p->alerts.cnt)
            pa = &p->alerts.alerts[i];
        else {
            if (!(p->flags & PKT_HAS_TAG))
                break;
            pa = PacketAlertGetTag();
        }

        if (unlikely(pa->s == NULL))
            continue;

        /* reset length and offset */
        aun->offset = offset;
        aun->length = length;
        memset(aun->data + aun->offset, 0, aun->datalen - aun->offset);

        /* copy the part common to all alerts */
        memcpy(aun->data, &hdr, sizeof(hdr));
        memcpy(phdr, &gphdr, sizeof(gphdr));

        /* fill the hdr structure with the alert data */
        event_id = htonl(SC_ATOMIC_ADD(unified2_event_id, 1));
        phdr->event_id = event_id;
        phdr->generator_id = htonl(pa->s->gid);
        phdr->signature_id = htonl(pa->s->id);
        phdr->signature_revision = htonl(pa->s->rev);
        phdr->classification_id = htonl(pa->s->class);
        phdr->priority_id = htonl(pa->s->prio);

        /* check and enforce the filesize limit */
        SCMutexLock(&aun->file_ctx->fp_mutex);

        if ((aun->file_ctx->size_current + length) > aun->file_ctx->size_limit) {
            if (Unified2AlertRotateFile(tv,aun) < 0) {
                aun->file_ctx->alerts += i;
                SCMutexUnlock(&aun->file_ctx->fp_mutex);
                return -1;
            }
        }

        if (Unified2Write(aun) != 1) {
            aun->file_ctx->alerts += i;
            SCMutexUnlock(&aun->file_ctx->fp_mutex);
            return -1;
        }

        memset(aun->data, 0, aun->length);
        aun->length = 0;
        aun->offset = 0;

        /* Write the alert (it doesn't lock inside, since we
         * already locked here for rotation check)
         */
        int stream = (gphdr.protocol == IPPROTO_TCP) ?
            (pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_STREAM_MATCH) ? 1 : 0) : 0;
        ret = Unified2PacketTypeAlert(aun, p, event_id, stream);
        if (ret != 1) {
            aun->file_ctx->alerts += i;
            SCMutexUnlock(&aun->file_ctx->fp_mutex);
            return -1;
        }

        fflush(aun->file_ctx->fp);
        aun->file_ctx->alerts++;
        SCMutexUnlock(&aun->file_ctx->fp_mutex);
    }

    return 0;
}
Пример #3
0
/**
 * Note, this is the IP header, plus a bit of the original packet, not the whole thing!
 */
int DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len )
{
    /** Check the sizes, the header must fit at least */
    if (len < IPV4_HEADER_LEN) {
        SCLogDebug("DecodePartialIPV4: ICMPV4_IPV4_TRUNC_PKT");
        ENGINE_SET_INVALID_EVENT(p, ICMPV4_IPV4_TRUNC_PKT);
        return -1;
    }

    IPV4Hdr *icmp4_ip4h = (IPV4Hdr*)partial_packet;

    /** Check the embedded version */
    if (IPV4_GET_RAW_VER(icmp4_ip4h) != 4) {
        /** Check the embedded version */
        SCLogDebug("DecodePartialIPV4: ICMPv4 contains Unknown IPV4 version "
                   "ICMPV4_IPV4_UNKNOWN_VER");
        ENGINE_SET_INVALID_EVENT(p, ICMPV4_IPV4_UNKNOWN_VER);
        return -1;
    }

    /** We need to fill icmpv4vars */
    p->icmpv4vars.emb_ipv4h = icmp4_ip4h;

    /** Get the IP address from the contained packet */
    p->icmpv4vars.emb_ip4_src = IPV4_GET_RAW_IPSRC(icmp4_ip4h);
    p->icmpv4vars.emb_ip4_dst = IPV4_GET_RAW_IPDST(icmp4_ip4h);

    p->icmpv4vars.emb_ip4_hlen=IPV4_GET_RAW_HLEN(icmp4_ip4h) << 2;

    switch (IPV4_GET_RAW_IPPROTO(icmp4_ip4h)) {
        case IPPROTO_TCP:
            if (len >= IPV4_HEADER_LEN + TCP_HEADER_LEN ) {
                p->icmpv4vars.emb_tcph = (TCPHdr*)(partial_packet + IPV4_HEADER_LEN);
                p->icmpv4vars.emb_sport = ntohs(p->icmpv4vars.emb_tcph->th_sport);
                p->icmpv4vars.emb_dport = ntohs(p->icmpv4vars.emb_tcph->th_dport);
                p->icmpv4vars.emb_ip4_proto = IPPROTO_TCP;

                SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->TCP header sport: "
                           "%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport,
                            p->icmpv4vars.emb_dport);
            } else if (len >= IPV4_HEADER_LEN + 4) {
                /* only access th_sport and th_dport */
                TCPHdr *emb_tcph = (TCPHdr*)(partial_packet + IPV4_HEADER_LEN);

                p->icmpv4vars.emb_tcph = NULL;
                p->icmpv4vars.emb_sport = ntohs(emb_tcph->th_sport);
                p->icmpv4vars.emb_dport = ntohs(emb_tcph->th_dport);
                p->icmpv4vars.emb_ip4_proto = IPPROTO_TCP;
                SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->TCP partial header sport: "
                           "%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport,
                            p->icmpv4vars.emb_dport);
            } else {
                SCLogDebug("DecodePartialIPV4: Warning, ICMPV4->IPV4->TCP "
                           "header Didn't fit in the packet!");
                p->icmpv4vars.emb_sport = 0;
                p->icmpv4vars.emb_dport = 0;
            }

            break;
        case IPPROTO_UDP:
            if (len >= IPV4_HEADER_LEN + UDP_HEADER_LEN ) {
                p->icmpv4vars.emb_udph = (UDPHdr*)(partial_packet + IPV4_HEADER_LEN);
                p->icmpv4vars.emb_sport = ntohs(p->icmpv4vars.emb_udph->uh_sport);
                p->icmpv4vars.emb_dport = ntohs(p->icmpv4vars.emb_udph->uh_dport);
                p->icmpv4vars.emb_ip4_proto = IPPROTO_UDP;

                SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->UDP header sport: "
                           "%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport,
                            p->icmpv4vars.emb_dport);
            } else {
                SCLogDebug("DecodePartialIPV4: Warning, ICMPV4->IPV4->UDP "
                           "header Didn't fit in the packet!");
                p->icmpv4vars.emb_sport = 0;
                p->icmpv4vars.emb_dport = 0;
            }

            break;
        case IPPROTO_ICMP:
            if (len >= IPV4_HEADER_LEN + ICMPV4_HEADER_LEN ) {
                p->icmpv4vars.emb_icmpv4h = (ICMPV4Hdr*)(partial_packet + IPV4_HEADER_LEN);
                p->icmpv4vars.emb_sport = 0;
                p->icmpv4vars.emb_dport = 0;
                p->icmpv4vars.emb_ip4_proto = IPPROTO_ICMP;

                SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->ICMP header");
            }

            break;
    }

    /* debug print */
#ifdef DEBUG
    char s[16], d[16];
    PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_src), s, sizeof(s));
    PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_dst), d, sizeof(d));
    SCLogDebug("ICMPv4 embedding IPV4 %s->%s - PROTO: %" PRIu32 " ID: %" PRIu32 "", s,d,
            IPV4_GET_RAW_IPPROTO(icmp4_ip4h), IPV4_GET_RAW_IPID(icmp4_ip4h));
#endif

    return 0;
}
Пример #4
0
TmEcode AlertUnifiedAlert (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
{
    AlertUnifiedAlertThread *aun = (AlertUnifiedAlertThread *)data;
    AlertUnifiedAlertPacketHeader hdr;

    int ret;
    uint8_t ethh_offset = 0;

    /* the unified1 format only supports IPv4. */
    if (p->alerts.cnt == 0 || !PKT_IS_IPV4(p))
        return TM_ECODE_OK;

    /* if we have no ethernet header (e.g. when using nfq), we have to create
     * one ourselves. */
    if (p->ethh == NULL) {
        ethh_offset = sizeof(EthernetHdr);
    }

    /* fill the hdr structure with the data of the packet */
    hdr.pad1 = 0;
    hdr.pad2 = 0;
    hdr.ts.tv_sec = hdr.ref_ts.tv_sec = p->ts.tv_sec;
    hdr.ts.tv_usec = hdr.ref_ts.tv_usec = p->ts.tv_sec;
    hdr.src_ip = ntohl(GET_IPV4_SRC_ADDR_U32(p)); /* addr is host order */
    hdr.dst_ip = ntohl(GET_IPV4_DST_ADDR_U32(p)); /* addr is host order */
    hdr.sp = p->sp;
    hdr.dp = p->dp;
    hdr.protocol = IPV4_GET_RAW_IPPROTO(p->ip4h);
    hdr.flags = 0;

    uint16_t i = 0;
    for (; i < p->alerts.cnt; i++) {
        PacketAlert *pa = &p->alerts.alerts[i];

        /* fill the rest of the hdr structure with the data of the alert */
        hdr.sig_gen = pa->gid;
        hdr.sig_sid = pa->sid;
        hdr.sig_rev = pa->rev;
        hdr.sig_class = pa->class;
        hdr.sig_prio = pa->prio;

        SCMutexLock(&aun->file_ctx->fp_mutex);
        /** check and enforce the filesize limit, thread safe */
        if ((aun->file_ctx->size_current + sizeof(hdr)) > aun->file_ctx->size_limit) {
            if (AlertUnifiedAlertRotateFile(tv,aun) < 0) {
                SCMutexUnlock(&aun->file_ctx->fp_mutex);
                aun->file_ctx->alerts += i;
                return TM_ECODE_FAILED;
            }
        }
        /* Then the unified header */
        ret = fwrite(&hdr, sizeof(AlertUnifiedAlertPacketHeader), 1, aun->file_ctx->fp);
        if (ret != 1) {
            SCLogError(SC_ERR_FWRITE, "Error: fwrite failed: %s", strerror(errno));
            SCMutexUnlock(&aun->file_ctx->fp_mutex);
            aun->file_ctx->alerts += i;
            return TM_ECODE_FAILED;
        }
        /* force writing to disk so barnyard will not read half
         * written records and choke. */
        fflush(aun->file_ctx->fp);

        aun->file_ctx->size_current += sizeof(hdr);
        aun->file_ctx->alerts++;
        SCMutexUnlock(&aun->file_ctx->fp_mutex);
    }

    return TM_ECODE_OK;
}
Пример #5
0
/**
 * \brief Add Source and Target fields to the IDMEF alert.
 * These objects contains IP addresses, source and destination
 * ports (see sections 4.2.4.3 and 4.2.4.4 of RFC 4765).
 *
 * \return 0 if ok
 */
static int EventToSourceTarget(Packet *p, idmef_alert_t *alert)
{
    int ret;
    idmef_node_t *node;
    idmef_source_t *source;
    idmef_target_t *target;
    idmef_address_t *address;
    idmef_service_t *service;
    prelude_string_t *string;
    static char saddr[128], daddr[128];
    uint8_t ip_vers;
    uint8_t ip_proto;

    SCEnter();

    if ( !p )
        SCReturnInt(0);

    if ( ! IPH_IS_VALID(p) )
        SCReturnInt(0);

    if (PKT_IS_IPV4(p)) {
        ip_vers = 4;
        ip_proto = IPV4_GET_RAW_IPPROTO(p->ip4h);
        PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), saddr, sizeof(saddr));
        PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), daddr, sizeof(daddr));
    } else if (PKT_IS_IPV6(p)) {
        ip_vers = 6;
        ip_proto = IPV6_GET_L4PROTO(p);
        PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), saddr, sizeof(saddr));
        PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), daddr, sizeof(daddr));
    } else
        SCReturnInt(0);

    ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND);
    if ( ret < 0 )
        SCReturnInt(ret);

    ret = idmef_source_new_service(source, &service);
    if ( ret < 0 )
        SCReturnInt(ret);

    if ( p->tcph || p->udph )
        idmef_service_set_port(service, p->sp);

    idmef_service_set_ip_version(service, ip_vers);
    idmef_service_set_iana_protocol_number(service, ip_proto);

    ret = idmef_source_new_node(source, &node);
    if ( ret < 0 )
        SCReturnInt(ret);

    ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND);
    if ( ret < 0 )
        SCReturnInt(ret);

    ret = idmef_address_new_address(address, &string);
    if ( ret < 0 )
        SCReturnInt(ret);

    prelude_string_set_ref(string, saddr);

    ret = idmef_alert_new_target(alert, &target, IDMEF_LIST_APPEND);
    if ( ret < 0 )
        SCReturnInt(ret);

    ret = idmef_target_new_service(target, &service);
    if ( ret < 0 )
        SCReturnInt(ret);

    if ( p->tcph || p->udph )
        idmef_service_set_port(service, p->dp);

    idmef_service_set_ip_version(service, ip_vers);
    idmef_service_set_iana_protocol_number(service, ip_proto);

    ret = idmef_target_new_node(target, &node);
    if ( ret < 0 )
        SCReturnInt(ret);

    ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND);
    if ( ret < 0 )
        SCReturnInt(ret);

    ret = idmef_address_new_address(address, &string);
    if ( ret < 0 )
        SCReturnInt(ret);

    prelude_string_set_ref(string, daddr);

    SCReturnInt(0);
}