TmEcode AlertDebugLogDecoderEvent(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { AlertDebugLogThread *aft = (AlertDebugLogThread *)data; int i; char timebuf[64]; if (p->alerts.cnt == 0) return TM_ECODE_OK; MemBufferReset(aft->buffer); CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); MemBufferWriteString(aft->buffer, "+================\n" "TIME: %s\n", timebuf); if (p->pcap_cnt > 0) { MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt); } MemBufferWriteString(aft->buffer, "ALERT CNT: %" PRIu32 "\n", p->alerts.cnt); for (i = 0; i < p->alerts.cnt; i++) { PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } MemBufferWriteString(aft->buffer, "ALERT MSG [%02d]: %s\n" "ALERT GID [%02d]: %" PRIu32 "\n" "ALERT SID [%02d]: %" PRIu32 "\n" "ALERT REV [%02d]: %" PRIu32 "\n" "ALERT CLASS [%02d]: %s\n" "ALERT PRIO [%02d]: %" PRIu32 "\n", i, pa->s->msg, i, pa->s->gid, i, pa->s->id, i, pa->s->rev, i, pa->s->class_msg, i, pa->s->prio); } MemBufferWriteString(aft->buffer, "PACKET LEN: %" PRIu32 "\n" "PACKET:\n", GET_PKT_LEN(p)); PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, GET_PKT_DATA(p), GET_PKT_LEN(p)); SCMutexLock(&aft->file_ctx->fp_mutex); (void)MemBufferPrintToFPAsString(aft->buffer, aft->file_ctx->fp); fflush(aft->file_ctx->fp); aft->file_ctx->alerts += p->alerts.cnt; SCMutexUnlock(&aft->file_ctx->fp_mutex); return TM_ECODE_OK; }
int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer *buffer) { char *js_s = json_dumps(js, JSON_PRESERVE_ORDER|JSON_COMPACT|JSON_ENSURE_ASCII| #ifdef JSON_ESCAPE_SLASH JSON_ESCAPE_SLASH #else 0 #endif ); if (unlikely(js_s == NULL)) return TM_ECODE_OK; SCMutexLock(&file_ctx->fp_mutex); if (json_out == ALERT_SYSLOG) { syslog(alert_syslog_level, "%s", js_s); } else if (json_out == ALERT_FILE) { MemBufferWriteString(buffer, "%s\n", js_s); (void)MemBufferPrintToFPAsString(buffer, file_ctx->fp); fflush(file_ctx->fp); } SCMutexUnlock(&file_ctx->fp_mutex); free(js_s); return 0; }
static TmEcode LogHttpLogIPWrapper(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq, int ipproto) { SCEnter(); LogHttpLogThread *aft = (LogHttpLogThread *)data; LogHttpFileCtx *hlog = aft->httplog_ctx; char timebuf[64]; size_t idx = 0; /* no flow, no htp state */ if (p->flow == NULL) { SCReturnInt(TM_ECODE_OK); } /* check if we have HTTP state or not */ FLOWLOCK_WRLOCK(p->flow); /* WRITE lock before we updated flow logged id */ uint16_t proto = AppLayerGetProtoFromPacket(p); if (proto != ALPROTO_HTTP) goto end; int r = AppLayerTransactionGetLoggedId(p->flow); if (r < 0) { goto end; } size_t logged = (size_t)r; r = HtpTransactionGetLoggableId(p->flow); if (r < 0) { goto end; } size_t loggable = (size_t)r; /* nothing to do */ if (logged >= loggable) { goto end; } HtpState *htp_state = (HtpState *)AppLayerGetProtoStateFromPacket(p); if (htp_state == NULL) { SCLogDebug("no http state, so no request logging"); goto end; } if (htp_state->connp == NULL || htp_state->connp->conn == NULL) goto end; htp_tx_t *tx = NULL; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); char srcip[46], dstip[46]; Port sp, dp; if ((PKT_IS_TOSERVER(p))) { switch (ipproto) { case AF_INET: PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); break; case AF_INET6: 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)); break; default: goto end; } sp = p->sp; dp = p->dp; } else { switch (ipproto) { case AF_INET: PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), dstip, sizeof(dstip)); break; case AF_INET6: PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), dstip, sizeof(dstip)); break; default: goto end; } sp = p->dp; dp = p->sp; } for (idx = logged; idx < loggable; idx++) { tx = list_get(htp_state->connp->conn->transactions, idx); if (tx == NULL) { SCLogDebug("tx is NULL not logging !!"); continue; } SCLogDebug("got a HTTP request and now logging !!"); /* reset */ MemBufferReset(aft->buffer); if (hlog->flags & LOG_HTTP_CUSTOM) { LogHttpLogCustom(aft, tx, &p->ts, srcip, sp, dstip, dp); } else { /* time */ MemBufferWriteString(aft->buffer, "%s ", timebuf); /* hostname */ if (tx->parsed_uri != NULL && tx->parsed_uri->hostname != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->parsed_uri->hostname), bstr_len(tx->parsed_uri->hostname)); } else { MemBufferWriteString(aft->buffer, "<hostname unknown>"); } MemBufferWriteString(aft->buffer, " [**] "); /* uri */ if (tx->request_uri != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_uri), bstr_len(tx->request_uri)); } MemBufferWriteString(aft->buffer, " [**] "); /* user agent */ htp_header_t *h_user_agent = NULL; if (tx->request_headers != NULL) { h_user_agent = table_getc(tx->request_headers, "user-agent"); } if (h_user_agent != NULL) { PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, (uint8_t *)bstr_ptr(h_user_agent->value), bstr_len(h_user_agent->value)); } else { MemBufferWriteString(aft->buffer, "<useragent unknown>"); } if (hlog->flags & LOG_HTTP_EXTENDED) { LogHttpLogExtended(aft, tx); } /* ip/tcp header info */ MemBufferWriteString(aft->buffer, " [**] %s:%" PRIu16 " -> %s:%" PRIu16 "\n", srcip, sp, dstip, dp); } aft->uri_cnt ++; SCMutexLock(&hlog->file_ctx->fp_mutex); MemBufferPrintToFPAsString(aft->buffer, hlog->file_ctx->fp); fflush(hlog->file_ctx->fp); SCMutexUnlock(&hlog->file_ctx->fp_mutex); AppLayerTransactionUpdateLoggedId(p->flow); } end: FLOWLOCK_UNLOCK(p->flow); SCReturnInt(TM_ECODE_OK); }
TmEcode AlertDebugLogger(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { AlertDebugLogThread *aft = (AlertDebugLogThread *)data; int i; char timebuf[64]; if (p->alerts.cnt == 0) return TM_ECODE_OK; MemBufferReset(aft->buffer); CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); MemBufferWriteString(aft->buffer, "+================\n" "TIME: %s\n", timebuf); if (p->pcap_cnt > 0) { MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt); } char srcip[46], dstip[46]; if (PKT_IS_IPV4(p)) { PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); } 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)); } MemBufferWriteString(aft->buffer, "SRC IP: %s\n" "DST IP: %s\n" "PROTO: %" PRIu32 "\n", srcip, dstip, p->proto); if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) { MemBufferWriteString(aft->buffer, "SRC PORT: %" PRIu32 "\n" "DST PORT: %" PRIu32 "\n", p->sp, p->dp); if (PKT_IS_TCP(p)) { MemBufferWriteString(aft->buffer, "TCP SEQ: %"PRIu32"\n" "TCP ACK: %"PRIu32"\n", TCP_GET_SEQ(p), TCP_GET_ACK(p)); } } /* flow stuff */ MemBufferWriteString(aft->buffer, "FLOW: to_server: %s, " "to_client: %s\n", p->flowflags & FLOW_PKT_TOSERVER ? "TRUE" : "FALSE", p->flowflags & FLOW_PKT_TOCLIENT ? "TRUE" : "FALSE"); if (p->flow != NULL) { FLOWLOCK_RDLOCK(p->flow); CreateTimeString(&p->flow->startts, timebuf, sizeof(timebuf)); MemBufferWriteString(aft->buffer, "FLOW Start TS: %s\n", timebuf); #ifdef DEBUG MemBufferWriteString(aft->buffer, "FLOW PKTS TODST: %"PRIu32"\n" "FLOW PKTS TOSRC: %"PRIu32"\n" "FLOW Total Bytes: %"PRIu64"\n", p->flow->todstpktcnt, p->flow->tosrcpktcnt, p->flow->bytecnt); #endif MemBufferWriteString(aft->buffer, "FLOW IPONLY SET: TOSERVER: %s, TOCLIENT: %s\n" "FLOW ACTION: DROP: %s, PASS %s\n" "FLOW NOINSPECTION: PACKET: %s, PAYLOAD: %s, APP_LAYER: %s\n" "FLOW APP_LAYER: DETECTED: %s, PROTO %"PRIu16"\n", p->flow->flags & FLOW_TOSERVER_IPONLY_SET ? "TRUE" : "FALSE", p->flow->flags & FLOW_TOCLIENT_IPONLY_SET ? "TRUE" : "FALSE", p->flow->flags & FLOW_ACTION_DROP ? "TRUE" : "FALSE", p->flow->flags & FLOW_ACTION_PASS ? "TRUE" : "FALSE", p->flow->flags & FLOW_NOPACKET_INSPECTION ? "TRUE" : "FALSE", p->flow->flags & FLOW_NOPAYLOAD_INSPECTION ? "TRUE" : "FALSE", p->flow->flags & FLOW_NO_APPLAYER_INSPECTION ? "TRUE" : "FALSE", (p->flow->alproto != ALPROTO_UNKNOWN) ? "TRUE" : "FALSE", p->flow->alproto); AlertDebugLogFlowVars(aft, p); AlertDebugLogFlowBits(aft, p); FLOWLOCK_UNLOCK(p->flow); } AlertDebugLogPktVars(aft, p); /* any stuff */ /* Sig details? */ MemBufferWriteString(aft->buffer, "PACKET LEN: %" PRIu32 "\n" "PACKET:\n", GET_PKT_LEN(p)); PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, GET_PKT_DATA(p), GET_PKT_LEN(p)); MemBufferWriteString(aft->buffer, "ALERT CNT: %" PRIu32 "\n", p->alerts.cnt); for (i = 0; i < p->alerts.cnt; i++) { PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } MemBufferWriteString(aft->buffer, "ALERT MSG [%02d]: %s\n" "ALERT GID [%02d]: %" PRIu32 "\n" "ALERT SID [%02d]: %" PRIu32 "\n" "ALERT REV [%02d]: %" PRIu32 "\n" "ALERT CLASS [%02d]: %s\n" "ALERT PRIO [%02d]: %" PRIu32 "\n" "ALERT FOUND IN [%02d]: %s\n", i, pa->s->msg, i, pa->s->gid, i, pa->s->id, i, pa->s->rev, i, pa->s->class_msg ? pa->s->class_msg : "<none>", i, pa->s->prio, i, pa->flags & PACKET_ALERT_FLAG_STREAM_MATCH ? "STREAM" : (pa->flags & PACKET_ALERT_FLAG_STATE_MATCH ? "STATE" : "PACKET")); if (p->payload_len > 0) { MemBufferWriteString(aft->buffer, "PAYLOAD LEN: %" PRIu32 "\n" "PAYLOAD:\n", p->payload_len); PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, p->payload, p->payload_len); } if (pa->flags & PACKET_ALERT_FLAG_STATE_MATCH || pa->flags & PACKET_ALERT_FLAG_STREAM_MATCH) { /* This is an app layer or stream alert */ int ret; uint8_t flag; if ((! PKT_IS_TCP(p)) || p->flow == NULL || p->flow->protoctx == NULL) { return TM_ECODE_OK; } /* IDS mode reverse the data */ /** \todo improve the order selection policy */ if (p->flowflags & FLOW_PKT_TOSERVER) { flag = FLOW_PKT_TOCLIENT; } else { flag = FLOW_PKT_TOSERVER; } ret = StreamSegmentForEach(p, flag, AlertDebugPrintStreamSegmentCallback, (void *)aft); if (ret < 0) { return TM_ECODE_FAILED; } } } SCMutexLock(&aft->file_ctx->fp_mutex); (void)MemBufferPrintToFPAsString(aft->buffer, aft->file_ctx->fp); fflush(aft->file_ctx->fp); aft->file_ctx->alerts += p->alerts.cnt; SCMutexUnlock(&aft->file_ctx->fp_mutex); return TM_ECODE_OK; }
void RulesDumpMatchArray(const DetectEngineThreadCtx *det_ctx, const Packet *p) { json_t *js = CreateJSONHeader(p, 0, "inspectedrules"); if (js == NULL) return; json_t *ir = json_object(); if (ir == NULL) return; json_object_set_new(ir, "rule_group_id", json_integer(det_ctx->sgh->id)); json_object_set_new(ir, "rule_cnt", json_integer(det_ctx->match_array_cnt)); json_t *js_array = json_array(); uint32_t x; for (x = 0; x < det_ctx->match_array_cnt; x++) { const Signature *s = det_ctx->match_array[x]; if (s == NULL) continue; json_t *js_sig = json_object(); if (unlikely(js == NULL)) continue; json_object_set_new(js_sig, "sig_id", json_integer(s->id)); json_object_set_new(js_sig, "mpm", (s->mpm_sm != NULL) ? json_true() : json_false()); if (s->mpm_sm != NULL) { char orig[256] = ""; char chop[256] = ""; DumpFp(s->mpm_sm, orig, sizeof(orig), chop, sizeof(chop)); json_object_set_new(js_sig, "mpm_buffer", json_string(DetectListToHumanString(SigMatchListSMBelongsTo(s, s->mpm_sm)))); json_object_set_new(js_sig, "mpm_pattern", json_string(orig)); if (strlen(chop) > 0) { json_object_set_new(js_sig, "mpm_pattern_chop", json_string(chop)); } } json_array_append_new(js_array, js_sig); } json_object_set_new(ir, "rules", js_array); json_object_set_new(js, "inspectedrules", ir); const char *filename = "packet_inspected_rules.json"; const char *log_dir = ConfigGetLogDirectory(); char log_path[PATH_MAX] = ""; snprintf(log_path, sizeof(log_path), "%s/%s", log_dir, filename); MemBuffer *mbuf = NULL; mbuf = MemBufferCreateNew(4096); BUG_ON(mbuf == NULL); OutputJSONMemBufferWrapper wrapper = { .buffer = &mbuf, .expand_by = 4096, }; int r = json_dump_callback(js, OutputJSONMemBufferCallback, &wrapper, JSON_PRESERVE_ORDER|JSON_COMPACT|JSON_ENSURE_ASCII| JSON_ESCAPE_SLASH); if (r != 0) { SCLogWarning(SC_ERR_SOCKET, "unable to serialize JSON object"); } else { MemBufferWriteString(mbuf, "\n"); SCMutexLock(&g_rule_dump_write_m); FILE *fp = fopen(log_path, "a"); if (fp != NULL) { MemBufferPrintToFPAsString(mbuf, fp); fclose(fp); SCMutexUnlock(&g_rule_dump_write_m); } } MemBufferFree(mbuf); json_object_clear(js); json_decref(js); }