detect/dns: move keywords to rust

Ticket: 7529
Ticket: 3725

Adds url for dns.opcode on the way
pull/13053/head
Philippe Antoine 2 years ago committed by Victor Julien
parent bb9b8d2460
commit 9814b698c8

@ -35,7 +35,7 @@ pub mod tojson;
pub mod vlan; pub mod vlan;
pub mod datasets; pub mod datasets;
use std::os::raw::{c_int, c_void}; use std::os::raw::{c_char, c_int, c_void};
use suricata_sys::sys::AppProto; use suricata_sys::sys::AppProto;
@ -106,6 +106,7 @@ extern "C" {
) -> *mut c_void, ) -> *mut c_void,
) -> c_int; ) -> c_int;
pub fn DetectHelperKeywordRegister(kw: *const SCSigTableElmt) -> c_int; pub fn DetectHelperKeywordRegister(kw: *const SCSigTableElmt) -> c_int;
pub fn DetectHelperKeywordAliasRegister(kwid: c_int, alias: *const c_char);
pub fn DetectHelperBufferRegister( pub fn DetectHelperBufferRegister(
name: *const libc::c_char, alproto: AppProto, toclient: bool, toserver: bool, name: *const libc::c_char, alproto: AppProto, toclient: bool, toserver: bool,
) -> c_int; ) -> c_int;

@ -15,17 +15,29 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use super::dns::DNSTransaction; use super::dns::{DNSTransaction, ALPROTO_DNS};
use crate::detect::uint::{
detect_match_uint, DetectUintData, SCDetectU16Free, SCDetectU16Parse, SCDetectU8Free,
SCDetectU8Parse,
};
use crate::detect::{
DetectBufferSetActiveList, DetectHelperBufferRegister, DetectHelperGetMultiData,
DetectHelperKeywordAliasRegister, DetectHelperKeywordRegister,
DetectHelperMultiBufferProgressMpmRegister, DetectSignatureSetAppProto, SCSigTableElmt,
SigMatchAppendSMToList, SIGMATCH_INFO_STICKY_BUFFER, SIGMATCH_NOOPT,
};
use crate::direction::Direction; use crate::direction::Direction;
use crate::detect::uint::{detect_match_uint, DetectUintData}; use std::os::raw::{c_int, c_void};
/// Perform the DNS opcode match. /// Perform the DNS opcode match.
/// ///
/// 1 will be returned on match, otherwise 0 will be returned. /// 1 will be returned on match, otherwise 0 will be returned.
#[no_mangle] unsafe extern "C" fn dns_opcode_match(
pub extern "C" fn SCDnsDetectOpcodeMatch( _de: *mut c_void, _f: *mut c_void, flags: u8, _state: *mut c_void, tx: *mut c_void,
tx: &mut DNSTransaction, detect: &mut DetectUintData<u8>, flags: u8, _sig: *const c_void, ctx: *const c_void,
) -> u8 { ) -> c_int {
let tx = cast_pointer!(tx, DNSTransaction);
let ctx = cast_pointer!(ctx, DetectUintData<u8>);
let header_flags = if flags & Direction::ToServer as u8 != 0 { let header_flags = if flags & Direction::ToServer as u8 != 0 {
if let Some(request) = &tx.request { if let Some(request) = &tx.request {
request.header.flags request.header.flags
@ -44,7 +56,7 @@ pub extern "C" fn SCDnsDetectOpcodeMatch(
}; };
let opcode = ((header_flags >> 11) & 0xf) as u8; let opcode = ((header_flags >> 11) & 0xf) as u8;
if detect_match_uint(detect, opcode) { if detect_match_uint(ctx, opcode) {
return 1; return 1;
} }
return 0; return 0;
@ -53,10 +65,12 @@ pub extern "C" fn SCDnsDetectOpcodeMatch(
/// Perform the DNS rcode match. /// Perform the DNS rcode match.
/// ///
/// 1 will be returned on match, otherwise 0 will be returned. /// 1 will be returned on match, otherwise 0 will be returned.
#[no_mangle] unsafe extern "C" fn dns_rcode_match(
pub extern "C" fn SCDnsDetectRcodeMatch( _de: *mut c_void, _f: *mut c_void, flags: u8, _state: *mut c_void, tx: *mut c_void,
tx: &mut DNSTransaction, detect: &mut DetectUintData<u8>, flags: u8, _sig: *const c_void, ctx: *const c_void,
) -> u8 { ) -> c_int {
let tx = cast_pointer!(tx, DNSTransaction);
let ctx = cast_pointer!(ctx, DetectUintData<u8>);
let header_flags = if flags & Direction::ToServer as u8 != 0 { let header_flags = if flags & Direction::ToServer as u8 != 0 {
if let Some(request) = &tx.request { if let Some(request) = &tx.request {
request.header.flags request.header.flags
@ -71,7 +85,7 @@ pub extern "C" fn SCDnsDetectRcodeMatch(
let rcode = (header_flags & 0xf) as u8; let rcode = (header_flags & 0xf) as u8;
if detect_match_uint(detect, rcode) { if detect_match_uint(ctx, rcode) {
return 1; return 1;
} }
return 0; return 0;
@ -79,14 +93,17 @@ pub extern "C" fn SCDnsDetectRcodeMatch(
/// Perform the DNS rrtype match. /// Perform the DNS rrtype match.
/// 1 will be returned on match, otherwise 0 will be returned. /// 1 will be returned on match, otherwise 0 will be returned.
#[no_mangle] unsafe extern "C" fn dns_rrtype_match(
pub extern "C" fn SCDnsDetectRrtypeMatch( _de: *mut c_void, _f: *mut c_void, flags: u8, _state: *mut c_void, tx: *mut c_void,
tx: &mut DNSTransaction, detect: &mut DetectUintData<u16>, flags: u8, _sig: *const c_void, ctx: *const c_void,
) -> u16 { ) -> c_int {
let tx = cast_pointer!(tx, DNSTransaction);
let ctx = cast_pointer!(ctx, DetectUintData<u16>);
if flags & Direction::ToServer as u8 != 0 { if flags & Direction::ToServer as u8 != 0 {
if let Some(request) = &tx.request { if let Some(request) = &tx.request {
for i in 0..request.queries.len() { for i in 0..request.queries.len() {
if detect_match_uint(detect, request.queries[i].rrtype) { if detect_match_uint(ctx, request.queries[i].rrtype) {
return 1; return 1;
} }
} }
@ -94,7 +111,7 @@ pub extern "C" fn SCDnsDetectRrtypeMatch(
} else if flags & Direction::ToClient as u8 != 0 { } else if flags & Direction::ToClient as u8 != 0 {
if let Some(response) = &tx.response { if let Some(response) = &tx.response {
for i in 0..response.answers.len() { for i in 0..response.answers.len() {
if detect_match_uint(detect, response.answers[i].rrtype) { if detect_match_uint(ctx, response.answers[i].rrtype) {
return 1; return 1;
} }
} }
@ -103,6 +120,342 @@ pub extern "C" fn SCDnsDetectRrtypeMatch(
return 0; return 0;
} }
static mut G_DNS_ANSWER_NAME_BUFFER_ID: c_int = 0;
static mut G_DNS_QUERY_NAME_BUFFER_ID: c_int = 0;
static mut G_DNS_QUERY_BUFFER_ID: c_int = 0;
static mut G_DNS_OPCODE_KW_ID: c_int = 0;
static mut G_DNS_OPCODE_BUFFER_ID: c_int = 0;
static mut G_DNS_RCODE_KW_ID: c_int = 0;
static mut G_DNS_RCODE_BUFFER_ID: c_int = 0;
static mut G_DNS_RRTYPE_KW_ID: c_int = 0;
static mut G_DNS_RRTYPE_BUFFER_ID: c_int = 0;
unsafe extern "C" fn dns_opcode_setup(
de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
) -> c_int {
if DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0 {
return -1;
}
let ctx = SCDetectU8Parse(raw) as *mut c_void;
if ctx.is_null() {
return -1;
}
if SigMatchAppendSMToList(de, s, G_DNS_OPCODE_KW_ID, ctx, G_DNS_OPCODE_BUFFER_ID).is_null() {
dns_opcode_free(std::ptr::null_mut(), ctx);
return -1;
}
return 0;
}
unsafe extern "C" fn dns_opcode_free(_de: *mut c_void, ctx: *mut c_void) {
// Just unbox...
let ctx = cast_pointer!(ctx, DetectUintData<u8>);
SCDetectU8Free(ctx);
}
unsafe extern "C" fn dns_rcode_setup(
de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
) -> c_int {
if DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0 {
return -1;
}
let ctx = SCDetectU8Parse(raw) as *mut c_void;
if ctx.is_null() {
return -1;
}
if SigMatchAppendSMToList(de, s, G_DNS_RCODE_KW_ID, ctx, G_DNS_RCODE_BUFFER_ID).is_null() {
dns_rcode_free(std::ptr::null_mut(), ctx);
return -1;
}
return 0;
}
unsafe extern "C" fn dns_rcode_free(_de: *mut c_void, ctx: *mut c_void) {
// Just unbox...
let ctx = cast_pointer!(ctx, DetectUintData<u8>);
SCDetectU8Free(ctx);
}
unsafe extern "C" fn dns_rrtype_setup(
de: *mut c_void, s: *mut c_void, raw: *const libc::c_char,
) -> c_int {
if DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0 {
return -1;
}
let ctx = SCDetectU16Parse(raw) as *mut c_void;
if ctx.is_null() {
return -1;
}
if SigMatchAppendSMToList(de, s, G_DNS_RRTYPE_KW_ID, ctx, G_DNS_RRTYPE_BUFFER_ID).is_null() {
dns_rrtype_free(std::ptr::null_mut(), ctx);
return -1;
}
return 0;
}
unsafe extern "C" fn dns_rrtype_free(_de: *mut c_void, ctx: *mut c_void) {
// Just unbox...
let ctx = cast_pointer!(ctx, DetectUintData<u16>);
SCDetectU16Free(ctx);
}
unsafe extern "C" fn dns_detect_answer_name_setup(
de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char,
) -> c_int {
if DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0 {
return -1;
}
if DetectBufferSetActiveList(de, s, G_DNS_ANSWER_NAME_BUFFER_ID) < 0 {
return -1;
}
return 0;
}
/// Get the DNS response answer name and index i.
unsafe extern "C" fn dns_tx_get_answer_name(
tx: *const c_void, flags: u8, i: u32, buf: *mut *const u8, len: *mut u32,
) -> bool {
let tx = cast_pointer!(tx, DNSTransaction);
let answers = if flags & Direction::ToClient as u8 != 0 {
tx.response.as_ref().map(|response| &response.answers)
} else {
tx.request.as_ref().map(|request| &request.answers)
};
let index = i as usize;
if let Some(answers) = answers {
if let Some(answer) = answers.get(index) {
if !answer.name.value.is_empty() {
*buf = answer.name.value.as_ptr();
*len = answer.name.value.len() as u32;
return true;
}
}
}
false
}
unsafe extern "C" fn dns_answer_name_get_data_wrapper(
de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8,
tx: *const c_void, list_id: c_int, local_id: u32,
) -> *mut c_void {
return DetectHelperGetMultiData(
de,
transforms,
flow,
flow_flags,
tx,
list_id,
local_id,
dns_tx_get_answer_name,
);
}
unsafe extern "C" fn dns_detect_query_name_setup(
de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char,
) -> c_int {
if DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0 {
return -1;
}
if DetectBufferSetActiveList(de, s, G_DNS_QUERY_NAME_BUFFER_ID) < 0 {
return -1;
}
return 0;
}
/// Get the DNS response answer name and index i.
unsafe extern "C" fn dns_tx_get_query_name(
tx: *const c_void, flags: u8, i: u32, buf: *mut *const u8, len: *mut u32,
) -> bool {
let tx = cast_pointer!(tx, DNSTransaction);
let queries = if flags & Direction::ToClient as u8 != 0 {
tx.response.as_ref().map(|response| &response.queries)
} else {
tx.request.as_ref().map(|request| &request.queries)
};
let index = i as usize;
if let Some(queries) = queries {
if let Some(query) = queries.get(index) {
if !query.name.value.is_empty() {
*buf = query.name.value.as_ptr();
*len = query.name.value.len() as u32;
return true;
}
}
}
false
}
unsafe extern "C" fn dns_tx_get_query(
tx: *const c_void, _flags: u8, i: u32, buf: *mut *const u8, len: *mut u32,
) -> bool {
return dns_tx_get_query_name(tx, Direction::ToServer as u8, i, buf, len);
}
unsafe extern "C" fn dns_detect_query_setup(
de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char,
) -> c_int {
if DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0 {
return -1;
}
if DetectBufferSetActiveList(de, s, G_DNS_QUERY_BUFFER_ID) < 0 {
return -1;
}
return 0;
}
unsafe extern "C" fn dns_query_name_get_data_wrapper(
de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8,
tx: *const c_void, list_id: c_int, local_id: u32,
) -> *mut c_void {
return DetectHelperGetMultiData(
de,
transforms,
flow,
flow_flags,
tx,
list_id,
local_id,
dns_tx_get_query_name,
);
}
unsafe extern "C" fn dns_query_get_data_wrapper(
de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8,
tx: *const c_void, list_id: c_int, local_id: u32,
) -> *mut c_void {
return DetectHelperGetMultiData(
de,
transforms,
flow,
flow_flags,
tx,
list_id,
local_id,
dns_tx_get_query,
);
}
#[no_mangle]
pub unsafe extern "C" fn SCDetectDNSRegister() {
let kw = SCSigTableElmt {
name: b"dns.answer.name\0".as_ptr() as *const libc::c_char,
desc: b"DNS answer name sticky buffer\0".as_ptr() as *const libc::c_char,
url: b"/rules/dns-keywords.html#dns-answer-name\0".as_ptr() as *const libc::c_char,
Setup: dns_detect_answer_name_setup,
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
AppLayerTxMatch: None,
Free: None,
};
let _g_dns_answer_name_kw_id = DetectHelperKeywordRegister(&kw);
G_DNS_ANSWER_NAME_BUFFER_ID = DetectHelperMultiBufferProgressMpmRegister(
b"dns.answer.name\0".as_ptr() as *const libc::c_char,
b"dns answer name\0".as_ptr() as *const libc::c_char,
ALPROTO_DNS,
true,
/* Register also in the TO_SERVER direction, even though this is not
normal, it could be provided as part of a request. */
true,
dns_answer_name_get_data_wrapper,
1, // response complete
);
let kw = SCSigTableElmt {
name: b"dns.opcode\0".as_ptr() as *const libc::c_char,
desc: b"Match the DNS header opcode flag.\0".as_ptr() as *const libc::c_char,
url: b"rules/dns-keywords.html#dns-opcode\0".as_ptr() as *const libc::c_char,
AppLayerTxMatch: Some(dns_opcode_match),
Setup: dns_opcode_setup,
Free: Some(dns_opcode_free),
flags: 0,
};
G_DNS_OPCODE_KW_ID = DetectHelperKeywordRegister(&kw);
G_DNS_OPCODE_BUFFER_ID = DetectHelperBufferRegister(
b"dns.opcode\0".as_ptr() as *const libc::c_char,
ALPROTO_DNS,
true,
true,
);
let kw = SCSigTableElmt {
name: b"dns.query.name\0".as_ptr() as *const libc::c_char,
desc: b"DNS query name sticky buffer\0".as_ptr() as *const libc::c_char,
url: b"/rules/dns-keywords.html#dns-query-name\0".as_ptr() as *const libc::c_char,
Setup: dns_detect_query_name_setup,
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
AppLayerTxMatch: None,
Free: None,
};
let _g_dns_query_name_kw_id = DetectHelperKeywordRegister(&kw);
G_DNS_QUERY_NAME_BUFFER_ID = DetectHelperMultiBufferProgressMpmRegister(
b"dns.query.name\0".as_ptr() as *const libc::c_char,
b"dns query name\0".as_ptr() as *const libc::c_char,
ALPROTO_DNS,
true,
/* Register in both directions as the query is usually echoed back
in the response. */
true,
dns_query_name_get_data_wrapper,
1, // request or response complete
);
let kw = SCSigTableElmt {
name: b"dns.rcode\0".as_ptr() as *const libc::c_char,
desc: b"Match the DNS header rcode flag.\0".as_ptr() as *const libc::c_char,
url: b"rules/dns-keywords.html#dns-rcode\0".as_ptr() as *const libc::c_char,
AppLayerTxMatch: Some(dns_rcode_match),
Setup: dns_rcode_setup,
Free: Some(dns_rcode_free),
flags: 0,
};
G_DNS_RCODE_KW_ID = DetectHelperKeywordRegister(&kw);
G_DNS_RCODE_BUFFER_ID = DetectHelperBufferRegister(
b"dns.rcode\0".as_ptr() as *const libc::c_char,
ALPROTO_DNS,
true,
true,
);
let kw = SCSigTableElmt {
name: b"dns.rrtype\0".as_ptr() as *const libc::c_char,
desc: b"Match the DNS rrtype in message body.\0".as_ptr() as *const libc::c_char,
url: b"rules/dns-keywords.html#dns-rrtype\0".as_ptr() as *const libc::c_char,
AppLayerTxMatch: Some(dns_rrtype_match),
Setup: dns_rrtype_setup,
Free: Some(dns_rrtype_free),
flags: 0,
};
G_DNS_RRTYPE_KW_ID = DetectHelperKeywordRegister(&kw);
G_DNS_RRTYPE_BUFFER_ID = DetectHelperBufferRegister(
b"dns.rrtype\0".as_ptr() as *const libc::c_char,
ALPROTO_DNS,
true,
true,
);
let kw = SCSigTableElmt {
name: b"dns.query\0".as_ptr() as *const libc::c_char,
desc: b"sticky buffer to match DNS query-buffer\0".as_ptr() as *const libc::c_char,
url: b"/rules/dns-keywords.html#dns-query\0".as_ptr() as *const libc::c_char,
Setup: dns_detect_query_setup,
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
AppLayerTxMatch: None,
Free: None,
};
let g_dns_query_name_kw_id = DetectHelperKeywordRegister(&kw);
DetectHelperKeywordAliasRegister(
g_dns_query_name_kw_id,
b"dns_query\0".as_ptr() as *const libc::c_char,
);
G_DNS_QUERY_BUFFER_ID = DetectHelperMultiBufferProgressMpmRegister(
b"dns_query\0".as_ptr() as *const libc::c_char,
b"dns request query\0".as_ptr() as *const libc::c_char,
ALPROTO_DNS,
false, // only toserver
true,
dns_query_get_data_wrapper, // reuse, will be called only toserver
1, // request complete
);
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;

@ -116,7 +116,7 @@ pub const DNS_RCODE_BADNAME: u16 = 20;
pub const DNS_RCODE_BADALG: u16 = 21; pub const DNS_RCODE_BADALG: u16 = 21;
pub const DNS_RCODE_BADTRUNC: u16 = 22; pub const DNS_RCODE_BADTRUNC: u16 = 22;
static mut ALPROTO_DNS: AppProto = ALPROTO_UNKNOWN; pub(super) static mut ALPROTO_DNS: AppProto = ALPROTO_UNKNOWN;
#[derive(AppLayerFrameType)] #[derive(AppLayerFrameType)]
enum DnsFrameType { enum DnsFrameType {

@ -113,11 +113,7 @@ noinst_HEADERS = \
detect-distance.h \ detect-distance.h \
detect-dnp3.h \ detect-dnp3.h \
detect-dns-name.h \ detect-dns-name.h \
detect-dns-opcode.h \
detect-dns-rcode.h \
detect-dns-response.h \ detect-dns-response.h \
detect-dns-rrtype.h \
detect-dns-query.h \
detect-dsize.h \ detect-dsize.h \
detect-engine-address.h \ detect-engine-address.h \
detect-engine-address-ipv4.h \ detect-engine-address-ipv4.h \
@ -702,11 +698,7 @@ libsuricata_c_a_SOURCES = \
detect-distance.c \ detect-distance.c \
detect-dnp3.c \ detect-dnp3.c \
detect-dns-name.c \ detect-dns-name.c \
detect-dns-opcode.c \
detect-dns-rcode.c \
detect-dns-response.c \ detect-dns-response.c \
detect-dns-rrtype.c \
detect-dns-query.c \
detect-dsize.c \ detect-dsize.c \
detect-engine-address.c \ detect-engine-address.c \
detect-engine-address-ipv4.c \ detect-engine-address-ipv4.c \

@ -1,89 +0,0 @@
/* Copyright (C) 2019 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.
*/
#include "suricata-common.h"
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-engine-uint.h"
#include "detect-dns-opcode.h"
#include "rust.h"
static int dns_opcode_list_id = 0;
static void DetectDnsOpcodeFree(DetectEngineCtx *, void *ptr);
static int DetectDnsOpcodeSetup(DetectEngineCtx *de_ctx, Signature *s,
const char *str)
{
SCEnter();
if (DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0) {
return -1;
}
void *detect = DetectU8Parse(str);
if (detect == NULL) {
SCLogError("failed to parse dns.opcode: %s", str);
return -1;
}
if (SigMatchAppendSMToList(
de_ctx, s, DETECT_DNS_OPCODE, (SigMatchCtx *)detect, dns_opcode_list_id) == NULL) {
goto error;
}
SCReturnInt(0);
error:
DetectDnsOpcodeFree(de_ctx, detect);
SCReturnInt(-1);
}
static void DetectDnsOpcodeFree(DetectEngineCtx *de_ctx, void *ptr)
{
SCEnter();
if (ptr != NULL) {
SCDetectU8Free(ptr);
}
SCReturn;
}
static int DetectDnsOpcodeMatch(DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state, void *txv, const Signature *s,
const SigMatchCtx *ctx)
{
return SCDnsDetectOpcodeMatch(txv, (void *)ctx, flags);
}
void DetectDnsOpcodeRegister(void)
{
sigmatch_table[DETECT_DNS_OPCODE].name = "dns.opcode";
sigmatch_table[DETECT_DNS_OPCODE].desc = "Match the DNS header opcode flag.";
sigmatch_table[DETECT_DNS_OPCODE].Setup = DetectDnsOpcodeSetup;
sigmatch_table[DETECT_DNS_OPCODE].Free = DetectDnsOpcodeFree;
sigmatch_table[DETECT_DNS_OPCODE].Match = NULL;
sigmatch_table[DETECT_DNS_OPCODE].AppLayerTxMatch = DetectDnsOpcodeMatch;
DetectAppLayerInspectEngineRegister(
"dns.opcode", ALPROTO_DNS, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL);
DetectAppLayerInspectEngineRegister(
"dns.opcode", ALPROTO_DNS, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL);
dns_opcode_list_id = DetectBufferTypeGetByName("dns.opcode");
}

@ -1,23 +0,0 @@
/* Copyright (C) 2019 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.
*/
#ifndef SURICATA_DETECT_DNS_OPCODE_H
#define SURICATA_DETECT_DNS_OPCODE_H
void DetectDnsOpcodeRegister(void);
#endif /* SURICATA_DETECT_DNS_OPCODE_H */

@ -1,131 +0,0 @@
/* Copyright (C) 2013-2023 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 "decode.h"
#include "detect.h"
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-engine-build.h"
#include "detect-engine-mpm.h"
#include "detect-engine-prefilter.h"
#include "detect-engine-content-inspection.h"
#include "detect-content.h"
#include "detect-pcre.h"
#include "flow.h"
#include "flow-util.h"
#include "flow-var.h"
#include "util-debug.h"
#include "util-spm.h"
#include "util-print.h"
#include "stream-tcp.h"
#include "app-layer.h"
#include "app-layer-parser.h"
#include "detect-dns-query.h"
#include "util-profiling.h"
#include "rust.h"
static int DetectDnsQuerySetup(DetectEngineCtx *, Signature *, const char *);
static int g_dns_query_buffer_id = 0;
static InspectionBuffer *DnsQueryGetData(DetectEngineThreadCtx *det_ctx,
const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv,
int list_id, uint32_t local_id)
{
SCEnter();
InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id);
if (buffer == NULL)
return NULL;
if (buffer->initialized)
return buffer;
const uint8_t *data;
uint32_t data_len;
if (SCDnsTxGetQueryName(txv, false, local_id, &data, &data_len) == 0) {
InspectionBufferSetupMultiEmpty(buffer);
return NULL;
}
InspectionBufferSetupMulti(det_ctx, buffer, transforms, data, data_len);
buffer->flags = DETECT_CI_FLAGS_SINGLE;
SCReturnPtr(buffer, "InspectionBuffer");
}
/**
* \brief Registration function for keyword: dns_query
*/
void DetectDnsQueryRegister (void)
{
sigmatch_table[DETECT_DNS_QUERY].name = "dns.query";
sigmatch_table[DETECT_DNS_QUERY].alias = "dns_query";
sigmatch_table[DETECT_DNS_QUERY].desc = "sticky buffer to match DNS query-buffer";
sigmatch_table[DETECT_DNS_QUERY].url = "/rules/dns-keywords.html#dns-query";
sigmatch_table[DETECT_DNS_QUERY].Setup = DetectDnsQuerySetup;
sigmatch_table[DETECT_DNS_QUERY].flags |= SIGMATCH_NOOPT;
sigmatch_table[DETECT_DNS_QUERY].flags |= SIGMATCH_INFO_STICKY_BUFFER;
DetectAppLayerMultiRegister(
"dns_query", ALPROTO_DNS, SIG_FLAG_TOSERVER, 1, DnsQueryGetData, 2, 1);
DetectBufferTypeSetDescriptionByName("dns_query",
"dns request query");
DetectBufferTypeSupportsMultiInstance("dns_query");
g_dns_query_buffer_id = DetectBufferTypeGetByName("dns_query");
}
/**
* \brief setup the dns_query sticky buffer 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, const char *str)
{
if (DetectBufferSetActiveList(de_ctx, s, g_dns_query_buffer_id) < 0)
return -1;
if (DetectSignatureSetAppProto(s, ALPROTO_DNS) < 0)
return -1;
return 0;
}

@ -1,29 +0,0 @@
/* 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 SURICATA_DETECT_DNS_QUERY_H
#define SURICATA_DETECT_DNS_QUERY_H
void DetectDnsQueryRegister (void);
#endif /* SURICATA_DETECT_DNS_QUERY_H */

@ -1,85 +0,0 @@
/* Copyright (C) 2024 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.
*/
#include "suricata-common.h"
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-dns-rcode.h"
#include "rust.h"
#include "detect-engine-uint.h"
static int dns_rcode_list_id = 0;
static void DetectDnsRcodeFree(DetectEngineCtx *, void *ptr);
static int DetectDnsRcodeSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
{
SCEnter();
if (DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0) {
SCReturnInt(-1);
}
void *detect = DetectU8Parse(str);
if (detect == NULL) {
SCLogError("failed to parse dns.rcode: %s", str);
SCReturnInt(-1);
}
if (SigMatchAppendSMToList(
de_ctx, s, DETECT_DNS_RCODE, (SigMatchCtx *)detect, dns_rcode_list_id) == NULL) {
DetectDnsRcodeFree(de_ctx, detect);
SCReturnInt(-1);
}
SCReturnInt(0);
}
static void DetectDnsRcodeFree(DetectEngineCtx *de_ctx, void *ptr)
{
SCEnter();
if (ptr != NULL) {
SCDetectU8Free(ptr);
}
SCReturn;
}
static int DetectDnsRcodeMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state,
void *txv, const Signature *s, const SigMatchCtx *ctx)
{
return SCDnsDetectRcodeMatch(txv, (void *)ctx, flags);
}
void DetectDnsRcodeRegister(void)
{
sigmatch_table[DETECT_DNS_RCODE].name = "dns.rcode";
sigmatch_table[DETECT_DNS_RCODE].desc = "Match the DNS header rcode flag.";
sigmatch_table[DETECT_DNS_RCODE].url = "/rules/dns-keywords.html#dns-rcode";
sigmatch_table[DETECT_DNS_RCODE].Setup = DetectDnsRcodeSetup;
sigmatch_table[DETECT_DNS_RCODE].Free = DetectDnsRcodeFree;
sigmatch_table[DETECT_DNS_RCODE].Match = NULL;
sigmatch_table[DETECT_DNS_RCODE].AppLayerTxMatch = DetectDnsRcodeMatch;
DetectAppLayerInspectEngineRegister(
"dns.rcode", ALPROTO_DNS, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL);
DetectAppLayerInspectEngineRegister(
"dns.rcode", ALPROTO_DNS, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL);
dns_rcode_list_id = DetectBufferTypeGetByName("dns.rcode");
}

@ -1,23 +0,0 @@
/* Copyright (C) 2024 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.
*/
#ifndef SURICATA_DETECT_DNS_RCODE_H
#define SURICATA_DETECT_DNS_RCODE_H
void DetectDnsRcodeRegister(void);
#endif /* SURICATA_DETECT_DNS_RCODE_H */

@ -1,85 +0,0 @@
/* Copyright (C) 2024 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.
*/
#include "suricata-common.h"
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-dns-rrtype.h"
#include "rust.h"
#include "detect-engine-uint.h"
static int dns_rrtype_list_id = 0;
static void DetectDnsRrtypeFree(DetectEngineCtx *, void *ptr);
static int DetectDnsRrtypeSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
{
SCEnter();
if (DetectSignatureSetAppProto(s, ALPROTO_DNS) != 0) {
SCReturnInt(-1);
}
void *detect = DetectU16Parse(str);
if (detect == NULL) {
SCLogError("failed to parse dns.rrtype: %s", str);
SCReturnInt(-1);
}
if (SigMatchAppendSMToList(
de_ctx, s, DETECT_DNS_RRTYPE, (SigMatchCtx *)detect, dns_rrtype_list_id) == NULL) {
DetectDnsRrtypeFree(de_ctx, detect);
SCReturnInt(-1);
}
SCReturnInt(0);
}
static void DetectDnsRrtypeFree(DetectEngineCtx *de_ctx, void *ptr)
{
SCEnter();
if (ptr != NULL) {
SCDetectU16Free(ptr);
}
SCReturn;
}
static int DetectDnsRrtypeMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state,
void *txv, const Signature *s, const SigMatchCtx *ctx)
{
return SCDnsDetectRrtypeMatch(txv, (void *)ctx, flags);
}
void DetectDnsRrtypeRegister(void)
{
sigmatch_table[DETECT_DNS_RRTYPE].name = "dns.rrtype";
sigmatch_table[DETECT_DNS_RRTYPE].desc = "Match the DNS rrtype in message body.";
sigmatch_table[DETECT_DNS_RRTYPE].url = "/rules/dns-keywords.html#dns-rrtype";
sigmatch_table[DETECT_DNS_RRTYPE].Setup = DetectDnsRrtypeSetup;
sigmatch_table[DETECT_DNS_RRTYPE].Free = DetectDnsRrtypeFree;
sigmatch_table[DETECT_DNS_RRTYPE].Match = NULL;
sigmatch_table[DETECT_DNS_RRTYPE].AppLayerTxMatch = DetectDnsRrtypeMatch;
DetectAppLayerInspectEngineRegister(
"dns.rrtype", ALPROTO_DNS, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL);
DetectAppLayerInspectEngineRegister(
"dns.rrtype", ALPROTO_DNS, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL);
dns_rrtype_list_id = DetectBufferTypeGetByName("dns.rrtype");
}

@ -1,23 +0,0 @@
/* Copyright (C) 2024 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.
*/
#ifndef SURICATA_DETECT_DNS_RRTYPE_H
#define SURICATA_DETECT_DNS_RRTYPE_H
void DetectDnsRrtypeRegister(void);
#endif /* SURICATA_DETECT_DNS_RRTYPE_H */

@ -141,6 +141,11 @@ int DetectHelperKeywordRegister(const SCSigTableElmt *kw)
return keyword_id; return keyword_id;
} }
void DetectHelperKeywordAliasRegister(int kwid, const char *alias)
{
sigmatch_table[kwid].alias = alias;
}
int DetectHelperTransformRegister(const SCTransformTableElmt *kw) int DetectHelperTransformRegister(const SCTransformTableElmt *kw)
{ {
int transform_id = SCDetectHelperNewKeywordId(); int transform_id = SCDetectHelperNewKeywordId();

@ -31,6 +31,7 @@
int SCDetectHelperNewKeywordId(void); int SCDetectHelperNewKeywordId(void);
int DetectHelperKeywordRegister(const SCSigTableElmt *kw); int DetectHelperKeywordRegister(const SCSigTableElmt *kw);
void DetectHelperKeywordAliasRegister(int kwid, const char *alias);
int DetectHelperBufferRegister(const char *name, AppProto alproto, bool toclient, bool toserver); int DetectHelperBufferRegister(const char *name, AppProto alproto, bool toclient, bool toserver);
typedef bool (*SimpleGetTxBuffer)(void *, uint8_t, const uint8_t **, uint32_t *); typedef bool (*SimpleGetTxBuffer)(void *, uint8_t, const uint8_t **, uint32_t *);

@ -47,10 +47,6 @@
#include "detect-engine-payload.h" #include "detect-engine-payload.h"
#include "detect-engine-dcepayload.h" #include "detect-engine-dcepayload.h"
#include "detect-dns-opcode.h"
#include "detect-dns-rcode.h"
#include "detect-dns-rrtype.h"
#include "detect-dns-query.h"
#include "detect-dns-name.h" #include "detect-dns-name.h"
#include "detect-dns-response.h" #include "detect-dns-response.h"
#include "detect-tls-sni.h" #include "detect-tls-sni.h"
@ -566,10 +562,6 @@ void SigTableSetup(void)
DetectHttpStatCodeRegister(); DetectHttpStatCodeRegister();
DetectHttp2Register(); DetectHttp2Register();
DetectDnsQueryRegister();
DetectDnsOpcodeRegister();
DetectDnsRcodeRegister();
DetectDnsRrtypeRegister();
DetectDnsNameRegister(); DetectDnsNameRegister();
DetectDnsResponseRegister(); DetectDnsResponseRegister();
DetectModbusRegister(); DetectModbusRegister();
@ -763,6 +755,7 @@ void SigTableSetup(void)
SCDetectTemplateRegister(); SCDetectTemplateRegister();
SCDetectLdapRegister(); SCDetectLdapRegister();
SCDetectSdpRegister(); SCDetectSdpRegister();
SCDetectDNSRegister();
for (size_t i = 0; i < preregistered_callbacks_nb; i++) { for (size_t i = 0; i < preregistered_callbacks_nb; i++) {
PreregisteredCallbacks[i](); PreregisteredCallbacks[i]();

@ -242,11 +242,7 @@ enum DetectKeywordId {
DETECT_L3PROTO, DETECT_L3PROTO,
DETECT_IPREP, DETECT_IPREP,
DETECT_DNS_QUERY,
DETECT_DNS_OPCODE,
DETECT_DNS_RCODE,
DETECT_DNS_RESPONSE, DETECT_DNS_RESPONSE,
DETECT_DNS_RRTYPE,
DETECT_TLS_SNI, DETECT_TLS_SNI,
DETECT_TLS_CERTS, DETECT_TLS_CERTS,
DETECT_TLS_CERT_ISSUER, DETECT_TLS_CERT_ISSUER,

Loading…
Cancel
Save