Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1328,7 +1328,7 @@ jobs:
- run: tar xf prep/suricata-update.tar.gz
- run: tar xf prep/suricata-verify.tar.gz
- run: ./autogen.sh
- run: ./configure --enable-unittests --enable-coccinelle
- run: ./configure --enable-unittests --enable-coccinelle --enable-mimetype --enable-bundled-gpl-mimetype
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--enable-bundled-gpl-mimetype doesn't exist in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outch, sorry

- run: make -j ${{ env.CPUS }}
- run: CONCURRENCY_LEVEL=${{ env.CPUS }} make check
- run: python3 ./suricata-verify/run.py -q --debug-failed
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
- run: git config --global --add safe.directory /__w/suricata/suricata
- run: ./scripts/bundle.sh
- run: ./autogen.sh
- run: ./configure --enable-warnings
- run: ./configure --enable-warnings --enable-mimetype --enable-bundled-gpl-mimetype
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--enable-bundled-gpl-mimetype doesn't exist in this PR.

- name: Checking bindgen output
working-directory: rust
run: |
Expand Down
25 changes: 25 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1765,6 +1765,29 @@
fi
fi

# mimetype
AC_ARG_ENABLE(mimetype,
AS_HELP_STRING([--enable-mimetype], [Enable mimetype support [default=no]]),
[enable_mimetype="$enableval"],[enable_mimetype=no])
AS_IF([test "x$enable_mimetype" = "xyes"], [
AC_DEFINE([HAVE_MIMETYPE],[1],(Mimetype support enabled))
AC_ARG_ENABLE(bundled-gpl-mimetype,
AS_HELP_STRING([--disable-bundled-gpl-mimetype], [Embed GPL data in mimetype support [default=yes]]),
[enable_gpl_mimetype="$enableval"],[enable_gpl_mimetype=yes])
AS_IF([test "x$enable_gpl_mimetype" = "xyes"], [
WITH_GPL_DATA="\"with-gpl-data\""
AC_SUBST(WITH_GPL_DATA)
])
AM_CONDITIONAL([HAVE_MIMETYPE], [true])
],
[
AM_CONDITIONAL([HAVE_MIMETYPE], [false])
]
)
if test "x$enable_gpl_mimetype" != "xyes"; then
enable_gpl_mimetype="no"
fi

# Napatech - Using the 3GD API
AC_ARG_ENABLE(napatech,
AS_HELP_STRING([--enable-napatech],[Enable Napatech Devices]),
Expand Down Expand Up @@ -2578,6 +2601,8 @@ SURICATA_BUILD_CONF="Suricata Configuration:
Detection enabled: ${enable_detection}

Libmagic support: ${enable_magic}
mimetype support: ${enable_mimetype}
GPL Mimetype DB inclusion: ${enable_gpl_mimetype}
libjansson support: ${enable_jansson}
hiredis support: ${enable_hiredis}
hiredis async with libevent: ${enable_hiredis_async}
Expand Down
15 changes: 15 additions & 0 deletions doc/userguide/rules/file-keywords.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,21 @@ here: https://redmine.openinfosecfoundation.org/issues/437

``file.magic`` supports multiple buffer matching, see :doc:`multi-buffer-matching`.

file.mimetype
-------------

Sticky buffer that matches on the MIME type guessed from the binary content of a file.

Example::

file.mimetype; content:"application/vnd.microsoft.portable-executable";

``file.mimetype`` supports multiple buffer matching, see :doc:`multi-buffer-matching`.

The MIME type analysis is faster than the magic analysis and the identification is also
more reproducible across different Suricata versions and operating systems. Being a
standard, this is also improving correlation with other tools.

filestore
---------

Expand Down
8 changes: 8 additions & 0 deletions etc/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1729,6 +1729,10 @@
"md5": {
"type": "string"
},
"mimetype": {
"type": "string",
"description": "The MIME type of the file (e.g., application/pdf, image/png, etc.)"
},
"sha1": {
"type": "string"
},
Expand Down Expand Up @@ -1788,6 +1792,10 @@
"md5": {
"type": "string"
},
"mimetype": {
"type": "string",
"description": "The MIME type of the file (e.g., application/pdf, image/png, etc.)"
},
"sha1": {
"type": "string"
},
Expand Down
43 changes: 43 additions & 0 deletions rust/Cargo.lock.in

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions rust/Cargo.toml.in
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ debug = []
debug-validate = []
ja3 = []
ja4 = []
filemimetype = ["dep:tree_magic_mini"]

[dependencies]
nom7 = { version="7.1", package="nom" }
Expand All @@ -58,6 +59,8 @@ lru = "~0.12.5"
der-parser = { version = "~9.0.0", default-features = false }
kerberos-parser = { version = "~0.8.0", default-features = false }

tree_magic_mini = { version = "~3.1.6", features = [@WITH_GPL_DATA@], optional = true }

sawp-modbus = "~0.13.1"
sawp-pop3 = "~0.13.1"
sawp = "~0.13.1"
Expand Down
4 changes: 4 additions & 0 deletions rust/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ if DEBUG
RUST_FEATURES += debug
endif

if HAVE_MIMETYPE
RUST_FEATURES += filemimetype
endif

if DEBUG_VALIDATION
RUST_FEATURES += debug-validate
endif
Expand Down
26 changes: 26 additions & 0 deletions rust/src/filemimetype.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* Copyright (C) 2025 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.
*/

use crate::common::rust_string_to_c;
use std::os::raw::c_char;

#[no_mangle]
pub unsafe extern "C" fn SCGetMimetype(input: *const u8, len: u32) -> * mut c_char {
let slice: &[u8] = std::slice::from_raw_parts(input as *mut u8, len as usize);
let result = tree_magic_mini::from_u8(slice);
rust_string_to_c(result.to_string())
}
2 changes: 2 additions & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ pub mod applayer;
pub mod frames;
pub mod filecontainer;
pub mod filetracker;
#[cfg(feature = "filemimetype")]
pub mod filemimetype;
pub mod kerberos;
pub mod detect;
pub mod utils;
Expand Down
4 changes: 4 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ noinst_HEADERS = \
detect-fast-pattern.h \
detect-file-data.h \
detect-file-hash-common.h \
detect-file-mimetype.h \
detect-filemagic.h \
detect-filemd5.h \
detect-filename.h \
Expand Down Expand Up @@ -565,6 +566,7 @@ noinst_HEADERS = \
util-memcmp.h \
util-memcpy.h \
util-memrchr.h \
util-mimetype.h \
util-misc.h \
util-mpm-ac-ks.h \
util-mpm-ac-queue.h \
Expand Down Expand Up @@ -761,6 +763,7 @@ libsuricata_c_a_SOURCES = \
detect-fast-pattern.c \
detect-file-data.c \
detect-file-hash-common.c \
detect-file-mimetype.c \
detect-filemagic.c \
detect-filemd5.c \
detect-filename.c \
Expand Down Expand Up @@ -1147,6 +1150,7 @@ libsuricata_c_a_SOURCES = \
util-mem.c \
util-memcmp.c \
util-memrchr.c \
util-mimetype.c \
util-misc.c \
util-mpm-ac-ks-small.c \
util-mpm-ac-ks.c \
Expand Down
3 changes: 2 additions & 1 deletion src/app-layer-smtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "app-layer-smtp.h"

#include "util-enum.h"
#include "util-file.h"
#include "util-mpm.h"
#include "util-debug.h"
#include "util-byte.h"
Expand Down Expand Up @@ -1193,7 +1194,7 @@ static int SMTPProcessRequest(
} else if (smtp_config.raw_extraction) {
if (FileOpenFileWithId(&tx->files_ts, &smtp_config.sbcfg, state->file_track_id++,
(uint8_t *)rawmsgname, strlen(rawmsgname), NULL, 0,
FILE_NOMD5 | FILE_NOMAGIC) == 0) {
FILE_NOMD5 | FILE_NOMAGIC | FILE_NOMIMETYPE) == 0) {
SMTPNewFile(tx, tx->files_ts.tail);
}
} else if (smtp_config.decode_mime) {
Expand Down
19 changes: 19 additions & 0 deletions src/detect-engine-build.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,25 @@ int SignatureIsFilemagicInspecting(const Signature *s)
return 0;
}

/**
* \brief Check if a signature contains the file.mimetype keyword.
*
* \param s signature
*
* \retval 0 no
* \retval 1 yes
*/
int SignatureIsFileMimetypeInspecting(const Signature *s)
{
if (s == NULL)
return 0;

if (s->file_flags & FILE_SIG_NEED_MIMETYPE)
return 1;

return 0;
}

/**
* \brief Check if a signature contains the filemd5 keyword.
*
Expand Down
1 change: 1 addition & 0 deletions src/detect-engine-build.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ void PacketCreateMask(Packet *p, SignatureMask *mask, AppProto alproto,

int SignatureIsFilestoring(const Signature *);
int SignatureIsFilemagicInspecting(const Signature *);
int SignatureIsFileMimetypeInspecting(const Signature *);
int SignatureIsFileMd5Inspecting(const Signature *);
int SignatureIsFileSha1Inspecting(const Signature *s);
int SignatureIsFileSha256Inspecting(const Signature *s);
Expand Down
6 changes: 6 additions & 0 deletions src/detect-engine-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ static uint8_t DetectFileInspect(DetectEngineThreadCtx *det_ctx, Flow *f, const
continue;
}

if ((s->file_flags & FILE_SIG_NEED_MIMETYPE) && file_size == 0) {
SCLogDebug("sig needs file content, but we don't have any");
r = DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
continue;
}

if ((s->file_flags & FILE_SIG_NEED_FILECONTENT) && file_size == 0) {
SCLogDebug("sig needs file content, but we don't have any");
r = DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
Expand Down
2 changes: 2 additions & 0 deletions src/detect-engine-register.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
#include "detect-filesha1.h"
#include "detect-filesha256.h"
#include "detect-filesize.h"
#include "detect-file-mimetype.h"
#include "detect-dataset.h"
#include "detect-datarep.h"
#include "detect-dsize.h"
Expand Down Expand Up @@ -565,6 +566,7 @@ void SigTableSetup(void)
DetectFileSha1Register();
DetectFileSha256Register();
DetectFilesizeRegister();
DetectFileMimetypeRegister();

DetectHttpUARegister();
DetectHttpHHRegister();
Expand Down
1 change: 1 addition & 0 deletions src/detect-engine-register.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ enum DetectKeywordId {
DETECT_FILESTORE_POSTMATCH,
DETECT_FILEMAGIC,
DETECT_FILE_MAGIC,
DETECT_FILE_MIMETYPE,
DETECT_FILEMD5,
DETECT_FILESHA1,
DETECT_FILESHA256,
Expand Down
3 changes: 3 additions & 0 deletions src/detect-engine-siggroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,9 @@ void SigGroupHeadSetupFiles(const DetectEngineCtx *de_ctx, SigGroupHead *sgh)
sgh->flags |= SIG_GROUP_HEAD_HAVEFILEMAGIC;
}
#endif
if (SignatureIsFileMimetypeInspecting(s)) {
sgh->flags |= SIG_GROUP_HEAD_HAVEFILEMIMETYPE;
}
if (SignatureIsFilestoring(s)) {
// should be insured by caller that we do not overflow
DEBUG_VALIDATE_BUG_ON(sgh->filestore_cnt == UINT16_MAX);
Expand Down
Loading
Loading