예제 #1
0
/**
 * \brief This function is used to match icode rule option set on a packet with those passed via icode:
 *
 * \param t pointer to thread vars
 * \param det_ctx pointer to the pattern matcher thread
 * \param p pointer to the current packet
 * \param m pointer to the sigmatch that we will cast into DetectICodeData
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectICodeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m) {
    int ret = 0;
    uint8_t picode;
    DetectICodeData *icd = (DetectICodeData *)m->ctx;

    if (PKT_IS_PSEUDOPKT(p))
        return 0;

    if (PKT_IS_ICMPV4(p)) {
        picode = ICMPV4_GET_CODE(p);
    } else if (PKT_IS_ICMPV6(p)) {
        picode = ICMPV6_GET_CODE(p);
    } else {
        /* Packet not ICMPv4 nor ICMPv6 */
        return ret;
    }

    switch(icd->mode) {
        case DETECT_ICODE_EQ:
            ret = (picode == icd->code1) ? 1 : 0;
            break;
        case DETECT_ICODE_LT:
            ret = (picode < icd->code1) ? 1 : 0;
            break;
        case DETECT_ICODE_GT:
            ret = (picode > icd->code1) ? 1 : 0;
            break;
        case DETECT_ICODE_RN:
            ret = (picode >= icd->code1 && picode <= icd->code2) ? 1 : 0;
            break;
    }

    return ret;
}
예제 #2
0
/**
 *  \brief Check if we should create a flow based on a packet
 *
 *  We use this check to filter out flow creation based on:
 *  - ICMP error messages
 *
 *  \param p packet
 *  \retval 1 true
 *  \retval 0 false
 */
static inline int FlowCreateCheck(const Packet *p)
{
    if (PKT_IS_ICMPV4(p)) {
        if (ICMPV4_IS_ERROR_MSG(p)) {
            return 0;
        }
    }

    return 1;
}
예제 #3
0
/**
 * \brief This function is used to match icmp_id rule option set on a packet
 *
 * \param t pointer to thread vars
 * \param det_ctx pointer to the pattern matcher thread
 * \param p pointer to the current packet
 * \param m pointer to the sigmatch that we will cast into DetectIcmpIdData
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectIcmpIdMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m)
{
    uint16_t pid;
    DetectIcmpIdData *iid = (DetectIcmpIdData *)m->ctx;

    if (PKT_IS_PSEUDOPKT(p))
        return 0;

    if (PKT_IS_ICMPV4(p)) {
        switch (ICMPV4_GET_TYPE(p)){
            case ICMP_ECHOREPLY:
            case ICMP_ECHO:
            case ICMP_TIMESTAMP:
            case ICMP_TIMESTAMPREPLY:
            case ICMP_INFO_REQUEST:
            case ICMP_INFO_REPLY:
            case ICMP_ADDRESS:
            case ICMP_ADDRESSREPLY:
                SCLogDebug("ICMPV4_GET_ID(p) %"PRIu16" (network byte order), "
                        "%"PRIu16" (host byte order)", ICMPV4_GET_ID(p),
                        ntohs(ICMPV4_GET_ID(p)));

                pid = ICMPV4_GET_ID(p);
                break;
            default:
                SCLogDebug("Packet has no id field");
                return 0;
        }
    } else if (PKT_IS_ICMPV6(p)) {
        switch (ICMPV6_GET_TYPE(p)) {
            case ICMP6_ECHO_REQUEST:
            case ICMP6_ECHO_REPLY:
                SCLogDebug("ICMPV6_GET_ID(p) %"PRIu16" (network byte order), "
                        "%"PRIu16" (host byte order)", ICMPV6_GET_ID(p),
                        ntohs(ICMPV6_GET_ID(p)));

                pid = ICMPV6_GET_ID(p);
                break;
            default:
                SCLogDebug("Packet has no id field");
                return 0;
        }
    } else {
        SCLogDebug("Packet not ICMPV4 nor ICMPV6");
        return 0;
    }

    if (pid == iid->id)
        return 1;

    return 0;
}
예제 #4
0
/**
 * \brief Convert IP packet to an IDMEF alert (RFC 4765).
 * This function stores the alert SID (description and reference),
 * the payload of the packet, and pre-processed data.
 *
 * \return 0 if ok
 */
static int PacketToData(Packet *p, PacketAlert *pa, idmef_alert_t *alert, AlertPreludeCtx *ctx)
{
    SCEnter();

    if ( ! p )
        SCReturnInt(0);

    AddIntData(alert, "snort_rule_sid", pa->s->id);
    AddIntData(alert, "snort_rule_rev", pa->s->rev);

    if (ctx->log_packet_header) {
        if ( PKT_IS_IPV4(p) )
            PacketToDataV4(p, pa, alert);

        else if ( PKT_IS_IPV6(p) )
            PacketToDataV6(p, pa, alert);

        if ( PKT_IS_TCP(p) ) {
            AddIntData(alert, "tcp_seq", ntohl(p->tcph->th_seq));
            AddIntData(alert, "tcp_ack", ntohl(p->tcph->th_ack));

            AddIntData(alert, "tcp_off", TCP_GET_RAW_OFFSET(p->tcph));
            AddIntData(alert, "tcp_res", TCP_GET_RAW_X2(p->tcph));
            AddIntData(alert, "tcp_flags", p->tcph->th_flags);

            AddIntData(alert, "tcp_win", ntohs(p->tcph->th_win));
            AddIntData(alert, "tcp_sum", ntohs(p->tcph->th_sum));
            AddIntData(alert, "tcp_urp", ntohs(p->tcph->th_urp));

        }

        else if ( PKT_IS_UDP(p) ) {
            AddIntData(alert, "udp_len", ntohs(p->udph->uh_len));
            AddIntData(alert, "udp_sum", ntohs(p->udph->uh_sum));
        }

        else if ( PKT_IS_ICMPV4(p) ) {
            AddIntData(alert, "icmp_type", p->icmpv4h->type);
            AddIntData(alert, "icmp_code", p->icmpv4h->code);
            AddIntData(alert, "icmp_sum", ntohs(p->icmpv4h->checksum));

        }
    }

    if (ctx->log_packet_content)
        AddByteData(alert, "payload", p->payload, p->payload_len);

    SCReturnInt(0);
}
예제 #5
0
static inline _Bool GetIcmpId(Packet *p, uint16_t *id)
{
    if (PKT_IS_PSEUDOPKT(p))
        return FALSE;

    uint16_t pid;
    if (PKT_IS_ICMPV4(p)) {
        switch (ICMPV4_GET_TYPE(p)){
            case ICMP_ECHOREPLY:
            case ICMP_ECHO:
            case ICMP_TIMESTAMP:
            case ICMP_TIMESTAMPREPLY:
            case ICMP_INFO_REQUEST:
            case ICMP_INFO_REPLY:
            case ICMP_ADDRESS:
            case ICMP_ADDRESSREPLY:
                SCLogDebug("ICMPV4_GET_ID(p) %"PRIu16" (network byte order), "
                        "%"PRIu16" (host byte order)", ICMPV4_GET_ID(p),
                        ntohs(ICMPV4_GET_ID(p)));

                pid = ICMPV4_GET_ID(p);
                break;
            default:
                SCLogDebug("Packet has no id field");
                return FALSE;
        }
    } else if (PKT_IS_ICMPV6(p)) {
        switch (ICMPV6_GET_TYPE(p)) {
            case ICMP6_ECHO_REQUEST:
            case ICMP6_ECHO_REPLY:
                SCLogDebug("ICMPV6_GET_ID(p) %"PRIu16" (network byte order), "
                        "%"PRIu16" (host byte order)", ICMPV6_GET_ID(p),
                        ntohs(ICMPV6_GET_ID(p)));

                pid = ICMPV6_GET_ID(p);
                break;
            default:
                SCLogDebug("Packet has no id field");
                return FALSE;
        }
    } else {
        SCLogDebug("Packet not ICMPV4 nor ICMPV6");
        return FALSE;
    }

    *id = pid;
    return TRUE;
}
예제 #6
0
/**
 * \brief This function is used to match icmp_seq rule option set on a packet
 *
 * \param t pointer to thread vars
 * \param det_ctx pointer to the pattern matcher thread
 * \param p pointer to the current packet
 * \param m pointer to the sigmatch that we will cast into DetectIcmpSeqData
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetectIcmpSeqMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m) {
    uint16_t seqn;
    DetectIcmpSeqData *iseq = (DetectIcmpSeqData *)m->ctx;

    if (PKT_IS_ICMPV4(p)) {
        SCLogDebug("ICMPV4_GET_SEQ(p) %"PRIu16" (network byte order), "
                "%"PRIu16" (host byte order)", ICMPV4_GET_SEQ(p),
                ntohs(ICMPV4_GET_SEQ(p)));

        switch (ICMPV4_GET_TYPE(p)){
            case ICMP_ECHOREPLY:
            case ICMP_ECHO:
            case ICMP_TIMESTAMP:
            case ICMP_TIMESTAMPREPLY:
            case ICMP_INFO_REQUEST:
            case ICMP_INFO_REPLY:
            case ICMP_ADDRESS:
            case ICMP_ADDRESSREPLY:
                seqn = ICMPV4_GET_SEQ(p);
                break;
            default:
                SCLogDebug("Packet has no seq field");
                return 0;
        }
    } else if (PKT_IS_ICMPV6(p)) {
        switch (ICMPV6_GET_TYPE(p)) {
            case ICMP6_ECHO_REQUEST:
            case ICMP6_ECHO_REPLY:
                seqn = ICMPV6_GET_SEQ(p);
                break;
            default:
                SCLogDebug("Packet has no seq field");
                return 0;
        }
    } else {
        SCLogDebug("Packet not ICMPV4 nor ICMPV6");
        return 0;
    }

    if (seqn == iseq->seq)
        return 1;

    return 0;
}
예제 #7
0
/**
 * \brief   Log the dropped packets in netfilter format when engine is running
 *          in inline mode
 *
 * \param tv    Pointer the current thread variables
 * \param p     Pointer the packet which is being logged
 * \param data  Pointer to the droplog struct
 *
 * \return return TM_EODE_OK on success
 */
static int LogDropLogNetFilter (ThreadVars *tv, const Packet *p, void *data)
{
    LogDropLogThread *dlt = (LogDropLogThread *)data;
    uint16_t proto = 0;
    char timebuf[64];

    CreateTimeString(&p->ts, timebuf, sizeof(timebuf));

    SCMutexLock(&dlt->file_ctx->fp_mutex);

    if (dlt->file_ctx->rotation_flag) {
        dlt->file_ctx->rotation_flag  = 0;
        if (SCConfLogReopen(dlt->file_ctx) != 0) {
            /* Rotation failed, error already logged. */
            SCMutexUnlock(&dlt->file_ctx->fp_mutex);
            return TM_ECODE_FAILED;
        }
    }

    char srcip[46] = "";
    char dstip[46] = "";

    if (PKT_IS_IPV4(p)) {
        PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, 16);
        PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, 16);
        fprintf(dlt->file_ctx->fp, "%s: IN= OUT= SRC=%s DST=%s LEN=%"PRIu16" "
                "TOS=0x%02"PRIu8" TTL=%"PRIu8" ID=%"PRIu16"", timebuf,
                srcip, dstip, IPV4_GET_IPLEN(p), IPV4_GET_IPTOS(p),
                IPV4_GET_IPTTL(p), IPV4_GET_IPID(p));
        proto = IPV4_GET_IPPROTO(p);
    } else if (PKT_IS_IPV6(p)) {
        PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip));
        PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip));
        fprintf(dlt->file_ctx->fp, "%s: IN= OUT= SRC=%s DST=%s LEN=%"PRIu16""
                " TC=%"PRIu32" HOPLIMIT=%"PRIu8" FLOWLBL=%"PRIu32"", timebuf,
                srcip, dstip, IPV6_GET_PLEN(p), IPV6_GET_CLASS(p),
                IPV6_GET_HLIM(p), IPV6_GET_FLOW(p));
        proto = IPV6_GET_L4PROTO(p);
    }

    if (SCProtoNameValid(proto) == TRUE) {
        fprintf(dlt->file_ctx->fp, " PROTO=%s",known_proto[proto]);
    } else {
        fprintf(dlt->file_ctx->fp, " PROTO=%03"PRIu16"",proto);
    }

    switch (proto) {
        case IPPROTO_TCP:
            if (PKT_IS_TCP(p)) {
                fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16" "
                        "SEQ=%"PRIu32" ACK=%"PRIu32" WINDOW=%"PRIu32"",
                        GET_TCP_SRC_PORT(p), GET_TCP_DST_PORT(p), TCP_GET_SEQ(p),
                        TCP_GET_ACK(p), TCP_GET_WINDOW(p));
                fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_SYN(p) ? " SYN" : "");
                fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_ACK(p) ? " ACK" : "");
                fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_PUSH(p) ? " PSH" : "");
                fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_RST(p) ? " RST" : "");
                fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_URG(p) ? " URG" : "");
                fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_FIN(p) ? " FIN" : "");
                fprintf(dlt->file_ctx->fp, " RES=0x%02"PRIu8" URGP=%"PRIu16"",
                        TCP_GET_RAW_X2(p->tcph), TCP_GET_URG_POINTER(p));
            }
            break;
        case IPPROTO_UDP:
            if (PKT_IS_UDP(p)) {
                fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16""
                        " LEN=%"PRIu16"", UDP_GET_SRC_PORT(p),
                        UDP_GET_DST_PORT(p), UDP_GET_LEN(p));
            }
            break;
        case IPPROTO_ICMP:
            if (PKT_IS_ICMPV4(p)) {
                fprintf(dlt->file_ctx->fp, " TYPE=%"PRIu8" CODE=%"PRIu8""
                        " ID=%"PRIu16" SEQ=%"PRIu16"", ICMPV4_GET_TYPE(p),
                        ICMPV4_GET_CODE(p), ICMPV4_GET_ID(p), ICMPV4_GET_SEQ(p));
            } else if (PKT_IS_ICMPV6(p)) {
                fprintf(dlt->file_ctx->fp, " TYPE=%"PRIu8" CODE=%"PRIu8""
                        " ID=%"PRIu16" SEQ=%"PRIu16"", ICMPV6_GET_TYPE(p),
                        ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p));
            }
            break;
        default:
            fprintf(dlt->file_ctx->fp," Unknown protocol");
    }

    fprintf(dlt->file_ctx->fp,"\n");

    fflush(dlt->file_ctx->fp);

    dlt->drop_cnt++;
    SCMutexUnlock(&dlt->file_ctx->fp_mutex);

    return TM_ECODE_OK;

}
예제 #8
0
/**
 * \brief   Log the dropped packets in netfilter format when engine is running
 *          in inline mode
 *
 * \param tv    Pointer the current thread variables
 * \param p     Pointer the packet which is being logged
 *
 * \return return TM_EODE_OK on success
 */
static int DropLogJSON (JsonDropLogThread *aft, const Packet *p)
{
    JsonDropOutputCtx *drop_ctx = aft->drop_ctx;

    json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "drop");
    if (unlikely(js == NULL))
        return TM_ECODE_OK;

    JsonAddCommonOptions(&drop_ctx->cfg, p, p->flow, js);

    json_t *djs = json_object();
    if (unlikely(djs == NULL)) {
        json_decref(js);
        return TM_ECODE_OK;
    }

    /* reset */
    MemBufferReset(aft->buffer);

    uint16_t proto = 0;
    if (PKT_IS_IPV4(p)) {
        json_object_set_new(djs, "len", json_integer(IPV4_GET_IPLEN(p)));
        json_object_set_new(djs, "tos", json_integer(IPV4_GET_IPTOS(p)));
        json_object_set_new(djs, "ttl", json_integer(IPV4_GET_IPTTL(p)));
        json_object_set_new(djs, "ipid", json_integer(IPV4_GET_IPID(p)));
        proto = IPV4_GET_IPPROTO(p);
    } else if (PKT_IS_IPV6(p)) {
        json_object_set_new(djs, "len", json_integer(IPV6_GET_PLEN(p)));
        json_object_set_new(djs, "tc", json_integer(IPV6_GET_CLASS(p)));
        json_object_set_new(djs, "hoplimit", json_integer(IPV6_GET_HLIM(p)));
        json_object_set_new(djs, "flowlbl", json_integer(IPV6_GET_FLOW(p)));
        proto = IPV6_GET_L4PROTO(p);
    }
    switch (proto) {
        case IPPROTO_TCP:
            if (PKT_IS_TCP(p)) {
                json_object_set_new(djs, "tcpseq", json_integer(TCP_GET_SEQ(p)));
                json_object_set_new(djs, "tcpack", json_integer(TCP_GET_ACK(p)));
                json_object_set_new(djs, "tcpwin", json_integer(TCP_GET_WINDOW(p)));
                json_object_set_new(djs, "syn", TCP_ISSET_FLAG_SYN(p) ? json_true() : json_false());
                json_object_set_new(djs, "ack", TCP_ISSET_FLAG_ACK(p) ? json_true() : json_false());
                json_object_set_new(djs, "psh", TCP_ISSET_FLAG_PUSH(p) ? json_true() : json_false());
                json_object_set_new(djs, "rst", TCP_ISSET_FLAG_RST(p) ? json_true() : json_false());
                json_object_set_new(djs, "urg", TCP_ISSET_FLAG_URG(p) ? json_true() : json_false());
                json_object_set_new(djs, "fin", TCP_ISSET_FLAG_FIN(p) ? json_true() : json_false());
                json_object_set_new(djs, "tcpres", json_integer(TCP_GET_RAW_X2(p->tcph)));
                json_object_set_new(djs, "tcpurgp", json_integer(TCP_GET_URG_POINTER(p)));
            }
            break;
        case IPPROTO_UDP:
            if (PKT_IS_UDP(p)) {
                json_object_set_new(djs, "udplen", json_integer(UDP_GET_LEN(p)));
            }
            break;
        case IPPROTO_ICMP:
            if (PKT_IS_ICMPV4(p)) {
                json_object_set_new(djs, "icmp_id", json_integer(ICMPV4_GET_ID(p)));
                json_object_set_new(djs, "icmp_seq", json_integer(ICMPV4_GET_SEQ(p)));
            } else if(PKT_IS_ICMPV6(p)) {
                json_object_set_new(djs, "icmp_id", json_integer(ICMPV6_GET_ID(p)));
                json_object_set_new(djs, "icmp_seq", json_integer(ICMPV6_GET_SEQ(p)));
            }
            break;
    }
    json_object_set_new(js, "drop", djs);

    if (aft->drop_ctx->flags & LOG_DROP_ALERTS) {
        int logged = 0;
        int i;
        for (i = 0; i < p->alerts.cnt; i++) {
            const PacketAlert *pa = &p->alerts.alerts[i];
            if (unlikely(pa->s == NULL)) {
                continue;
            }
            if ((pa->action & (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)) ||
               ((pa->action & ACTION_DROP) && EngineModeIsIPS()))
            {
                AlertJsonHeader(NULL, p, pa, js, 0);
                logged = 1;
            }
        }
        if (logged == 0) {
            if (p->alerts.drop.action != 0) {
                const PacketAlert *pa = &p->alerts.drop;
                AlertJsonHeader(NULL, p, pa, js, 0);
            }
        }
    }

    OutputJSONBuffer(js, aft->drop_ctx->file_ctx, &aft->buffer);
    json_object_del(js, "drop");
    json_object_clear(js);
    json_decref(js);

    return TM_ECODE_OK;
}
예제 #9
0
/**
 * \brief This function is used to match packets via the eDDOS rule
 *
 * \param t pointer to thread vars
 * \param det_ctx pointer to the pattern matcher thread
 * \param p pointer to the current packet
 * \param m pointer to the sigmatch that we will cast into DetectDummyData
 *
 * \retval 0 no match
 * \retval 1 match
 */
int DetecteDDOSMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m) {

    int ret = 0;
    DetecteDDOSSig *dsig = (DetecteDDOSSig *) m->ctx;
    DetecteDDOSData *ddata;
    Host *h;
    time_t t1;
    double time_diff_ms;

    if (PKT_IS_PSEUDOPKT(p)
            || !PKT_IS_IPV4(p)
            || p->flags & PKT_HOST_SRC_LOOKED_UP) {
        return 0;
    }

    /* TODO: Inspect the packet contents here.
     * Suricata defines a `Packet` structure in decode.h which already defines 
     * many useful elements -- have a look! */

    h = HostGetHostFromHash(&(p->src)); // Only SRC or can DEST be used too?
    p->flags |= PKT_HOST_SRC_LOOKED_UP;

    if (h == NULL) {
        printf("host not found!\n");
        return 0;
    }

    ddata = (DetecteDDOSData *) h->eddos;
    if (!ddata) {
        /* initialize fresh dummydata */
        ddata = SCMalloc(sizeof (DetecteDDOSData));
        bzero(ddata, sizeof (DetecteDDOSData));
        h->eddos = ddata;
    }
    /**
     * Start counting for evaluation
     */
    (ddata->cnt_packets)++;

    if (PKT_IS_TCP(p)) {
        //counter host
        (ddata->cnt_tcp)++;
        //counter global
        tcp_pkts_gesamt++;
        //printf("\nPakets TCP Flag: %d\n", p->tcph->th_flags);
        if (p->tcph->th_flags == tcp_syn_ack_flag) {
            (ddata->cnt_tcp_syn_ack)++;
            tcp_syn_ack_gesamt++;
            //printf("TCP_SYN_ACK");
        }
        if (p->tcph->th_flags == tcp_fin_ack_flag) {
            (ddata->cnt_tcp_fin_ack)++;
            tcp_fin_ack_gesamt++;
            //printf("TCP_FIN_ACK");
        }
        if (p->tcph->th_flags == TH_SYN) {
            (ddata->cnt_tcp_syn)++;
            tcp_syn_gesamt++;
            //printf("TCP_SYN");

        }
    }

    if (PKT_IS_UDP(p)) {
        (ddata->cnt_udp)++;
        udp_pkt_gesamt++;
    }

    if (PKT_IS_ICMPV4(p) && p->icmpv4h->type == ICMP_ECHO) {
        (ddata->cnt_icmp_echo_req)++;
        icmp_gesamt++;
    }

    /**
     * End Counting
     */
    /**
     * Start evaluation
     */
    if (PKT_IS_UDP(p) || PKT_IS_TCP(p)) {
        t1 = p->ts.tv_sec;
        time_diff_ms = difftime(t1, ddata->PeriodStart);
        if (time_diff_ms > (60)) {
            /*check for alarm here*/
            // abweichung vom 1:2 verhältnis SYN/ACK zu FIN/ACK
            float ver_syn_ack;
            float abw_syn_ack;
            // verhältnis von ICMP echo req paketen zu allen paketen
            float ver_echoreq_norm;
            // verhältnis von udp pakten zu allen paketen
            float ver_udp_norm;
            if (ddata->cnt_tcp_fin_ack != 0) {
                ver_syn_ack = ((float) (ddata->cnt_tcp_syn_ack) / ddata->cnt_tcp_fin_ack);
            } else {
                // we have syn but no syn_acks
                if ((((ddata->cnt_tcp_syn - ddata->cnt_tcp_syn_ack)*2) > dsig->max_abweichung_syn_ack ) && ddata->cnt_tcp_syn > 250) {
                    printf("\nSYN zu SYN/ACK Host\n");
                    printf("\n SYN: %llu SYN/ACK: %llu \n", ddata->cnt_tcp_syn, ddata->cnt_tcp_syn_ack );
                    ver_syn_ack = -1;
                }
                ver_syn_ack = 0;
            }

            abw_syn_ack = (((1 / 2) - ver_syn_ack))*2;
            //printf("\nSYN/ACK zu FIN/ACK Host Value: %f # SYN/ACK: %llu - FIN/ACK: %llu\n", (abw_syn_ack), ddata->cnt_tcp_syn_ack, ddata->cnt_tcp_fin_ack);

            if (abw_syn_ack < 0) {

                // check if abweichung größer als in signatur angegeben
                if (fabs(abw_syn_ack) > dsig->max_abweichung_syn_ack) {
                    ret = 1;
                    printf("\nSYN/ACK zu FIN/ACK Host Value: %f # SYN/ACK: %llu - FIN/ACK: %llu\n", fabs(abw_syn_ack), ddata->cnt_tcp_syn_ack, ddata->cnt_tcp_fin_ack);

                }
            }


            // verhältnis icmp echo request berechnen
            ver_echoreq_norm = ((float) (ddata->cnt_icmp_echo_req) / ddata->cnt_packets)*100;

            // check if ICMP echo request pakete zu viel im verhältnis zu allen
            if (ver_echoreq_norm > (float) (dsig->max_icmp_echo_req_packets)) {
                ret = 1;
                //printf("\nICMP Host\n");
            }
            /**
            // verhältnis udp paketen berechnen
            ver_udp_norm = ((float)(ddata->cnt_udp) / ddata->cnt_packets);
            // check if udp pakete zu viel im verhältnis zu allen
            if ( ver_udp_norm > (float)(dsig->max_udp_packets) ) {
                ret = 1;
            }  
             */
            /**
             * gesamtauswertung 
             */
            time_diff_ms = difftime(t1, start_time);
            if (time_diff_ms > (300)) {
                // auswertung udp pakete
                // verhältnis udp paketen berechnen
                ver_udp_norm = ((float) (udp_pkt_gesamt) / (udp_pkt_gesamt + tcp_pkts_gesamt))*100;
                //printf("UDP Pakete Verhaeltnis: %f", ver_udp_norm);
                // check if udp pakete zu viel im verhältnis zu allen
                if (ver_udp_norm > (float) (dsig->max_verhaeltnis_udp_packets)) {
                    ret = 1;
                    //printf("\nUDP ALL\n");
                }

                // auswertung echo requests
                ver_echoreq_norm = ((float) (icmp_gesamt) / (udp_pkt_gesamt + tcp_pkts_gesamt))*100;
                if (ver_echoreq_norm > (float) (icmp_gesamt)) {
                    ret = 1;
                    printf("\nICMP ALL\n");
                }

                // auswertung syn/ack
                if (tcp_fin_ack_gesamt != 0) {
                    ver_syn_ack = ((float) (tcp_syn_ack_gesamt) / tcp_fin_ack_gesamt);
                } else {
                    // we have syn but no syn_acks
                    if (fabs((float)((tcp_syn_gesamt - tcp_syn_gesamt)*2)) > dsig->max_abweichung_syn_ack) {
                        printf("\nSYN zu SYN/ACK ALL\n");
                        ver_syn_ack = -1;
                    }
                    ver_syn_ack = 0;
                }

                abw_syn_ack = (((1 / 2) - ver_syn_ack))*2;
                if (abw_syn_ack < 0) {
                    // check if abweichung größer als in signatur angegeben
                    if (fabs(abw_syn_ack) > dsig->max_abweichung_syn_ack) {
                        ret = 1;
                        printf("\nSYN/ACK zu FIN/ACK ALL\n");
                    }
                }
                // reset global counter for new interval
                
                tcp_pkts_gesamt = 0;
                udp_pkt_gesamt = 0;
                tcp_fin_ack_gesamt = 0;
                tcp_syn_ack_gesamt = 0;
                icmp_gesamt = 0;
                


            }
            /**printf("host found, packets now %d\n", (int)(ddata->cnt_packets));
            ret = (ddata->cnt_packets > dsig->max_numpackets);
             */

            // reset der parameter, da neuer zeitraum beginnt
            ddata->PeriodStart = p->ts.tv_sec;
            ddata->cnt_icmp_echo_req = 0;
            ddata->cnt_packets = 0;
            ddata->cnt_tcp = 0;
            ddata->cnt_tcp_fin_ack = 0;
            ddata->cnt_tcp_syn_ack = 0;
            ddata->cnt_udp = 0;

        } else {
            ret = 0;
        }
    }
    /**
     * End of evaluation
     */

    //printf("\nHost: %d - %d\n", (int)h, ddata->cnt_packets);
    /**
    printf("#################################\n");
    printf("Host: %d\n",(int)h);
    printf("\n TCP-SYN: %d \n", ddata->cnt_tcp_syn);
    printf("\n TCP-ACK: %d \n", ddata->cnt_tcp_ack);
    printf("\n Packets gesamt: %d \n", ddata->cnt_packets);
    printf("\n Packets TCP gesamt: %d \n", ddata->cnt_tcp);
    printf("\n Packets UDP gesamt: %d \n", ddata->cnt_udp);
    printf("\n ICMP ECHO REQUEST Packets: %d \n", ddata->cnt_icmp_echo_req);
    printf("#################################\n");
    
    printf("\n\nTCP Gesamt: %llu\n",tcp_pkts_gesamt);
    printf("UDP Gesamt: %llu\n",udp_pkt_gesamt);
    printf("SYN: %llu\n",tcp_syn_gesamt);
    printf("ICMP: %llu\n",icmp_gesamt);
    printf("SYN_ACK gesamt %d\n",(int)tcp_syn_ack_gesamt);
    printf("FIN_ACK_gesamt %d\n\n",(int)tcp_fin_ack_gesamt);
    */
    HostRelease(h);
    return ret;
}
예제 #10
0
/**
 * \brief Convert IP packet to an IDMEF alert (RFC 4765).
 * This function stores the alert SID (description and reference),
 * the payload of the packet, and pre-processed data.
 *
 * \return 0 if ok
 */
static int PacketToData(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert, AlertPreludeCtx *ctx)
{
    SCEnter();

    if (unlikely(p == NULL))
        SCReturnInt(0);

    AddIntData(alert, "snort_rule_sid", pa->s->id);
    AddIntData(alert, "snort_rule_rev", pa->s->rev);

    if (ctx->log_packet_header) {
        if ( PKT_IS_IPV4(p) )
            PacketToDataV4(p, pa, alert);

        else if ( PKT_IS_IPV6(p) )
            PacketToDataV6(p, pa, alert);

        if ( PKT_IS_TCP(p) ) {
            AddIntData(alert, "tcp_seq", TCP_GET_SEQ(p));
            AddIntData(alert, "tcp_ack", TCP_GET_ACK(p));

            AddIntData(alert, "tcp_off", TCP_GET_OFFSET(p));
            AddIntData(alert, "tcp_res", TCP_GET_X2(p));
            AddIntData(alert, "tcp_flags", TCP_GET_FLAGS(p));

            AddIntData(alert, "tcp_win", TCP_GET_WINDOW(p));
            AddIntData(alert, "tcp_sum", TCP_GET_SUM(p));
            AddIntData(alert, "tcp_urp", TCP_GET_URG_POINTER(p));
            if (p->tcpvars.ts_val != 0) {
                AddIntData(alert, "tcp_tsval", TCP_GET_TSVAL(p));
            }
            if (p->tcpvars.ts_ecr != 0) {
                AddIntData(alert, "tcp_tsecr", TCP_GET_TSECR(p));
            }
            if (p->tcph != NULL) {
                AddIntData(alert, "tcp_wscale", TCP_GET_WSCALE(p));
            }
            if (TCP_HAS_SACKOK(p)) {
                AddIntData(alert, "tcp_sackok", TCP_GET_SACKOK(p));
            }
            if (TCP_HAS_SACK(p)) {
                AddIntData(alert, "tcp_sack_cnt", TCP_GET_SACK_CNT(p));
            }
            AddIntData(alert, "tcp_hlen", TCP_GET_HLEN(p));
        }

        else if ( PKT_IS_UDP(p) ) {
            AddIntData(alert, "udp_len", UDP_GET_LEN(p));
            AddIntData(alert, "udp_sum", UDP_GET_SUM(p));
        }

        else if ( PKT_IS_ICMPV4(p) ) {
            AddIntData(alert, "icmp_type", ICMPV4_GET_TYPE(p));
            AddIntData(alert, "icmp_code", ICMPV4_GET_CODE(p));
            AddIntData(alert, "icmp_sum", ICMPV4_GET_RAW_CSUM(p));

        }

        else if ( PKT_IS_ICMPV6(p) ) {
            AddIntData(alert, "icmp_type", ICMPV6_GET_TYPE(p));
            AddIntData(alert, "icmp_code", ICMPV6_GET_CODE(p));
            AddIntData(alert, "icmp_csum", ICMPV6_GET_RAW_CSUM(p));
        }
    }

    if (ctx->log_packet_content)
        AddByteData(alert, "payload", p->payload, p->payload_len);

    SCReturnInt(0);
}
예제 #11
0
/**
 * \brief   Log the dropped packets in netfilter format when engine is running
 *          in inline mode
 *
 * \param tv    Pointer the current thread variables
 * \param p     Pointer the packet which is being logged
 *
 * \return return TM_EODE_OK on success
 */
static int DropLogJSON (JsonDropLogThread *aft, const Packet *p)
{
    uint16_t proto = 0;
    MemBuffer *buffer = (MemBuffer *)aft->buffer;
    json_t *js = CreateJSONHeader((Packet *)p, 0, "drop");//TODO const
    if (unlikely(js == NULL))
        return TM_ECODE_OK;

    json_t *djs = json_object();
    if (unlikely(djs == NULL)) {
        json_decref(js);
        return TM_ECODE_OK;
    }

    /* reset */
    MemBufferReset(buffer);

    if (PKT_IS_IPV4(p)) {
        json_object_set_new(djs, "len", json_integer(IPV4_GET_IPLEN(p)));
        json_object_set_new(djs, "tos", json_integer(IPV4_GET_IPTOS(p)));
        json_object_set_new(djs, "ttl", json_integer(IPV4_GET_IPTTL(p)));
        json_object_set_new(djs, "ipid", json_integer(IPV4_GET_IPID(p)));
        proto = IPV4_GET_IPPROTO(p);
    } else if (PKT_IS_IPV6(p)) {
        json_object_set_new(djs, "len", json_integer(IPV6_GET_PLEN(p)));
        json_object_set_new(djs, "tc", json_integer(IPV6_GET_CLASS(p)));
        json_object_set_new(djs, "hoplimit", json_integer(IPV6_GET_HLIM(p)));
        json_object_set_new(djs, "flowlbl", json_integer(IPV6_GET_FLOW(p)));
        proto = IPV6_GET_L4PROTO(p);
    }
    switch (proto) {
        case IPPROTO_TCP:
            json_object_set_new(djs, "tcpseq", json_integer(TCP_GET_SEQ(p)));
            json_object_set_new(djs, "tcpack", json_integer(TCP_GET_ACK(p)));
            json_object_set_new(djs, "tcpwin", json_integer(TCP_GET_WINDOW(p)));
            json_object_set_new(djs, "syn", TCP_ISSET_FLAG_SYN(p) ? json_true() : json_false());
            json_object_set_new(djs, "ack", TCP_ISSET_FLAG_ACK(p) ? json_true() : json_false());
            json_object_set_new(djs, "psh", TCP_ISSET_FLAG_PUSH(p) ? json_true() : json_false());
            json_object_set_new(djs, "rst", TCP_ISSET_FLAG_RST(p) ? json_true() : json_false());
            json_object_set_new(djs, "urg", TCP_ISSET_FLAG_URG(p) ? json_true() : json_false());
            json_object_set_new(djs, "fin", TCP_ISSET_FLAG_FIN(p) ? json_true() : json_false());
            json_object_set_new(djs, "tcpres", json_integer(TCP_GET_RAW_X2(p->tcph)));
            json_object_set_new(djs, "tcpurgp", json_integer(TCP_GET_URG_POINTER(p)));
            break;
        case IPPROTO_UDP:
            json_object_set_new(djs, "udplen", json_integer(UDP_GET_LEN(p)));
            break;
        case IPPROTO_ICMP:
            if (PKT_IS_ICMPV4(p)) {
                json_object_set_new(djs, "icmp_id", json_integer(ICMPV4_GET_ID(p)));
                json_object_set_new(djs, "icmp_seq", json_integer(ICMPV4_GET_SEQ(p)));
            } else if(PKT_IS_ICMPV6(p)) {
                json_object_set_new(djs, "icmp_id", json_integer(ICMPV6_GET_ID(p)));
                json_object_set_new(djs, "icmp_seq", json_integer(ICMPV6_GET_SEQ(p)));
            }
            break;
    }
    json_object_set_new(js, "drop", djs);
    OutputJSONBuffer(js, aft->file_ctx, buffer);
    json_object_del(js, "drop");
    json_object_clear(js);
    json_decref(js);

    return TM_ECODE_OK;
}