mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 05:45:59 +03:00
parent
4ecfed3163
commit
7622866f97
2
CHANGES
2
CHANGES
@ -2,6 +2,8 @@
|
|||||||
v3.0.????? - ?
|
v3.0.????? - ?
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
- Adds support for @fuzzyHash operator.
|
||||||
|
[Issue #997 - @zimmerle]
|
||||||
- Fix build on non x86 arch build
|
- Fix build on non x86 arch build
|
||||||
[Issue #1598 - @athmane]
|
[Issue #1598 - @athmane]
|
||||||
- Fix memory issue while changing rule target dynamic
|
- Fix memory issue while changing rule target dynamic
|
||||||
|
@ -284,4 +284,5 @@ TESTS+=test/test-cases/regression/offset-variable.json
|
|||||||
TESTS+=test/test-cases/regression/config-update-target-by-tag.json
|
TESTS+=test/test-cases/regression/config-update-target-by-tag.json
|
||||||
TESTS+=test/test-cases/regression/config-update-target-by-id.json
|
TESTS+=test/test-cases/regression/config-update-target-by-id.json
|
||||||
TESTS+=test/test-cases/regression/misc-variable-under-quotes.json
|
TESTS+=test/test-cases/regression/misc-variable-under-quotes.json
|
||||||
|
TESTS+=test/test-cases/regression/operator-fuzzyhash.json
|
||||||
|
|
||||||
|
153
build/ssdeep.m4
Normal file
153
build/ssdeep.m4
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
dnl Check for SSDEEP Libraries
|
||||||
|
dnl CHECK_SSDEEP(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
|
||||||
|
|
||||||
|
|
||||||
|
AC_DEFUN([CHECK_SSDEEP],
|
||||||
|
[dnl
|
||||||
|
|
||||||
|
# Possible names for the ssdeep library/package (pkg-config)
|
||||||
|
SSDEEP_POSSIBLE_LIB_NAMES="fuzzy"
|
||||||
|
|
||||||
|
# Possible extensions for the library
|
||||||
|
SSDEEP_POSSIBLE_EXTENSIONS="so so0 la sl dll dylib so.0.0.0"
|
||||||
|
|
||||||
|
# Possible paths (if pkg-config was not found, proceed with the file lookup)
|
||||||
|
SSDEEP_POSSIBLE_PATHS="/usr/lib /usr/local/lib /usr/local/fuzzy /usr/local/libfuzzy /usr/local /opt /usr /usr/lib64 /opt/local"
|
||||||
|
|
||||||
|
# Variables to be set by this very own script.
|
||||||
|
SSDEEP_CFLAGS=""
|
||||||
|
SSDEEP_LDFLAGS=""
|
||||||
|
SSDEEP_LDADD=""
|
||||||
|
SSDEEP_DISPLAY=""
|
||||||
|
|
||||||
|
AC_ARG_WITH(
|
||||||
|
ssdeep,
|
||||||
|
AC_HELP_STRING(
|
||||||
|
[--with-ssdeep=PATH],
|
||||||
|
[Path to ssdeep prefix]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if test "x${with_ssdeep}" == "xno"; then
|
||||||
|
AC_DEFINE(HAVE_SSDEEP, 0, [Support for SSDEEP was disabled by the utilization of --without-ssdeep or --with-ssdeep=no])
|
||||||
|
AC_MSG_NOTICE([Support for SSDEEP was disabled by the utilization of --without-ssdeep or --with-ssdeep=no])
|
||||||
|
SSDEEP_DISABLED=yes
|
||||||
|
else
|
||||||
|
if test "x${with_ssdeep}" == "xyes"; then
|
||||||
|
SSDEEP_MANDATORY=yes
|
||||||
|
AC_MSG_NOTICE([SSDEEP support was marked as mandatory by the utilization of --with-ssdeep=yes])
|
||||||
|
else
|
||||||
|
SSDEEP_MANDATORY=no
|
||||||
|
fi
|
||||||
|
for x in ${SSDEEP_POSSIBLE_PATHS}; do
|
||||||
|
CHECK_FOR_SSDEEP_AT(${x})
|
||||||
|
if test -n "${SSDEEP_CFLAGS}"; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test -z "${SSDEEP_CFLAGS}"; then
|
||||||
|
if test -z "${SSDEEP_MANDATORY}"; then
|
||||||
|
if test -z "${SSDEEP_DISABLED}"; then
|
||||||
|
AC_MSG_NOTICE([SSDEEP library was not found])
|
||||||
|
SSDEEP_FOUND=0
|
||||||
|
else
|
||||||
|
SSDEEP_FOUND=2
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
AC_MSG_ERROR([SSDEEP was explicitly referenced but it was not found])
|
||||||
|
SSDEEP_FOUND=-1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
|
||||||
|
if test -z "${SSDEEP_MANDATORY}"; then
|
||||||
|
SSDEEP_FOUND=2
|
||||||
|
AC_MSG_NOTICE([SSDEEP is disabled by default.])
|
||||||
|
else
|
||||||
|
SSDEEP_FOUND=1
|
||||||
|
AC_MSG_NOTICE([using SSDEEP v${SSDEEP_VERSION}])
|
||||||
|
SSDEEP_CFLAGS="-DWITH_SSDEEP ${SSDEEP_CFLAGS}"
|
||||||
|
SSDEEP_DISPLAY="${SSDEEP_LDADD} ${SSDEEP_LDFLAGS}, ${SSDEEP_CFLAGS}"
|
||||||
|
AC_SUBST(SSDEEP_LDFLAGS)
|
||||||
|
AC_SUBST(SSDEEP_LDADD)
|
||||||
|
AC_SUBST(SSDEEP_CFLAGS)
|
||||||
|
AC_SUBST(SSDEEP_DISPLAY)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
AC_SUBST(SSDEEP_FOUND)
|
||||||
|
|
||||||
|
]) # AC_DEFUN [CHECK_SSDEEP]
|
||||||
|
|
||||||
|
|
||||||
|
AC_DEFUN([CHECK_FOR_SSDEEP_AT], [
|
||||||
|
path=$1
|
||||||
|
echo "*** LOOKING AT PATH: " ${path}
|
||||||
|
for y in ${SSDEEP_POSSIBLE_EXTENSIONS}; do
|
||||||
|
for z in ${SSDEEP_POSSIBLE_LIB_NAMES}; do
|
||||||
|
if test -e "${path}/${z}.${y}"; then
|
||||||
|
ssdeep_lib_path="${path}/"
|
||||||
|
ssdeep_lib_name="${z}"
|
||||||
|
ssdeep_lib_file="${ssdeep_lib_path}/${z}.${y}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if test -e "${path}/lib${z}.${y}"; then
|
||||||
|
ssdeep_lib_path="${path}/"
|
||||||
|
ssdeep_lib_name="${z}"
|
||||||
|
ssdeep_lib_file="${ssdeep_lib_path}/lib${z}.${y}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if test -e "${path}/lib/lib${z}.${y}"; then
|
||||||
|
ssdeep_lib_path="${path}/lib/"
|
||||||
|
ssdeep_lib_name="${z}"
|
||||||
|
ssdeep_lib_file="${ssdeep_lib_path}/lib${z}.${y}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then
|
||||||
|
ssdeep_lib_path="${path}/lib/x86_64-linux-gnu/"
|
||||||
|
ssdeep_lib_name="${z}"
|
||||||
|
ssdeep_lib_file="${ssdeep_lib_path}/lib${z}.${y}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if test -e "${path}/lib/i386-linux-gnu/lib${z}.${y}"; then
|
||||||
|
ssdeep_lib_path="${path}/lib/i386-linux-gnu/"
|
||||||
|
ssdeep_lib_name="${z}"
|
||||||
|
ssdeep_lib_file="${ssdeep_lib_path}/lib${z}.${y}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if test -n "$ssdeep_lib_path"; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if test -e "${path}/include/fuzzy.h"; then
|
||||||
|
ssdeep_inc_path="${path}/include"
|
||||||
|
elif test -e "${path}/fuzzy.h"; then
|
||||||
|
ssdeep_inc_path="${path}"
|
||||||
|
elif test -e "${path}/include/fuzzy/fuzzy.h"; then
|
||||||
|
ssdeep_inc_path="${path}/include"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -n "${ssdeep_lib_path}"; then
|
||||||
|
AC_MSG_NOTICE([SSDEEP library found at: ${ssdeep_lib_file}])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -n "${ssdeep_inc_path}"; then
|
||||||
|
AC_MSG_NOTICE([SSDEEP headers found at: ${ssdeep_inc_path}])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -n "${ssdeep_lib_path}" -a -n "${ssdeep_inc_path}"; then
|
||||||
|
# TODO: Compile a piece of code to check the version.
|
||||||
|
SSDEEP_CFLAGS="-I${ssdeep_inc_path}"
|
||||||
|
SSDEEP_LDADD="-l${ssdeep_lib_name}"
|
||||||
|
SSDEEP_LDFLAGS="-L${ssdeep_lib_path}"
|
||||||
|
SSDEEP_DISPLAY="${ssdeep_lib_file}, ${ssdeep_inc_path}"
|
||||||
|
fi
|
||||||
|
]) # AC_DEFUN [CHECK_FOR_SSDEEP_AT]
|
||||||
|
|
||||||
|
|
||||||
|
|
22
configure.ac
22
configure.ac
@ -86,6 +86,10 @@ AM_CONDITIONAL([GEOIP_CFLAGS], [test "GEOIP_CFLAGS" != ""])
|
|||||||
PROG_LMDB
|
PROG_LMDB
|
||||||
AM_CONDITIONAL([LMDB_CFLAGS], [test "LMDB_CFLAGS" != ""])
|
AM_CONDITIONAL([LMDB_CFLAGS], [test "LMDB_CFLAGS" != ""])
|
||||||
|
|
||||||
|
# Check for SSDEEP
|
||||||
|
CHECK_SSDEEP
|
||||||
|
AM_CONDITIONAL([SSDEEP_CFLAGS], [test "SSDEEP_CFLAGS" != ""])
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check for curl
|
# Check for curl
|
||||||
#
|
#
|
||||||
@ -483,6 +487,24 @@ if test "x$LIBXML2_FOUND" = "x2"; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
## SSDEEP
|
||||||
|
if test "x$SSDEEP_FOUND" = "x0"; then
|
||||||
|
echo " + SSDEEP ....not found"
|
||||||
|
fi
|
||||||
|
if test "x$SSDEEP_FOUND" = "x1"; then
|
||||||
|
echo -n " + SSDEEP ....found "
|
||||||
|
if ! test "x$SSDEEP_VERSION" = "x"; then
|
||||||
|
echo "v${SSDEEP_VERSION}"
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
echo " ${SSDEEP_DISPLAY}"
|
||||||
|
fi
|
||||||
|
if test "x$SSDEEP_FOUND" = "x2"; then
|
||||||
|
echo " + SSDEEP ....disabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
echo " "
|
echo " "
|
||||||
echo " Other Options"
|
echo " Other Options"
|
||||||
if test $buildTestUtilities = true; then
|
if test $buildTestUtilities = true; then
|
||||||
|
@ -11,6 +11,7 @@ multi_LDADD = \
|
|||||||
-lpthread \
|
-lpthread \
|
||||||
$(YAJL_LDFLAGS) \
|
$(YAJL_LDFLAGS) \
|
||||||
$(GEOIP_LDFLAGS) \
|
$(GEOIP_LDFLAGS) \
|
||||||
|
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
|
||||||
$(GLOBAL_LDADD)
|
$(GLOBAL_LDADD)
|
||||||
|
|
||||||
multi_CFLAGS = \
|
multi_CFLAGS = \
|
||||||
|
@ -13,6 +13,7 @@ simple_request_LDADD = \
|
|||||||
$(PCRE_LDADD) \
|
$(PCRE_LDADD) \
|
||||||
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
||||||
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
||||||
|
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
|
||||||
$(LIBXML2_LDADD) \
|
$(LIBXML2_LDADD) \
|
||||||
$(GLOBAL_LDADD)
|
$(GLOBAL_LDADD)
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ read_LDADD = \
|
|||||||
$(PCRE_LDADD) \
|
$(PCRE_LDADD) \
|
||||||
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
||||||
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
||||||
|
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
|
||||||
$(LIBXML2_LDADD) \
|
$(LIBXML2_LDADD) \
|
||||||
$(GLOBAL_LDADD)
|
$(GLOBAL_LDADD)
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ test_LDADD = \
|
|||||||
-lmodsecurity \
|
-lmodsecurity \
|
||||||
$(YAJL_LDFLAGS) \
|
$(YAJL_LDFLAGS) \
|
||||||
$(GEOIP_LDFLAGS) \
|
$(GEOIP_LDFLAGS) \
|
||||||
|
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
|
||||||
$(GLOBAL_LDADD)
|
$(GLOBAL_LDADD)
|
||||||
|
|
||||||
test_CFLAGS = \
|
test_CFLAGS = \
|
||||||
|
@ -13,6 +13,7 @@ simple_request_LDADD = \
|
|||||||
$(PCRE_LDADD) \
|
$(PCRE_LDADD) \
|
||||||
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
||||||
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
||||||
|
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
|
||||||
$(LIBXML2_LDADD) \
|
$(LIBXML2_LDADD) \
|
||||||
$(GLOBAL_LDADD)
|
$(GLOBAL_LDADD)
|
||||||
|
|
||||||
|
@ -297,6 +297,7 @@ libmodsecurity_la_CPPFLAGS = \
|
|||||||
$(YAJL_CFLAGS) \
|
$(YAJL_CFLAGS) \
|
||||||
$(LMDB_CFLAGS) \
|
$(LMDB_CFLAGS) \
|
||||||
$(PCRE_CFLAGS) \
|
$(PCRE_CFLAGS) \
|
||||||
|
$(SSDEEP_CFLAGS) \
|
||||||
$(LIBXML2_CFLAGS)
|
$(LIBXML2_CFLAGS)
|
||||||
|
|
||||||
libmodsecurity_la_LIBADD = \
|
libmodsecurity_la_LIBADD = \
|
||||||
@ -306,6 +307,7 @@ libmodsecurity_la_LIBADD = \
|
|||||||
$(PCRE_LDADD) \
|
$(PCRE_LDADD) \
|
||||||
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
||||||
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
||||||
|
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
|
||||||
$(LIBXML2_LDADD) \
|
$(LIBXML2_LDADD) \
|
||||||
../others/libinjection.la \
|
../others/libinjection.la \
|
||||||
../others/libmbedtls.la
|
../others/libmbedtls.la
|
||||||
|
@ -19,16 +19,96 @@
|
|||||||
|
|
||||||
#include "src/operators/operator.h"
|
#include "src/operators/operator.h"
|
||||||
#include "src/macro_expansion.h"
|
#include "src/macro_expansion.h"
|
||||||
|
#include "src/utils/system.h"
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace operators {
|
namespace operators {
|
||||||
|
|
||||||
bool FuzzyHash::evaluate(Transaction *transaction, const std::string &str) {
|
bool FuzzyHash::init(const std::string ¶m2, std::string *error) {
|
||||||
/**
|
#ifdef WITH_SSDEEP
|
||||||
* @todo Implement the operator FuzzyHash.
|
std::string digit;
|
||||||
* Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#fuzzyhash
|
std::string file;
|
||||||
*/
|
std::istream *iss;
|
||||||
|
struct fuzzy_hash_chunk *chunk, *t;
|
||||||
|
std::string err;
|
||||||
|
|
||||||
|
auto pos = m_param.find_last_of(' ');
|
||||||
|
if (pos == std::string::npos) {
|
||||||
|
error->assign("Please use @fuzzyHash with filename and value");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
digit.append(std::string(m_param, pos+1));
|
||||||
|
file.append(std::string(m_param, 0, pos));
|
||||||
|
try {
|
||||||
|
m_threshold = std::stoi(digit);
|
||||||
|
} catch (...) {
|
||||||
|
error->assign("Expecting a digit, got: " + digit);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string resource = utils::find_resource(file, param2, &err);
|
||||||
|
iss = new std::ifstream(resource, std::ios::in);
|
||||||
|
|
||||||
|
if (((std::ifstream *)iss)->is_open() == false) {
|
||||||
|
error->assign("Failed to open file: " + m_param + ". " + err);
|
||||||
|
delete iss;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::string line; std::getline(*iss, line); ) {
|
||||||
|
chunk = (struct fuzzy_hash_chunk *)calloc(1, sizeof(struct fuzzy_hash_chunk));
|
||||||
|
|
||||||
|
chunk->data = strdup(line.c_str());
|
||||||
|
chunk->next = NULL;
|
||||||
|
|
||||||
|
if (m_head == NULL) {
|
||||||
|
m_head = chunk;
|
||||||
|
} else {
|
||||||
|
t = m_head;
|
||||||
|
|
||||||
|
while (t->next) {
|
||||||
|
t = t->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
t->next = chunk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete iss;
|
||||||
return true;
|
return true;
|
||||||
|
#else
|
||||||
|
error->assign("@fuzzyHash: SSDEEP support was not enabled during the compilation.");
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool FuzzyHash::evaluate(Transaction *t, const std::string &str) {
|
||||||
|
#ifdef WITH_SSDEEP
|
||||||
|
char result[FUZZY_MAX_RESULT];
|
||||||
|
struct fuzzy_hash_chunk *chunk = m_head;
|
||||||
|
|
||||||
|
if (fuzzy_hash_buf((const unsigned char*)str.c_str(), str.size(), result))
|
||||||
|
{
|
||||||
|
t->debug(4, "Problems generating fuzzy hash");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (chunk != NULL)
|
||||||
|
{
|
||||||
|
int i = fuzzy_compare(chunk->data, result);
|
||||||
|
if (i >= m_threshold)
|
||||||
|
{
|
||||||
|
t->debug(4, "Fuzzy hash: matched " \
|
||||||
|
"with score: " + std::to_string(i) + ".");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
chunk = chunk->next;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* No match. */
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace operators
|
} // namespace operators
|
||||||
|
@ -18,20 +18,38 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/operators/operator.h"
|
#ifdef WITH_SSDEEP
|
||||||
|
#include "fuzzy.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "src/operators/operator.h"
|
||||||
|
|
||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace operators {
|
namespace operators {
|
||||||
|
|
||||||
|
|
||||||
|
struct fuzzy_hash_chunk {
|
||||||
|
const char *data;
|
||||||
|
struct fuzzy_hash_chunk *next;
|
||||||
|
};
|
||||||
|
|
||||||
class FuzzyHash : public Operator {
|
class FuzzyHash : public Operator {
|
||||||
public:
|
public:
|
||||||
/** @ingroup ModSecurity_Operator */
|
/** @ingroup ModSecurity_Operator */
|
||||||
FuzzyHash(std::string o, std::string p, bool n)
|
FuzzyHash(std::string o, std::string p, bool n)
|
||||||
: Operator(o, p, n) { }
|
: Operator(o, p, n),
|
||||||
|
m_head(NULL),
|
||||||
|
m_threshold(0) { }
|
||||||
explicit FuzzyHash(std::string param)
|
explicit FuzzyHash(std::string param)
|
||||||
: Operator("FuzzyHash", param) { }
|
: Operator("FuzzyHash", param),
|
||||||
|
m_head(NULL),
|
||||||
|
m_threshold(0) { }
|
||||||
bool evaluate(Transaction *transaction, const std::string &std) override;
|
bool evaluate(Transaction *transaction, const std::string &std) override;
|
||||||
|
|
||||||
|
bool init(const std::string ¶m, std::string *error) override;
|
||||||
|
private:
|
||||||
|
int m_threshold;
|
||||||
|
struct fuzzy_hash_chunk *m_head;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace operators
|
} // namespace operators
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -910,8 +910,12 @@ op_before_init:
|
|||||||
}
|
}
|
||||||
| OPERATOR_FUZZY_HASH FREE_TEXT
|
| OPERATOR_FUZZY_HASH FREE_TEXT
|
||||||
{
|
{
|
||||||
/* $$ = new operators::FuzzyHash(); */
|
OPERATOR_CONTAINER($$, new operators::FuzzyHash(utils::string::removeBracketsIfNeeded($2)));
|
||||||
OPERATOR_NOT_SUPPORTED("FuzzyHash", @0);
|
std::string error;
|
||||||
|
if ($$->init(driver.ref.back(), &error) == false) {
|
||||||
|
driver.error(@0, error);
|
||||||
|
YYERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
| OPERATOR_VALIDATE_BYTE_RANGE FREE_TEXT
|
| OPERATOR_VALIDATE_BYTE_RANGE FREE_TEXT
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,7 @@ unit_tests_LDADD = \
|
|||||||
$(PCRE_LDADD) \
|
$(PCRE_LDADD) \
|
||||||
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
||||||
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
||||||
|
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
|
||||||
$(LIBXML2_LDADD) \
|
$(LIBXML2_LDADD) \
|
||||||
$(GLOBAL_LDADD)
|
$(GLOBAL_LDADD)
|
||||||
|
|
||||||
@ -80,6 +81,7 @@ regression_tests_LDADD = \
|
|||||||
$(PCRE_LDADD) \
|
$(PCRE_LDADD) \
|
||||||
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
||||||
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
||||||
|
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
|
||||||
$(LIBXML2_LDADD) \
|
$(LIBXML2_LDADD) \
|
||||||
$(GLOBAL_LDADD)
|
$(GLOBAL_LDADD)
|
||||||
|
|
||||||
@ -115,6 +117,7 @@ rules_optimization_LDADD = \
|
|||||||
$(PCRE_LDADD) \
|
$(PCRE_LDADD) \
|
||||||
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
||||||
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
||||||
|
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
|
||||||
$(LIBXML2_LDADD) \
|
$(LIBXML2_LDADD) \
|
||||||
$(GLOBAL_LDADD)
|
$(GLOBAL_LDADD)
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ benchmark_LDADD = \
|
|||||||
$(PCRE_LDADD) \
|
$(PCRE_LDADD) \
|
||||||
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
||||||
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
||||||
|
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
|
||||||
$(LIBXML2_LDADD) \
|
$(LIBXML2_LDADD) \
|
||||||
$(GLOBAL_LDADD)
|
$(GLOBAL_LDADD)
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ afl_fuzzer_LDADD = \
|
|||||||
$(PCRE_LDADD) \
|
$(PCRE_LDADD) \
|
||||||
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
||||||
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
||||||
|
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
|
||||||
$(LIBXML2_LDADD) \
|
$(LIBXML2_LDADD) \
|
||||||
$(top_builddir)/src/.libs/libmodsecurity.a \
|
$(top_builddir)/src/.libs/libmodsecurity.a \
|
||||||
$(top_builddir)/others/libinjection.la \
|
$(top_builddir)/others/libinjection.la \
|
||||||
|
4
test/test-cases/data/ssdeep.txt
Normal file
4
test/test-cases/data/ssdeep.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
ssdeep,1.1--blocksize:hash:hash,filename
|
||||||
|
96:MbQ1L0LDX8GPI8ov3D2D9zd6/gz2wZhFvV0O598La8Kqvfi0znNa8Xi5SM7XRWCK:KvL8Gg8rWIz2ZKqvfjzQ55RpRHjftQ++,"modsecurity.conf-recommended"
|
||||||
|
192:b8B5UQvywcMIJuavpde/Yyz/U/vF+vGCoCvrQr/dw:afcnrvp8zqUvGrzr6,"README_WINDOWS.TXT"
|
||||||
|
96:+qK8Z4gA165/hquKNMi68zuEyMM9qNB26x:+RG4z6c1LyZOB26x,"README.TXT"
|
214
test/test-cases/regression/operator-fuzzyhash.json
Normal file
214
test/test-cases/regression/operator-fuzzyhash.json
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"enabled":1,
|
||||||
|
"version_min":300000,
|
||||||
|
"title":"Testing Operator :: @fuzzyHash (1/2)",
|
||||||
|
"client":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":123
|
||||||
|
},
|
||||||
|
"server":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":80
|
||||||
|
},
|
||||||
|
"request":{
|
||||||
|
"headers":{
|
||||||
|
"Host":"localhost",
|
||||||
|
"User-Agent":"curl/7.38.0",
|
||||||
|
"Accept":"*/*",
|
||||||
|
"Content-Length": "27",
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
"uri":"/",
|
||||||
|
"method":"POST",
|
||||||
|
"body": [
|
||||||
|
"",
|
||||||
|
"# -- Rule engine initialization ----------------------------------------------",
|
||||||
|
"",
|
||||||
|
"# Enable ModSecurity, attaching it to every transaction. Use detection",
|
||||||
|
"# only to start with, because that minimises the chances of post-installation",
|
||||||
|
"# disruption.",
|
||||||
|
"#",
|
||||||
|
"SecRuleEngine DetectionOnly",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"# -- Request body handling ---------------------------------------------------",
|
||||||
|
"",
|
||||||
|
"# Allow ModSecurity to access request bodies. If you don't, ModSecurity",
|
||||||
|
"# won't be able to see any POST parameters, which opens a large security",
|
||||||
|
"# hole for attackers to exploit.",
|
||||||
|
"#",
|
||||||
|
"SecRequestBodyAccess On",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"# Enable XML request body parser.",
|
||||||
|
"# Initiate XML Processor in case of xml content-type",
|
||||||
|
"#",
|
||||||
|
"SecRule REQUEST_HEADERS:Content-Type \"text/xml\" \\",
|
||||||
|
" \"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML\"",
|
||||||
|
"",
|
||||||
|
"# Enable JSON request body parser.",
|
||||||
|
"# Initiate JSON Processor in case of JSON content-type; change accordingly",
|
||||||
|
"# if your application does not use 'application/json'",
|
||||||
|
"#",
|
||||||
|
"SecRule REQUEST_HEADERS:Content-Type \"application/json\" \\",
|
||||||
|
" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"",
|
||||||
|
"",
|
||||||
|
"# Maximum request body size we will accept for buffering. If you support",
|
||||||
|
"# file uploads then the value given on the first line has to be as large",
|
||||||
|
"# as the largest file you are willing to accept. The second value refers",
|
||||||
|
"# to the size of data, with files excluded. You want to keep that value as",
|
||||||
|
"# low as practical.",
|
||||||
|
"#",
|
||||||
|
"SecRequestBodyLimit 13107200",
|
||||||
|
"SecRequestBodyNoFilesLimit 131072",
|
||||||
|
"",
|
||||||
|
"# Store up to 128 KB of request body data in memory. When the multipart",
|
||||||
|
"# parser reachers this limit, it will start using your hard disk for",
|
||||||
|
"# storage. That is slow, but unavoidable.",
|
||||||
|
"#",
|
||||||
|
"SecRequestBodyInMemoryLimit 131072",
|
||||||
|
"",
|
||||||
|
"# What do do if the request body size is above our configured limit.",
|
||||||
|
"# Keep in mind that this setting will automatically be set to ProcessPartial",
|
||||||
|
"# when SecRuleEngine is set to DetectionOnly mode in order to minimize",
|
||||||
|
"# disruptions when initially deploying ModSecurity.",
|
||||||
|
"#",
|
||||||
|
"SecRequestBodyLimitAction Reject",
|
||||||
|
"",
|
||||||
|
"# Verify that we've correctly processed the request body.",
|
||||||
|
"# As a rule of thumb, when failing to process a request body",
|
||||||
|
"# you should reject the request (when deployed in blocking mode)",
|
||||||
|
"# or log a high-severity alert (when deployed in detection-only mode).",
|
||||||
|
"#",
|
||||||
|
"SecRule REQBODY_ERROR \"!\\@eq 0\" ",
|
||||||
|
"\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\"",
|
||||||
|
" "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"response":{
|
||||||
|
"headers":{
|
||||||
|
"Date":"Mon, 13 Jul 2015 20:02:41 GMT",
|
||||||
|
"Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT",
|
||||||
|
"Content-Type":"text/html"
|
||||||
|
},
|
||||||
|
"body":[
|
||||||
|
"no need."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"expected":{
|
||||||
|
"debug_log":" Fuzzy hash: matched with score: 54."
|
||||||
|
},
|
||||||
|
"rules":[
|
||||||
|
"SecRuleEngine On",
|
||||||
|
"SecRequestBodyAccess On",
|
||||||
|
"SecRule REQUEST_BODY \"@fuzzyHash test-cases/data/ssdeep.txt 1\" \"id:1,phase:2,pass,t:trim\""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enabled":1,
|
||||||
|
"version_min":300000,
|
||||||
|
"title":"Testing Operator :: @fuzzyHash (2/2)",
|
||||||
|
"client":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":123
|
||||||
|
},
|
||||||
|
"server":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":80
|
||||||
|
},
|
||||||
|
"request":{
|
||||||
|
"headers":{
|
||||||
|
"Host":"localhost",
|
||||||
|
"User-Agent":"curl/7.38.0",
|
||||||
|
"Accept":"*/*",
|
||||||
|
"Content-Length": "27",
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
"uri":"/",
|
||||||
|
"method":"POST",
|
||||||
|
"body": [
|
||||||
|
"",
|
||||||
|
"# -- Rule engine initialization ----------------------------------------------",
|
||||||
|
"",
|
||||||
|
"# Enable ModSecurity, attaching it to every transaction. Use detection",
|
||||||
|
"# only to start with, because that minimises the chances of post-installation",
|
||||||
|
"# disruption.",
|
||||||
|
"#",
|
||||||
|
"SecRuleEngine DetectionOnly",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"# -- Request body handling ---------------------------------------------------",
|
||||||
|
"",
|
||||||
|
"# Allow ModSecurity to access request bodies. If you don't, ModSecurity",
|
||||||
|
"# won't be able to see any POST parameters, which opens a large security",
|
||||||
|
"# hole for attackers to exploit.",
|
||||||
|
"#",
|
||||||
|
"SecRequestBodyAccess On",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"# Enable XML request body parser.",
|
||||||
|
"# Initiate XML Processor in case of xml content-type",
|
||||||
|
"#",
|
||||||
|
"SecRule REQUEST_HEADERS:Content-Type \"text/xml\" \\",
|
||||||
|
" \"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML\"",
|
||||||
|
"",
|
||||||
|
"# Enable JSON request body parser.",
|
||||||
|
"# Initiate JSON Processor in case of JSON content-type; change accordingly",
|
||||||
|
"# if your application does not use 'application/json'",
|
||||||
|
"#",
|
||||||
|
"SecRule REQUEST_HEADERS:Content-Type \"application/json\" \\",
|
||||||
|
" \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"",
|
||||||
|
"",
|
||||||
|
"# Maximum request body size we will accept for buffering. If you support",
|
||||||
|
"# file uploads then the value given on the first line has to be as large",
|
||||||
|
"# as the largest file you are willing to accept. The second value refers",
|
||||||
|
"# to the size of data, with files excluded. You want to keep that value as",
|
||||||
|
"# low as practical.",
|
||||||
|
"#",
|
||||||
|
"SecRequestBodyLimit 13107200",
|
||||||
|
"SecRequestBodyNoFilesLimit 131072",
|
||||||
|
"",
|
||||||
|
"# Store up to 128 KB of request body data in memory. When the multipart",
|
||||||
|
"# parser reachers this limit, it will start using your hard disk for",
|
||||||
|
"# storage. That is slow, but unavoidable.",
|
||||||
|
"#",
|
||||||
|
"SecRequestBodyInMemoryLimit 131072",
|
||||||
|
"",
|
||||||
|
"# What do do if the request body size is above our configured limit.",
|
||||||
|
"# Keep in mind that this setting will automatically be set to ProcessPartial",
|
||||||
|
"# when SecRuleEngine is set to DetectionOnly mode in order to minimize",
|
||||||
|
"# disruptions when initially deploying ModSecurity.",
|
||||||
|
"#",
|
||||||
|
"SecRequestBodyLimitAction Reject",
|
||||||
|
"",
|
||||||
|
"# Verify that we've correctly processed the request body.",
|
||||||
|
"# As a rule of thumb, when failing to process a request body",
|
||||||
|
"# you should reject the request (when deployed in blocking mode)",
|
||||||
|
"# or log a high-severity alert (when deployed in detection-only mode).",
|
||||||
|
"#",
|
||||||
|
"SecRule REQBODY_ERROR \"!\\@eq 0\" ",
|
||||||
|
"\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\"",
|
||||||
|
" "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"response":{
|
||||||
|
"headers":{
|
||||||
|
"Date":"Mon, 13 Jul 2015 20:02:41 GMT",
|
||||||
|
"Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT",
|
||||||
|
"Content-Type":"text/html"
|
||||||
|
},
|
||||||
|
"body":[
|
||||||
|
"no need."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"expected":{
|
||||||
|
"debug_log":"Rule returned 0."
|
||||||
|
},
|
||||||
|
"rules":[
|
||||||
|
"SecRuleEngine On",
|
||||||
|
"SecRequestBodyAccess On",
|
||||||
|
"SecRule REQUEST_BODY \"@fuzzyHash test-cases/data/ssdeep.txt 100\" \"id:1,phase:2,pass,t:trim\""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -12,6 +12,7 @@ modsec_rules_check_LDADD = \
|
|||||||
$(PCRE_LDADD) \
|
$(PCRE_LDADD) \
|
||||||
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
|
||||||
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
|
||||||
|
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
|
||||||
$(LIBXML2_LDADD) \
|
$(LIBXML2_LDADD) \
|
||||||
$(GLOBAL_LDADD)
|
$(GLOBAL_LDADD)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user