DNS: adding dns_request content modifier

pull/412/merge
Victor Julien 12 years ago
parent 6674f4892c
commit f10dd603ff

@ -73,6 +73,7 @@ detect-dce-stub-data.c detect-dce-stub-data.h \
detect-depth.c detect-depth.h \ detect-depth.c detect-depth.h \
detect-detection-filter.c detect-detection-filter.h \ detect-detection-filter.c detect-detection-filter.h \
detect-distance.c detect-distance.h \ detect-distance.c detect-distance.h \
detect-dns-query.c detect-dns-query.h \
detect-dsize.c detect-dsize.h \ detect-dsize.c detect-dsize.h \
detect-engine-address.c detect-engine-address.h \ detect-engine-address.c detect-engine-address.h \
detect-engine-address-ipv4.c detect-engine-address-ipv4.h \ detect-engine-address-ipv4.c detect-engine-address-ipv4.h \
@ -82,6 +83,7 @@ detect-engine-analyzer.c detect-engine-analyzer.h \
detect-engine.c detect-engine.h \ detect-engine.c detect-engine.h \
detect-engine-content-inspection.c detect-engine-content-inspection.h \ detect-engine-content-inspection.c detect-engine-content-inspection.h \
detect-engine-dcepayload.c detect-engine-dcepayload.h \ detect-engine-dcepayload.c detect-engine-dcepayload.h \
detect-engine-dns.c detect-engine-dns.h \
detect-engine-event.c detect-engine-event.h \ detect-engine-event.c detect-engine-event.h \
detect-engine-file.c detect-engine-file.h \ detect-engine-file.c detect-engine-file.h \
detect-engine-hcbd.c detect-engine-hcbd.h \ detect-engine-hcbd.c detect-engine-hcbd.h \

@ -74,13 +74,23 @@ void DNSStateFree(void *s) {
} }
void *DNSGetTx(void *alstate, uint64_t tx_id) { void *DNSGetTx(void *alstate, uint64_t tx_id) {
/* todo */ DNSState *dns_state = (DNSState *)alstate;
DNSTransaction *tx = NULL;
TAILQ_FOREACH(tx, &dns_state->tx_list, next) {
SCLogDebug("tx->tx_num %u, tx_id %"PRIu64, tx->tx_num, tx_id);
if ((tx_id+1) != tx->tx_num)
continue;
return tx;
}
return NULL; return NULL;
} }
uint64_t DNSGetTxCnt(void *alstate) { uint64_t DNSGetTxCnt(void *alstate) {
DNSState *dns_state = (DNSState *)alstate; DNSState *dns_state = (DNSState *)alstate;
return (uint64_t)dns_state->transaction_cnt; return (uint64_t)dns_state->transaction_max;
} }
int DNSGetAlstateProgress(void *tx, uint8_t direction) { int DNSGetAlstateProgress(void *tx, uint8_t direction) {

@ -39,8 +39,11 @@ enum {
ALPROTO_DCERPC, ALPROTO_DCERPC,
ALPROTO_DCERPC_UDP, ALPROTO_DCERPC_UDP,
ALPROTO_IRC, ALPROTO_IRC,
ALPROTO_DNS,
ALPROTO_DNS_UDP, ALPROTO_DNS_UDP,
ALPROTO_DNS_TCP, ALPROTO_DNS_TCP,
/* used by the probing parser when alproto detection fails /* used by the probing parser when alproto detection fails
* permanently for that particular stream */ * permanently for that particular stream */
ALPROTO_FAILED, ALPROTO_FAILED,

@ -158,13 +158,17 @@ int DetectAppLayerEventSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
sm->ctx = (void *)data; sm->ctx = (void *)data;
if (s->alproto != ALPROTO_UNKNOWN) { if (s->alproto != ALPROTO_UNKNOWN) {
if (s->alproto != ((DetectAppLayerEventData *)sm->ctx)->alproto) { if (s->alproto == ALPROTO_DNS &&
(data->alproto == ALPROTO_DNS_UDP || data->alproto == ALPROTO_DNS_TCP))
{
SCLogDebug("DNS app layer event");
} else if (s->alproto != data->alproto) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains " SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains "
"conflicting keywords needing different alprotos"); "conflicting keywords needing different alprotos");
goto error; goto error;
} }
} else { } else {
s->alproto = ((DetectAppLayerEventData *)sm->ctx)->alproto; s->alproto = data->alproto;
} }
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);

@ -0,0 +1,91 @@
/* Copyright (C) 2013 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \ingroup dnslayer
*
* @{
*/
/**
* \file
*
* \author Victor Julien <victor@inliniac.net>
*/
#include "suricata-common.h"
#include "threads.h"
#include "debug.h"
#include "decode.h"
#include "detect.h"
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-engine-mpm.h"
#include "detect-content.h"
#include "detect-pcre.h"
#include "flow.h"
#include "flow-var.h"
#include "util-debug.h"
#include "util-unittest.h"
#include "util-spm.h"
#include "util-print.h"
#include "app-layer.h"
#include "detect-dns-query.h"
static int DetectDnsQuerySetup (DetectEngineCtx *, Signature *, char *);
/**
* \brief Registration function for keyword: http_uri
*/
void DetectDnsQueryRegister (void) {
sigmatch_table[DETECT_AL_DNS_QUERY].name = "dns_query";
sigmatch_table[DETECT_AL_DNS_QUERY].desc = "content modifier to match specifically and only on the DNS query-buffer";
sigmatch_table[DETECT_AL_DNS_QUERY].Match = NULL;
sigmatch_table[DETECT_AL_DNS_QUERY].AppLayerMatch = NULL;
sigmatch_table[DETECT_AL_DNS_QUERY].alproto = ALPROTO_DNS;
sigmatch_table[DETECT_AL_DNS_QUERY].Setup = DetectDnsQuerySetup;
sigmatch_table[DETECT_AL_DNS_QUERY].Free = NULL;
sigmatch_table[DETECT_AL_DNS_QUERY].RegisterTests = NULL;
sigmatch_table[DETECT_AL_DNS_QUERY].flags |= SIGMATCH_PAYLOAD;
}
/**
* \brief this function setups the dns_query modifier keyword used in the rule
*
* \param de_ctx Pointer to the Detection Engine Context
* \param s Pointer to the Signature to which the current keyword belongs
* \param str Should hold an empty string always
*
* \retval 0 On success
* \retval -1 On failure
*/
static int DetectDnsQuerySetup(DetectEngineCtx *de_ctx, Signature *s, char *str)
{
return DetectEngineContentModifierBufferSetup(de_ctx, s, str,
DETECT_AL_DNS_QUERY,
DETECT_SM_LIST_DNSQUERY_MATCH,
ALPROTO_DNS, NULL);
}

@ -0,0 +1,29 @@
/* Copyright (C) 2013 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Victor Julien <victor@inliniac.net>
*/
#ifndef __DETECT_DNS_QUERY_H__
#define __DETECT_DNS_QUERY_H__
void DetectDnsQueryRegister (void);
#endif /* __DETECT_DNS_QUERY_H__ */

@ -47,6 +47,7 @@ enum {
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HUAD, DETECT_ENGINE_CONTENT_INSPECTION_MODE_HUAD,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HHHD, DETECT_ENGINE_CONTENT_INSPECTION_MODE_HHHD,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRHHD, DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRHHD,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_DNSQUERY,
}; };
int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,

@ -0,0 +1,92 @@
/* Copyright (C) 2013 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/** \file
*
* \author Victor Julien <victor@inliniac.net>
*
* Based on detect-engine-uri.c
*/
#include "suricata-common.h"
#include "suricata.h"
#include "decode.h"
#include "detect.h"
#include "detect-engine.h"
#include "detect-parse.h"
#include "detect-engine-state.h"
#include "detect-engine-content-inspection.h"
#include "flow-util.h"
#include "util-debug.h"
#include "util-print.h"
#include "flow.h"
#include "app-layer.h"
#include "app-layer-parser.h"
#include "app-layer-protos.h"
#include "app-layer-dns-common.h"
#include "util-unittest.h"
#include "util-unittest-helper.h"
/** \brief Do the content inspection & validation for a signature
*
* \param de_ctx Detection engine context
* \param det_ctx Detection engine thread context
* \param s Signature to inspect
* \param sm SigMatch to inspect
* \param f Flow
* \param flags app layer flags
* \param state App layer state
*
* \retval 0 no match
* \retval 1 match
*/
int DetectEngineInspectDnsQueryName(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
void *alstate, void *txv, uint64_t tx_id)
{
DNSTransaction *tx = (DNSTransaction *)txv;
DNSQueryEntry *query = NULL;
uint8_t *buffer;
uint16_t buffer_len;
int r = 0;
TAILQ_FOREACH(query, &tx->query_list, next) {
SCLogDebug("tx %p query %p", tx, query);
det_ctx->discontinue_matching = 0;
det_ctx->buffer_offset = 0;
det_ctx->inspection_recursion_counter = 0;
buffer = (uint8_t *)((uint8_t *)query + sizeof(DNSQueryEntry));
buffer_len = query->len;
//PrintRawDataFp(stdout, buffer, buffer_len);
r = DetectEngineContentInspection(de_ctx, det_ctx,
s, s->sm_lists[DETECT_SM_LIST_DNSQUERY_MATCH],
f, buffer, buffer_len, 0,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_DNSQUERY, NULL);
if (r == 1)
break;
}
return r;
}

@ -0,0 +1,30 @@
/* Copyright (C) 2013 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/** \file
*
* \author Victor Julien <victor@inliniac.net>
*/
#ifndef __DETECT_ENGINE_DNS_H__
#define __DETECT_ENGINE_DNS_H__
int DetectEngineInspectDnsQueryName(ThreadVars *, DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *, Signature *,
Flow *, uint8_t, void *, void *, uint64_t);
#endif /* __DETECT_ENGINE_DNS_H__ */

@ -69,6 +69,7 @@
#include "app-layer-smb.h" #include "app-layer-smb.h"
#include "app-layer-dcerpc-common.h" #include "app-layer-dcerpc-common.h"
#include "app-layer-dcerpc.h" #include "app-layer-dcerpc.h"
#include "app-layer-dns-common.h"
#include "util-unittest.h" #include "util-unittest.h"
#include "util-unittest-helper.h" #include "util-unittest-helper.h"
@ -265,14 +266,16 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
if (AppLayerAlprotoSupportsTxs(alproto)) { if (AppLayerAlprotoSupportsTxs(alproto)) {
FLOWLOCK_WRLOCK(f); FLOWLOCK_WRLOCK(f);
htp_state = (HtpState *)alstate; if (alproto == ALPROTO_HTTP) {
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) { htp_state = (HtpState *)alstate;
FLOWLOCK_UNLOCK(f); if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
goto end; FLOWLOCK_UNLOCK(f);
goto end;
}
} }
tx_id = AppLayerTransactionGetInspectId(f, flags); tx_id = AppLayerTransactionGetInspectId(f, flags);
total_txs = AppLayerGetTxCnt(alproto, htp_state); total_txs = AppLayerGetTxCnt(alproto, alstate);
for (; tx_id < total_txs; tx_id++) { for (; tx_id < total_txs; tx_id++) {
total_matches = 0; total_matches = 0;
tx = AppLayerGetTx(alproto, alstate, tx_id); tx = AppLayerGetTx(alproto, alstate, tx_id);
@ -526,11 +529,13 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
if (alproto_supports_txs) { if (alproto_supports_txs) {
FLOWLOCK_WRLOCK(f); FLOWLOCK_WRLOCK(f);
htp_state = (HtpState *)alstate; if (alproto == ALPROTO_HTTP) {
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) { htp_state = (HtpState *)alstate;
FLOWLOCK_UNLOCK(f); if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
RULE_PROFILING_END(det_ctx, s, match); FLOWLOCK_UNLOCK(f);
goto end; RULE_PROFILING_END(det_ctx, s, match);
goto end;
}
} }
engine = app_inspection_engine[alproto][(flags & STREAM_TOSERVER) ? 0 : 1]; engine = app_inspection_engine[alproto][(flags & STREAM_TOSERVER) ? 0 : 1];

@ -74,6 +74,7 @@
#define DE_STATE_FLAG_FILE_TS_INSPECT (1 << 14) #define DE_STATE_FLAG_FILE_TS_INSPECT (1 << 14)
#define DE_STATE_FLAG_FULL_INSPECT (1 << 15) #define DE_STATE_FLAG_FULL_INSPECT (1 << 15)
#define DE_STATE_FLAG_SIG_CANT_MATCH (1 << 16) #define DE_STATE_FLAG_SIG_CANT_MATCH (1 << 16)
#define DE_STATE_FLAG_DNSQUERY_INSPECT (1 << 17)
/* state flags */ /* state flags */
#define DETECT_ENGINE_STATE_FLAG_FILE_STORE_DISABLED 0x0001 #define DETECT_ENGINE_STATE_FLAG_FILE_STORE_DISABLED 0x0001

@ -56,6 +56,7 @@
#include "detect-engine-hhhd.h" #include "detect-engine-hhhd.h"
#include "detect-engine-hrhhd.h" #include "detect-engine-hrhhd.h"
#include "detect-engine-file.h" #include "detect-engine-file.h"
#include "detect-engine-dns.h"
#include "detect-engine.h" #include "detect-engine.h"
#include "detect-engine-state.h" #include "detect-engine-state.h"
@ -214,6 +215,13 @@ void DetectEngineRegisterAppInspectionEngines(void)
DE_STATE_FLAG_HRHHD_INSPECT, DE_STATE_FLAG_HRHHD_INSPECT,
0, 0,
DetectEngineInspectHttpHRH }, DetectEngineInspectHttpHRH },
/* DNS */
{ ALPROTO_DNS,
DETECT_SM_LIST_DNSQUERY_MATCH,
DE_STATE_FLAG_DNSQUERY_INSPECT,
DE_STATE_FLAG_DNSQUERY_INSPECT,
0,
DetectEngineInspectDnsQueryName },
}; };
struct tmp_t data_toclient[] = { struct tmp_t data_toclient[] = {

@ -779,7 +779,7 @@ static int SigParseBasics(Signature *s, char *sigstr, char ***result, uint8_t ad
goto error; goto error;
if (SigParseProto(s, "dnsudp") < 0) if (SigParseProto(s, "dnsudp") < 0)
goto error; goto error;
s->alproto = ALPROTO_DNS;
} else { } else {
if (SigParseProto(s, arr[CONFIG_PROTO]) < 0) if (SigParseProto(s, arr[CONFIG_PROTO]) < 0)
goto error; goto error;
@ -1402,6 +1402,8 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, char *sigstr,
sig->flags |= SIG_FLAG_STATE_MATCH; sig->flags |= SIG_FLAG_STATE_MATCH;
if (sig->sm_lists[DETECT_SM_LIST_HRHHDMATCH]) if (sig->sm_lists[DETECT_SM_LIST_HRHHDMATCH])
sig->flags |= SIG_FLAG_STATE_MATCH; sig->flags |= SIG_FLAG_STATE_MATCH;
if (sig->sm_lists[DETECT_SM_LIST_DNSQUERY_MATCH])
sig->flags |= SIG_FLAG_STATE_MATCH;
if (!(sig->init_flags & SIG_FLAG_INIT_FLOW)) { if (!(sig->init_flags & SIG_FLAG_INIT_FLOW)) {
sig->flags |= SIG_FLAG_TOSERVER; sig->flags |= SIG_FLAG_TOSERVER;

@ -149,6 +149,7 @@
#include "detect-luajit.h" #include "detect-luajit.h"
#include "detect-iprep.h" #include "detect-iprep.h"
#include "detect-geoip.h" #include "detect-geoip.h"
#include "detect-dns-query.h"
#include "util-rule-vars.h" #include "util-rule-vars.h"
@ -505,6 +506,11 @@ static inline int SigMatchSignaturesBuildMatchArrayAddSignature(DetectEngineThre
SCLogDebug("DCERPC sig, alproto not SMB or SMB2"); SCLogDebug("DCERPC sig, alproto not SMB or SMB2");
return 0; return 0;
} }
} else if (s->alproto == ALPROTO_DNS) {
if (alproto != ALPROTO_DNS_UDP && alproto != ALPROTO_DNS_TCP) {
SCLogDebug("DNS sig, alproto not DNS/TCP or DNS/UDP");
return 0;
}
} else { } else {
SCLogDebug("alproto mismatch"); SCLogDebug("alproto mismatch");
return 0; return 0;
@ -4869,6 +4875,7 @@ void SigTableSetup(void) {
DetectHttpHRHRegister(); DetectHttpHRHRegister();
DetectLuajitRegister(); DetectLuajitRegister();
DetectIPRepRegister(); DetectIPRepRegister();
DetectDnsQueryRegister();
uint8_t i = 0; uint8_t i = 0;
for (i = 0; i < DETECT_TBLSIZE; i++) { for (i = 0; i < DETECT_TBLSIZE; i++) {

@ -115,6 +115,8 @@ enum {
DETECT_SM_LIST_FILEMATCH, DETECT_SM_LIST_FILEMATCH,
DETECT_SM_LIST_DNSQUERY_MATCH,
/* list for post match actions: flowbit set, flowint increment, etc */ /* list for post match actions: flowbit set, flowint increment, etc */
DETECT_SM_LIST_POSTMATCH, DETECT_SM_LIST_POSTMATCH,
@ -1122,6 +1124,8 @@ enum {
DETECT_LUAJIT, DETECT_LUAJIT,
DETECT_IPREP, DETECT_IPREP,
DETECT_AL_DNS_QUERY,
/* make sure this stays last */ /* make sure this stays last */
DETECT_TBLSIZE, DETECT_TBLSIZE,
}; };

Loading…
Cancel
Save