Adds support for @fuzzyHash

Issue #997
This commit is contained in:
Felipe Zimmerle 2017-10-25 19:11:09 -03:00
parent 4ecfed3163
commit 7622866f97
No known key found for this signature in database
GPG Key ID: E6DFB08CE8B11277
20 changed files with 1234 additions and 719 deletions

View File

@ -2,6 +2,8 @@
v3.0.????? - ?
---------------------------
- Adds support for @fuzzyHash operator.
[Issue #997 - @zimmerle]
- Fix build on non x86 arch build
[Issue #1598 - @athmane]
- Fix memory issue while changing rule target dynamic

View File

@ -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-id.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
View 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]

View File

@ -86,6 +86,10 @@ AM_CONDITIONAL([GEOIP_CFLAGS], [test "GEOIP_CFLAGS" != ""])
PROG_LMDB
AM_CONDITIONAL([LMDB_CFLAGS], [test "LMDB_CFLAGS" != ""])
# Check for SSDEEP
CHECK_SSDEEP
AM_CONDITIONAL([SSDEEP_CFLAGS], [test "SSDEEP_CFLAGS" != ""])
#
# Check for curl
#
@ -483,6 +487,24 @@ if test "x$LIBXML2_FOUND" = "x2"; then
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 " Other Options"
if test $buildTestUtilities = true; then

View File

@ -11,6 +11,7 @@ multi_LDADD = \
-lpthread \
$(YAJL_LDFLAGS) \
$(GEOIP_LDFLAGS) \
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
$(GLOBAL_LDADD)
multi_CFLAGS = \

View File

@ -13,6 +13,7 @@ simple_request_LDADD = \
$(PCRE_LDADD) \
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
$(LIBXML2_LDADD) \
$(GLOBAL_LDADD)

View File

@ -12,6 +12,7 @@ read_LDADD = \
$(PCRE_LDADD) \
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
$(LIBXML2_LDADD) \
$(GLOBAL_LDADD)

View File

@ -10,6 +10,7 @@ test_LDADD = \
-lmodsecurity \
$(YAJL_LDFLAGS) \
$(GEOIP_LDFLAGS) \
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
$(GLOBAL_LDADD)
test_CFLAGS = \

View File

@ -13,6 +13,7 @@ simple_request_LDADD = \
$(PCRE_LDADD) \
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
$(LIBXML2_LDADD) \
$(GLOBAL_LDADD)

View File

@ -297,6 +297,7 @@ libmodsecurity_la_CPPFLAGS = \
$(YAJL_CFLAGS) \
$(LMDB_CFLAGS) \
$(PCRE_CFLAGS) \
$(SSDEEP_CFLAGS) \
$(LIBXML2_CFLAGS)
libmodsecurity_la_LIBADD = \
@ -306,6 +307,7 @@ libmodsecurity_la_LIBADD = \
$(PCRE_LDADD) \
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
$(LIBXML2_LDADD) \
../others/libinjection.la \
../others/libmbedtls.la

View File

@ -19,16 +19,96 @@
#include "src/operators/operator.h"
#include "src/macro_expansion.h"
#include "src/utils/system.h"
namespace modsecurity {
namespace operators {
bool FuzzyHash::evaluate(Transaction *transaction, const std::string &str) {
/**
* @todo Implement the operator FuzzyHash.
* Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#fuzzyhash
*/
bool FuzzyHash::init(const std::string &param2, std::string *error) {
#ifdef WITH_SSDEEP
std::string digit;
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;
#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

View File

@ -18,20 +18,38 @@
#include <string>
#include "src/operators/operator.h"
#ifdef WITH_SSDEEP
#include "fuzzy.h"
#endif
#include "src/operators/operator.h"
namespace modsecurity {
namespace operators {
struct fuzzy_hash_chunk {
const char *data;
struct fuzzy_hash_chunk *next;
};
class FuzzyHash : public Operator {
public:
/** @ingroup ModSecurity_Operator */
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)
: Operator("FuzzyHash", param) { }
: Operator("FuzzyHash", param),
m_head(NULL),
m_threshold(0) { }
bool evaluate(Transaction *transaction, const std::string &std) override;
bool init(const std::string &param, std::string *error) override;
private:
int m_threshold;
struct fuzzy_hash_chunk *m_head;
};
} // namespace operators

File diff suppressed because it is too large Load Diff

View File

@ -910,8 +910,12 @@ op_before_init:
}
| OPERATOR_FUZZY_HASH FREE_TEXT
{
/* $$ = new operators::FuzzyHash(); */
OPERATOR_NOT_SUPPORTED("FuzzyHash", @0);
OPERATOR_CONTAINER($$, new operators::FuzzyHash(utils::string::removeBracketsIfNeeded($2)));
std::string error;
if ($$->init(driver.ref.back(), &error) == false) {
driver.error(@0, error);
YYERROR;
}
}
| OPERATOR_VALIDATE_BYTE_RANGE FREE_TEXT
{

View File

@ -44,6 +44,7 @@ unit_tests_LDADD = \
$(PCRE_LDADD) \
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
$(LIBXML2_LDADD) \
$(GLOBAL_LDADD)
@ -80,6 +81,7 @@ regression_tests_LDADD = \
$(PCRE_LDADD) \
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
$(LIBXML2_LDADD) \
$(GLOBAL_LDADD)
@ -115,6 +117,7 @@ rules_optimization_LDADD = \
$(PCRE_LDADD) \
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
$(LIBXML2_LDADD) \
$(GLOBAL_LDADD)

View File

@ -12,6 +12,7 @@ benchmark_LDADD = \
$(PCRE_LDADD) \
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
$(LIBXML2_LDADD) \
$(GLOBAL_LDADD)

View File

@ -20,6 +20,7 @@ afl_fuzzer_LDADD = \
$(PCRE_LDADD) \
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
$(LIBXML2_LDADD) \
$(top_builddir)/src/.libs/libmodsecurity.a \
$(top_builddir)/others/libinjection.la \

View 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"

View 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\""
]
}
]

View File

@ -12,6 +12,7 @@ modsec_rules_check_LDADD = \
$(PCRE_LDADD) \
$(YAJL_LDFLAGS) $(YAJL_LDADD) \
$(LMDB_LDFLAGS) $(LMDB_LDADD) \
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
$(LIBXML2_LDADD) \
$(GLOBAL_LDADD)