From a05fa8287bf0c38e1e5c5f18aff2d9fba83c6efd Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Mon, 27 Jul 2015 22:44:42 -0300 Subject: [PATCH] Adds support to the validateByteRange operator --- src/operators/validate_byte_range.cc | 106 ++++++++++++++++++++++++--- src/operators/validate_byte_range.h | 13 +++- 2 files changed, 107 insertions(+), 12 deletions(-) diff --git a/src/operators/validate_byte_range.cc b/src/operators/validate_byte_range.cc index 1f9eda14..db350ae6 100644 --- a/src/operators/validate_byte_range.cc +++ b/src/operators/validate_byte_range.cc @@ -22,21 +22,107 @@ namespace ModSecurity { namespace operators { -bool ValidateByteRange::evaluate(Assay *assay) { - /** - * @todo Implement the operator ValidateByteRange. - * Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#validateByteRange - */ +bool ValidateByteRange::getRange(const std::string &rangeRepresentation, + const char **error) { + size_t pos = param.find_first_of("-"); + int start; + int end; + + if (pos == std::string::npos) { + try { + start = std::stoi(rangeRepresentation); + } catch(...) { + *error = ("Not able to convert '" + rangeRepresentation + "' into a number").c_str(); + return false; + } + table[start >> 3] = (table[start >> 3] | (1 << (start & 0x7))); + return true; + } + + try { + start = std::stoi(std::string(rangeRepresentation, 0, pos)); + } catch (...) { + *error = ("Not able to convert '" + std::string(rangeRepresentation, 0, pos) + "' into a number").c_str(); + return false; + } + + try { + end = std::stoi(std::string(rangeRepresentation, pos + 1, + rangeRepresentation.length() - (pos + 1))); + } catch (...) { + *error = ("Not able to convert '" + std::string(rangeRepresentation, pos + 1, + rangeRepresentation.length() - (pos + 1)) + "' into a number").c_str(); + return false; + } + + if ((start < 0) || (start > 255)) { + *error = ("Invalid range start value: " + std::to_string(start)).c_str(); + return false; + } + if ((end < 0) || (end > 255)) { + *error = ("Invalid range end value: " + std::to_string(end)).c_str(); + return false; + } + if (start > end) { + *error = ("Invalid range: " + std::to_string(start) + "-" + + std::to_string(end)).c_str(); + return false; + } + + while(start <= end) { + table[start >> 3] = (table[start >> 3] | (1 << (start & 0x7))); + start++; + } + return true; } -ValidateByteRange::ValidateByteRange(std::string op, std::string param, - bool negation) - : Operator() { - this->op = op; - this->param = param; +bool ValidateByteRange::init(const char **error) { + size_t pos = param.find_first_of(","); + + if (pos == std::string::npos) { + getRange(param, error); + } + + while (pos != std::string::npos) { + size_t next_pos = param.find_first_of(",", pos + 1); + if (next_pos == std::string::npos) { + getRange(std::string(param, pos + 1, param.length() - (pos + 1)), error); + } else { + getRange(std::string(param, pos + 1, next_pos), error); + } + pos = next_pos; + } } + + +bool ValidateByteRange::evaluate(Assay *assay, const std::string &input) { + bool ret = true; + + size_t count = 0; + for(int i = 0; i < input.length(); i++) { + int x = input.at(i); + if (!(table[x >> 3] & (1 << (x & 0x7)))) { + //debug(9, "Value " + std::to_string(x) + " in " + input + " ouside range: " + param); + count++; + } + } + + ret = (count != 0); + //if (count == 0) return 0; + + //debug(9, "Found %d byte(s) in %s outside range: %s.", + //count, var->name, rule->op_param); + + if (negation) { + return !ret; + } + + return ret; +} + + } // namespace operators } // namespace ModSecurity diff --git a/src/operators/validate_byte_range.h b/src/operators/validate_byte_range.h index 82709dad..bbfbf38c 100644 --- a/src/operators/validate_byte_range.h +++ b/src/operators/validate_byte_range.h @@ -27,8 +27,17 @@ namespace operators { class ValidateByteRange : public Operator { public: /** @ingroup ModSecurity_Operator */ - ValidateByteRange(std::string o, std::string p, bool i); - bool evaluate(Assay *assay); + ValidateByteRange(std::string op, std::string param, bool negation) + : Operator(op, param, negation) { } + + ~ValidateByteRange() override { } + + bool evaluate(Assay *assay, const std::string &input) override; + bool getRange(const std::string &rangeRepresentation, const char **error); + bool init(const char **error) override; + private: + std::vector ranges; + char table[32]; }; } // namespace operators