From 8d499032794856ce3004f0142328539560be61ff Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Fri, 27 May 2016 10:45:05 -0300 Subject: [PATCH] Adds support to the transformations parity[even|odd|zero]7bit Issues: #968, #969, #967 --- .../transformations/parity_even_7bit.cc | 53 ++++++++++++++----- .../transformations/parity_even_7bit.h | 7 +-- .../transformations/parity_odd_7bit.cc | 52 +++++++++++++----- src/actions/transformations/parity_odd_7bit.h | 7 +-- .../transformations/parity_zero_7bit.cc | 44 ++++++++++----- .../transformations/parity_zero_7bit.h | 7 +-- src/actions/transformations/transformation.cc | 6 +-- src/parser/seclang-scanner.ll | 2 +- 8 files changed, 126 insertions(+), 52 deletions(-) diff --git a/src/actions/transformations/parity_even_7bit.cc b/src/actions/transformations/parity_even_7bit.cc index a004842e..2ca037f0 100644 --- a/src/actions/transformations/parity_even_7bit.cc +++ b/src/actions/transformations/parity_even_7bit.cc @@ -30,25 +30,52 @@ namespace modsecurity { namespace actions { namespace transformations { -ParityEven7bit::ParityEven7bit(std::string action) - : Transformation(action) { - this->action_kind = 1; -} std::string ParityEven7bit::evaluate(std::string value, Transaction *transaction) { - /** - * @todo Implement the transformation ParityEven7bit - */ - if (transaction) { -#ifndef NO_LOGS - transaction->debug(4, "Transformation ParityEven7bit is not" \ - " implemented yet."); -#endif + std::string ret; + unsigned char *input = NULL; + + input = reinterpret_cast + (malloc(sizeof(char) * value.length()+1)); + + if (input == NULL) { + return ""; } - return value; + + memcpy(input, value.c_str(), value.length()+1); + + inplace(input, value.length()); + + ret.assign(reinterpret_cast(input), value.length()); + free(input); + + return ret; } +bool ParityEven7bit::inplace(unsigned char *input, u_int64_t input_len) { + u_int64_t i; + + i = 0; + while (i < input_len) { + unsigned int x = input[i]; + + input[i] ^= input[i] >> 4; + input[i] &= 0xf; + + if ((0x6996 >> input[i]) & 1) { + input[i] = x | 0x80; + } else { + input[i] = x & 0x7f; + } + i++; + } + + return true; +} + + + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/parity_even_7bit.h b/src/actions/transformations/parity_even_7bit.h index a80b8680..c914d70f 100644 --- a/src/actions/transformations/parity_even_7bit.h +++ b/src/actions/transformations/parity_even_7bit.h @@ -30,9 +30,10 @@ namespace transformations { class ParityEven7bit : public Transformation { public: - explicit ParityEven7bit(std::string action); - std::string evaluate(std::string exp, - Transaction *transaction) override; + explicit ParityEven7bit(std::string action) : Transformation(action) { } + + std::string evaluate(std::string exp, Transaction *transaction) override; + static bool inplace(unsigned char *input, u_int64_t input_len); }; } // namespace transformations diff --git a/src/actions/transformations/parity_odd_7bit.cc b/src/actions/transformations/parity_odd_7bit.cc index df198eca..eb515563 100644 --- a/src/actions/transformations/parity_odd_7bit.cc +++ b/src/actions/transformations/parity_odd_7bit.cc @@ -30,25 +30,51 @@ namespace modsecurity { namespace actions { namespace transformations { -ParityOdd7bit::ParityOdd7bit(std::string action) - : Transformation(action) { - this->action_kind = 1; -} std::string ParityOdd7bit::evaluate(std::string value, Transaction *transaction) { - /** - * @todo Implement the transformation ParityOdd7bit - */ - if (transaction) { -#ifndef NO_LOGS - transaction->debug(4, "Transformation ParityOdd7bit is not " \ - "implemented yet."); -#endif + std::string ret; + unsigned char *input = NULL; + + input = reinterpret_cast + (malloc(sizeof(char) * value.length()+1)); + + if (input == NULL) { + return ""; } - return value; + + memcpy(input, value.c_str(), value.length()+1); + + inplace(input, value.length()); + + ret.assign(reinterpret_cast(input), value.length()); + free(input); + + return ret; } +bool ParityOdd7bit::inplace(unsigned char *input, u_int64_t input_len) { + u_int64_t i; + + i = 0; + while (i < input_len) { + unsigned int x = input[i]; + + input[i] ^= input[i] >> 4; + input[i] &= 0xf; + + if ((0x6996 >> input[i]) & 1) { + input[i] = x & 0x7f; + } else { + input[i] = x | 0x80; + } + i++; + } + + return true; +} + + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/parity_odd_7bit.h b/src/actions/transformations/parity_odd_7bit.h index 1ade4e6d..2ebdac75 100644 --- a/src/actions/transformations/parity_odd_7bit.h +++ b/src/actions/transformations/parity_odd_7bit.h @@ -30,9 +30,10 @@ namespace transformations { class ParityOdd7bit : public Transformation { public: - explicit ParityOdd7bit(std::string action); - std::string evaluate(std::string exp, - Transaction *transaction) override; + explicit ParityOdd7bit(std::string action) : Transformation(action) { } + + std::string evaluate(std::string exp, Transaction *transaction) override; + static bool inplace(unsigned char *input, u_int64_t input_len); }; } // namespace transformations diff --git a/src/actions/transformations/parity_zero_7bit.cc b/src/actions/transformations/parity_zero_7bit.cc index 0dbc1ba8..639927c4 100644 --- a/src/actions/transformations/parity_zero_7bit.cc +++ b/src/actions/transformations/parity_zero_7bit.cc @@ -30,25 +30,43 @@ namespace modsecurity { namespace actions { namespace transformations { -ParityZero7bit::ParityZero7bit(std::string action) - : Transformation(action) { - this->action_kind = 1; -} std::string ParityZero7bit::evaluate(std::string value, Transaction *transaction) { - /** - * @todo Implement the transformation ParityZero7bit - */ - if (transaction) { -#ifndef NO_LOGS - transaction->debug(4, "Transformation ParityZero7bit is not" \ - "implemented yet."); -#endif + std::string ret; + unsigned char *input = NULL; + + input = reinterpret_cast + (malloc(sizeof(char) * value.length()+1)); + + if (input == NULL) { + return ""; } - return value; + + memcpy(input, value.c_str(), value.length()+1); + + inplace(input, value.length()); + + ret.assign(reinterpret_cast(input), value.length()); + free(input); + + return ret; } + +bool ParityZero7bit::inplace(unsigned char *input, u_int64_t input_len) { + u_int64_t i; + + i = 0; + while (i < input_len) { + input[i] &= 0x7f; + i++; + } + + return true; +} + + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/parity_zero_7bit.h b/src/actions/transformations/parity_zero_7bit.h index 7a769555..e69e5312 100644 --- a/src/actions/transformations/parity_zero_7bit.h +++ b/src/actions/transformations/parity_zero_7bit.h @@ -30,9 +30,10 @@ namespace transformations { class ParityZero7bit : public Transformation { public: - explicit ParityZero7bit(std::string action); - std::string evaluate(std::string exp, - Transaction *transaction) override; + explicit ParityZero7bit(std::string action) : Transformation(action) { } + + std::string evaluate(std::string exp, Transaction *transaction) override; + static bool inplace(unsigned char *input, u_int64_t input_len); }; } // namespace transformations diff --git a/src/actions/transformations/transformation.cc b/src/actions/transformations/transformation.cc index 9b06b7ac..cf5c87d1 100644 --- a/src/actions/transformations/transformation.cc +++ b/src/actions/transformations/transformation.cc @@ -94,9 +94,9 @@ Transformation* Transformation::instantiate(std::string a) { IF_MATCH(normalizePath) { return new NormalisePath(a); } IF_MATCH(normalisePath) { return new NormalisePath(a); } IF_MATCH(normalisePath) { return new NormalisePath(a); } - IF_MATCH(parity_even_7bit) { return new ParityEven7bit(a); } - IF_MATCH(parity_odd_7bit) { return new ParityOdd7bit(a); } - IF_MATCH(parity_zero_7bit) { return new ParityZero7bit(a); } + IF_MATCH(parityEven7bit) { return new ParityEven7bit(a); } + IF_MATCH(parityOdd7bit) { return new ParityOdd7bit(a); } + IF_MATCH(parityZero7bit) { return new ParityZero7bit(a); } IF_MATCH(removeCommentsChar) { return new RemoveCommentsChar(a); } IF_MATCH(removeComments) { return new RemoveComments(a); } IF_MATCH(removeNulls) { return new RemoveNulls(a); } diff --git a/src/parser/seclang-scanner.ll b/src/parser/seclang-scanner.ll index 66358004..9e86ad6b 100755 --- a/src/parser/seclang-scanner.ll +++ b/src/parser/seclang-scanner.ll @@ -115,7 +115,7 @@ OPERATOR (?i:(?:@inspectFile|@fuzzyHash|@validateByteRange|@validateDTD|@ OPERATORNOARG (?i:@detectSQLi|@detectXSS|@validateUrlEncoding|@validateUtf8Encoding) OPERATOR_GEOIP (?i:@geoLookup) -TRANSFORMATION t:(?i:(sqlHexDecode|cmdLine|sha1|md5|hexEncode|lowercase|urlDecodeUni|urlDecode|none|compressWhitespace|removeWhitespace|replaceNulls|removeNulls|htmlEntityDecode|jsDecode|cssDecode|trim|normalizePathWin|normalisePathWin|normalisePath|length|utf8toUnicode|urldecode|removeCommentsChar|removeComments|replaceComments)) +TRANSFORMATION t:(?i:(parityZero7bit|parityOdd7bit|parityEven7bit|sqlHexDecode|cmdLine|sha1|md5|hexEncode|lowercase|urlDecodeUni|urlDecode|none|compressWhitespace|removeWhitespace|replaceNulls|removeNulls|htmlEntityDecode|jsDecode|cssDecode|trim|normalizePathWin|normalisePathWin|normalisePath|length|utf8toUnicode|urldecode|removeCommentsChar|removeComments|replaceComments)) VARIABLE (?i:(RESOURCE|ARGS_COMBINED_SIZE|ARGS_GET_NAMES|ARGS_POST_NAMES|FILES_COMBINED_SIZE|FULL_REQUEST_LENGTH|REQUEST_BODY_LENGTH|REQUEST_URI_RAW|UNIQUE_ID|SERVER_PORT|SERVER_ADDR|REMOTE_PORT|REMOTE_HOST|MULTIPART_STRICT_ERROR|PATH_INFO|MULTIPART_CRLF_LF_LINES|MATCHED_VAR_NAME|MATCHED_VAR|INBOUND_DATA_ERROR|OUTBOUND_DATA_ERROR|FULL_REQUEST|AUTH_TYPE|ARGS_NAMES|REMOTE_ADDR|REQUEST_BASENAME|REQUEST_BODY|REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_METHOD|REQUEST_PROTOCOL|REQUEST_URI|RESPONSE_BODY|RESPONSE_CONTENT_LENGTH|RESPONSE_CONTENT_TYPE|RESPONSE_HEADERS_NAMES|RESPONSE_PROTOCOL|RESPONSE_STATUS|REQBODY_PROCESSOR|USERID|SESSIONID))