detect/ssh: move ssh.hassh to rust

Introduces helper SCDetectRegisterBufferLowerMd5Callbacks
pull/14712/head
Philippe Antoine 8 months ago committed by Victor Julien
parent 14c78d8405
commit 2cf9a327d5

@ -26,7 +26,8 @@ use std::ptr;
use suricata_sys::sys::{
DetectEngineCtx, SCDetectBufferSetActiveList, SCDetectHelperBufferProgressMpmRegister,
SCDetectHelperKeywordAliasRegister, SCDetectHelperKeywordRegister,
SCDetectSignatureSetAppProto, SCSigMatchSilentErrorEnabled, SCSigTableAppLiteElmt, Signature,
SCDetectRegisterBufferLowerMd5Callbacks, SCDetectSignatureSetAppProto,
SCSigMatchSilentErrorEnabled, SCSigTableAppLiteElmt, Signature,
};
#[no_mangle]
@ -88,8 +89,8 @@ pub unsafe extern "C" fn SCSshTxGetSoftware(
#[no_mangle]
pub unsafe extern "C" fn SCSshTxGetHassh(
tx: *mut std::os::raw::c_void, buffer: *mut *const u8, buffer_len: *mut u32, direction: u8,
) -> u8 {
tx: *const c_void, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32,
) -> bool {
let tx = cast_pointer!(tx, SSHTransaction);
match direction.into() {
Direction::ToServer => {
@ -97,7 +98,7 @@ pub unsafe extern "C" fn SCSshTxGetHassh(
if !m.is_empty() {
*buffer = m.as_ptr();
*buffer_len = m.len() as u32;
return 1;
return true;
}
}
Direction::ToClient => {
@ -105,14 +106,14 @@ pub unsafe extern "C" fn SCSshTxGetHassh(
if !m.is_empty() {
*buffer = m.as_ptr();
*buffer_len = m.len() as u32;
return 1;
return true;
}
}
}
*buffer = ptr::null();
*buffer_len = 0;
return 0;
return false;
}
#[no_mangle]
@ -212,6 +213,50 @@ unsafe extern "C" fn ssh_hassh_server_string_setup(
return 0;
}
unsafe extern "C" fn ssh_hassh_setup(
de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
) -> c_int {
if SCDetectSignatureSetAppProto(s, ALPROTO_SSH) != 0 {
return -1;
}
if SCDetectBufferSetActiveList(de, s, G_SSH_HASSH_BUFFER_ID) < 0 {
return -1;
}
/* try to enable Hassh */
SCSshEnableHassh();
/* Check if Hassh is disabled */
if !SCSshHasshIsEnabled() {
if !SCSigMatchSilentErrorEnabled(de, DETECT_SSH_HASSH) {
SCLogError!("hassh support is not enabled");
}
return -2;
}
return 0;
}
unsafe extern "C" fn ssh_hassh_server_setup(
de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
) -> c_int {
if SCDetectSignatureSetAppProto(s, ALPROTO_SSH) != 0 {
return -1;
}
if SCDetectBufferSetActiveList(de, s, G_SSH_HASSH_SRV_BUFFER_ID) < 0 {
return -1;
}
/* try to enable Hassh */
SCSshEnableHassh();
/* Check if Hassh is disabled */
if !SCSshHasshIsEnabled() {
if !SCSigMatchSilentErrorEnabled(de, DETECT_SSH_HASSH_SERVER) {
SCLogError!("hassh support is not enabled");
}
return -2;
}
return 0;
}
unsafe extern "C" fn ssh_software_obsolete_setup(
_de: *mut DetectEngineCtx, _s: *mut Signature, _raw: *const std::os::raw::c_char,
) -> c_int {
@ -230,9 +275,13 @@ static mut G_SSH_SOFTWARE_BUFFER_ID: c_int = 0;
static mut G_SSH_PROTO_BUFFER_ID: c_int = 0;
static mut G_SSH_HASSH_STR_BUFFER_ID: c_int = 0;
static mut G_SSH_HASSH_SRV_STR_BUFFER_ID: c_int = 0;
static mut G_SSH_HASSH_BUFFER_ID: c_int = 0;
static mut G_SSH_HASSH_SRV_BUFFER_ID: c_int = 0;
static mut DETECT_SSH_HASSH_STRING: u16 = 0;
static mut DETECT_SSH_HASSH_SERVER_STRING: u16 = 0;
static mut DETECT_SSH_HASSH: u16 = 0;
static mut DETECT_SSH_HASSH_SERVER: u16 = 0;
#[no_mangle]
pub unsafe extern "C" fn SCDetectSshRegister() {
@ -337,4 +386,46 @@ pub unsafe extern "C" fn SCDetectSshRegister() {
DETECT_SSH_HASSH_SERVER_STRING,
b"ssh-hassh-server-string\0".as_ptr() as *const libc::c_char,
);
let kw = SigTableElmtStickyBuffer {
name: String::from("ssh.hassh"),
desc: String::from("ssh.hassh sticky buffer"),
url: String::from("/rules/ssh-keywords.html#hassh"),
setup: ssh_hassh_setup,
};
DETECT_SSH_HASSH = helper_keyword_register_sticky_buffer(&kw);
G_SSH_HASSH_BUFFER_ID = SCDetectHelperBufferProgressMpmRegister(
b"ssh.hassh\0".as_ptr() as *const libc::c_char,
b"Ssh Client Fingerprinting For Ssh Clients\0".as_ptr() as *const libc::c_char,
ALPROTO_SSH,
STREAM_TOSERVER,
Some(SCSshTxGetHassh),
SSHConnectionState::SshStateBannerDone as c_int,
);
SCDetectHelperKeywordAliasRegister(
DETECT_SSH_HASSH,
b"ssh-hassh\0".as_ptr() as *const libc::c_char,
);
SCDetectRegisterBufferLowerMd5Callbacks(b"ssh.hassh\0".as_ptr() as *const libc::c_char);
let kw = SigTableElmtStickyBuffer {
name: String::from("ssh.hassh.server"),
desc: String::from("ssh.hassh.server sticky buffer"),
url: String::from("/rules/ssh-keywords.html#ssh.hassh.server"),
setup: ssh_hassh_server_setup,
};
DETECT_SSH_HASSH_SERVER = helper_keyword_register_sticky_buffer(&kw);
G_SSH_HASSH_SRV_BUFFER_ID = SCDetectHelperBufferProgressMpmRegister(
b"ssh.hassh.server\0".as_ptr() as *const libc::c_char,
b"Ssh Client Fingerprinting For Ssh Servers\0".as_ptr() as *const libc::c_char,
ALPROTO_SSH,
STREAM_TOCLIENT,
Some(SCSshTxGetHassh),
SSHConnectionState::SshStateBannerDone as c_int,
);
SCDetectHelperKeywordAliasRegister(
DETECT_SSH_HASSH_SERVER,
b"ssh-hassh-server\0".as_ptr() as *const libc::c_char,
);
SCDetectRegisterBufferLowerMd5Callbacks(b"ssh.hassh.server\0".as_ptr() as *const libc::c_char);
}

@ -477,6 +477,9 @@ extern "C" {
kw: *const SCTransformTableElmt,
) -> ::std::os::raw::c_int;
}
extern "C" {
pub fn SCDetectRegisterBufferLowerMd5Callbacks(name: *const ::std::os::raw::c_char);
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct DeStateStoreItem_ {

@ -283,8 +283,6 @@ noinst_HEADERS = \
detect-smb-share.h \
detect-smb-version.h \
detect-smtp.h \
detect-ssh-hassh-server.h \
detect-ssh-hassh.h \
detect-ssl-state.h \
detect-ssl-version.h \
detect-stream_size.h \
@ -877,8 +875,6 @@ libsuricata_c_a_SOURCES = \
detect-smb-share.c \
detect-smb-version.c \
detect-smtp.c \
detect-ssh-hassh-server.c \
detect-ssh-hassh.c \
detect-ssl-state.c \
detect-ssl-version.c \
detect-stream_size.c \

@ -169,3 +169,9 @@ int SCDetectHelperTransformRegister(const SCTransformTableElmt *kw)
return transform_id;
}
void SCDetectRegisterBufferLowerMd5Callbacks(const char *name)
{
DetectBufferTypeRegisterSetupCallback(name, DetectLowerSetupCallback);
DetectBufferTypeRegisterValidateCallback(name, DetectMd5ValidateCallback);
}

@ -93,4 +93,6 @@ int SCDetectHelperMultiBufferProgressMpmRegister(const char *name, const char *d
int SCDetectHelperTransformRegister(const SCTransformTableElmt *kw);
void SCDetectRegisterBufferLowerMd5Callbacks(const char *name);
#endif /* SURICATA_DETECT_ENGINE_HELPER_H */

@ -234,8 +234,6 @@
#include "detect-tls.h"
#include "detect-tls-cert-validity.h"
#include "detect-tls-version.h"
#include "detect-ssh-hassh.h"
#include "detect-ssh-hassh-server.h"
#include "detect-http-stat-code.h"
#include "detect-ssl-version.h"
#include "detect-ssl-state.h"
@ -708,8 +706,6 @@ void SigTableSetup(void)
DetectBsizeRegister();
DetectDetectionFilterRegister();
DetectAsn1Register();
DetectSshHasshRegister();
DetectSshHasshServerRegister();
DetectSslStateRegister();
DetectSslVersionRegister();
DetectByteExtractRegister();

@ -189,8 +189,6 @@ enum DetectKeywordId {
DETECT_HTTP_REQUEST_LINE,
DETECT_HTTP_RESPONSE_LINE,
DETECT_NFS_VERSION,
DETECT_SSH_HASSH,
DETECT_SSH_HASSH_SERVER,
DETECT_SSL_VERSION,
DETECT_SSL_STATE,
DETECT_FILE_DATA,

@ -1,144 +0,0 @@
/* Copyright (C) 2007-2020 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 Vadym Malakhatko <v.malakhatko@sirinsoftware.com>
*/
#include "suricata-common.h"
#include "threads.h"
#include "decode.h"
#include "detect.h"
#include "detect-parse.h"
#include "detect-content.h"
#include "detect-engine.h"
#include "detect-engine-buffer.h"
#include "detect-engine-mpm.h"
#include "detect-engine-state.h"
#include "detect-engine-prefilter.h"
#include "flow.h"
#include "flow-var.h"
#include "flow-util.h"
#include "stream-tcp.h"
#include "util-debug.h"
#include "util-unittest.h"
#include "util-unittest-helper.h"
#include "app-layer.h"
#include "app-layer-parser.h"
#include "app-layer-ssh.h"
#include "detect-ssh-hassh-server.h"
#include "rust.h"
#define KEYWORD_NAME "ssh.hassh.server"
#define KEYWORD_ALIAS "ssh-hassh-server"
#define KEYWORD_DOC "ssh-keywords.html#ssh.hassh.server"
#define BUFFER_NAME "ssh.hassh.server"
#define BUFFER_DESC "Ssh Client Fingerprinting For Ssh Servers"
static int g_ssh_hassh_buffer_id = 0;
static InspectionBuffer *GetSshData(DetectEngineThreadCtx *det_ctx,
const DetectEngineTransforms *transforms, Flow *_f,
const uint8_t flow_flags, void *txv, const int list_id)
{
SCEnter();
InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
if (buffer->inspect == NULL) {
const uint8_t *hasshServer = NULL;
uint32_t b_len = 0;
if (SCSshTxGetHassh(txv, &hasshServer, &b_len, flow_flags) != 1)
return NULL;
if (hasshServer == NULL || b_len == 0) {
SCLogDebug("SSH hassh not set");
return NULL;
}
InspectionBufferSetupAndApplyTransforms(
det_ctx, list_id, buffer, hasshServer, b_len, transforms);
}
return buffer;
}
/**
* \brief this function setup the ssh.hassh.server 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
* \retval -2 on failure that should be silent after the first
*/
static int DetectSshHasshServerSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
{
if (SCDetectBufferSetActiveList(de_ctx, s, g_ssh_hassh_buffer_id) < 0)
return -1;
if (SCDetectSignatureSetAppProto(s, ALPROTO_SSH) < 0)
return -1;
/* try to enable Hassh */
SCSshEnableHassh();
/* Check if Hassh is disabled */
if (!RunmodeIsUnittests() && !SCSshHasshIsEnabled()) {
if (!SCSigMatchSilentErrorEnabled(de_ctx, DETECT_SSH_HASSH_SERVER)) {
SCLogError("hassh support is not enabled");
}
return -2;
}
return 0;
}
/**
* \brief Registration function for hasshServer keyword.
*/
void DetectSshHasshServerRegister(void)
{
sigmatch_table[DETECT_SSH_HASSH_SERVER].name = KEYWORD_NAME;
sigmatch_table[DETECT_SSH_HASSH_SERVER].alias = KEYWORD_ALIAS;
sigmatch_table[DETECT_SSH_HASSH_SERVER].desc = BUFFER_NAME " sticky buffer";
sigmatch_table[DETECT_SSH_HASSH_SERVER].url = "/rules/" KEYWORD_DOC;
sigmatch_table[DETECT_SSH_HASSH_SERVER].Setup = DetectSshHasshServerSetup;
sigmatch_table[DETECT_SSH_HASSH_SERVER].flags |= SIGMATCH_INFO_STICKY_BUFFER | SIGMATCH_NOOPT;
DetectAppLayerMpmRegister(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister,
GetSshData, ALPROTO_SSH, SshStateBannerDone);
DetectAppLayerInspectEngineRegister(BUFFER_NAME, ALPROTO_SSH, SIG_FLAG_TOCLIENT,
SshStateBannerDone, DetectEngineInspectBufferGeneric, GetSshData);
DetectBufferTypeSetDescriptionByName(BUFFER_NAME, BUFFER_DESC);
g_ssh_hassh_buffer_id = DetectBufferTypeGetByName(BUFFER_NAME);
DetectBufferTypeRegisterSetupCallback(BUFFER_NAME, DetectLowerSetupCallback);
DetectBufferTypeRegisterValidateCallback(BUFFER_NAME, DetectMd5ValidateCallback);
}

@ -1,30 +0,0 @@
/* Copyright (C) 2007-2020 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 Malakhatko Vadym <v.malakhatko@sirinsoftware.com>
*/
#ifndef SURICATA_DETECT_SSH_HASSH_SERVER_H
#define SURICATA_DETECT_SSH_HASSH_SERVER_H
/* prototypes */
void DetectSshHasshServerRegister (void);
#endif /* SURICATA_DETECT_SSH_HASSH_SERVER_H */

@ -1,144 +0,0 @@
/* Copyright (C) 2007-2020 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 Vadym Malakhatko <v.malakhatko@sirinsoftware.com>
*/
#include "suricata-common.h"
#include "threads.h"
#include "decode.h"
#include "detect.h"
#include "detect-parse.h"
#include "detect-content.h"
#include "detect-engine.h"
#include "detect-engine-buffer.h"
#include "detect-engine-mpm.h"
#include "detect-engine-state.h"
#include "detect-engine-prefilter.h"
#include "flow.h"
#include "flow-var.h"
#include "flow-util.h"
#include "util-debug.h"
#include "util-unittest.h"
#include "util-unittest-helper.h"
#include "stream-tcp.h"
#include "app-layer.h"
#include "app-layer-parser.h"
#include "app-layer-ssh.h"
#include "detect-ssh-hassh.h"
#include "rust.h"
#define KEYWORD_NAME "ssh.hassh"
#define KEYWORD_ALIAS "ssh-hassh"
#define KEYWORD_DOC "ssh-keywords.html#hassh"
#define BUFFER_NAME "ssh.hassh"
#define BUFFER_DESC "Ssh Client Fingerprinting For Ssh Clients "
static int g_ssh_hassh_buffer_id = 0;
static InspectionBuffer *GetSshData(DetectEngineThreadCtx *det_ctx,
const DetectEngineTransforms *transforms, Flow *_f,
const uint8_t flow_flags, void *txv, const int list_id)
{
SCEnter();
InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
if (buffer->inspect == NULL) {
const uint8_t *hassh = NULL;
uint32_t b_len = 0;
if (SCSshTxGetHassh(txv, &hassh, &b_len, flow_flags) != 1)
return NULL;
if (hassh == NULL || b_len == 0) {
SCLogDebug("SSH hassh not set");
return NULL;
}
InspectionBufferSetupAndApplyTransforms(det_ctx, list_id, buffer, hassh, b_len, transforms);
}
return buffer;
}
/**
* \brief this function setup the hassh 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
* \retval -2 on failure that should be silent after the first
*/
static int DetectSshHasshSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
{
if (SCDetectBufferSetActiveList(de_ctx, s, g_ssh_hassh_buffer_id) < 0)
return -1;
if (SCDetectSignatureSetAppProto(s, ALPROTO_SSH) < 0)
return -1;
/* try to enable Hassh */
SCSshEnableHassh();
/* Check if Hassh is disabled */
if (!RunmodeIsUnittests() && !SCSshHasshIsEnabled()) {
if (!SCSigMatchSilentErrorEnabled(de_ctx, DETECT_SSH_HASSH)) {
SCLogError("hassh support is not enabled");
}
return -2;
}
return 0;
}
/**
* \brief Registration function for hassh keyword.
*/
void DetectSshHasshRegister(void)
{
sigmatch_table[DETECT_SSH_HASSH].name = KEYWORD_NAME;
sigmatch_table[DETECT_SSH_HASSH].alias = KEYWORD_ALIAS;
sigmatch_table[DETECT_SSH_HASSH].desc = BUFFER_NAME " sticky buffer";
sigmatch_table[DETECT_SSH_HASSH].url = "/rules/" KEYWORD_DOC;
sigmatch_table[DETECT_SSH_HASSH].Setup = DetectSshHasshSetup;
sigmatch_table[DETECT_SSH_HASSH].flags |= SIGMATCH_INFO_STICKY_BUFFER | SIGMATCH_NOOPT;
DetectAppLayerMpmRegister(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister,
GetSshData, ALPROTO_SSH, SshStateBannerDone),
DetectAppLayerInspectEngineRegister(BUFFER_NAME, ALPROTO_SSH, SIG_FLAG_TOSERVER,
SshStateBannerDone, DetectEngineInspectBufferGeneric, GetSshData);
DetectBufferTypeSetDescriptionByName(BUFFER_NAME, BUFFER_DESC);
g_ssh_hassh_buffer_id = DetectBufferTypeGetByName(BUFFER_NAME);
DetectBufferTypeRegisterSetupCallback(BUFFER_NAME, DetectLowerSetupCallback);
DetectBufferTypeRegisterValidateCallback(BUFFER_NAME, DetectMd5ValidateCallback);
}

@ -1,30 +0,0 @@
/* Copyright (C) 2007-2020 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 Malakhatko Vadym <v.malakhatko@sirinsoftware.com>
*/
#ifndef SURICATA_DETECT_SSH_HASSH_H
#define SURICATA_DETECT_SSH_HASSH_H
/* prototypes */
void DetectSshHasshRegister (void);
#endif /* SURICATA_DETECT_SSH_HASSH_H */

@ -118,7 +118,7 @@ static int LuaSshTxGetHassh(lua_State *L, uint8_t flags)
lua_pushnil(L);
return 1;
}
if (SCSshTxGetHassh(ltx->tx, &buf, &b_len, flags) != 1) {
if (SCSshTxGetHassh(ltx->tx, flags, &buf, &b_len) != 1) {
lua_pushnil(L);
return 1;
}

Loading…
Cancel
Save