Adds support to sqlHexDecode transformation

Issue #973
This commit is contained in:
Felipe Zimmerle 2016-05-25 20:16:29 -03:00
parent bd2e95953c
commit 1fe0e34201
4 changed files with 79 additions and 18 deletions

View File

@ -24,31 +24,83 @@
#include "modsecurity/transaction.h" #include "modsecurity/transaction.h"
#include "actions/transformations/transformation.h" #include "actions/transformations/transformation.h"
#include "src/utils.h"
namespace modsecurity { namespace modsecurity {
namespace actions { namespace actions {
namespace transformations { namespace transformations {
SqlHexDecode::SqlHexDecode(std::string action) #ifndef VALID_HEX
: Transformation(action) { #define VALID_HEX(X) (((X >= '0') && (X <= '9')) \
this->action_kind = 1; || ((X >= 'a') && (X <= 'f')) \
} || ((X >= 'A') && (X <= 'F')))
#endif
#ifndef ISODIGIT
#define ISODIGIT(X) ((X >= '0') && (X <= '7'))
#endif
std::string SqlHexDecode::evaluate(std::string value, std::string SqlHexDecode::evaluate(std::string value,
Transaction *transaction) { Transaction *transaction) {
/** std::string ret;
* @todo Implement the transformation SqlHexDecode unsigned char *input = NULL;
*/ int size = 0;
if (transaction) {
#ifndef NO_LOGS input = reinterpret_cast<unsigned char *>
transaction->debug(4, "Transformation SqlHexDecode " \ (malloc(sizeof(char) * value.length()+1));
"is not implemented yet.");
#endif if (input == NULL) {
return "";
} }
return value;
memcpy(input, value.c_str(), value.length()+1);
size = inplace(input, value.length());
ret.assign(reinterpret_cast<char *>(input), size);
free(input);
return ret;
} }
int SqlHexDecode::inplace(unsigned char *data, int len) {
unsigned char *d, *begin = data;
if ((data == NULL) || (len == 0)) {
return 0;
}
for (d = data; *data; *d++ = *data++) {
if (*data != '0') {
continue;
}
++data;
if (mytolower(*data) != 'x') {
data--;
continue;
}
data++;
// Do we need to keep "0x" if no hexa after?
if (!VALID_HEX(data[0]) || !VALID_HEX(data[1])) {
data -= 2;
continue;
}
while (VALID_HEX(data[0]) && VALID_HEX(data[1])) {
*d++ = x2c(data);
data += 2;
}
}
*d = '\0';
return strlen(reinterpret_cast<char *>(begin));
}
} // namespace transformations } // namespace transformations
} // namespace actions } // namespace actions
} // namespace modsecurity } // namespace modsecurity

View File

@ -30,10 +30,19 @@ namespace transformations {
class SqlHexDecode : public Transformation { class SqlHexDecode : public Transformation {
public: public:
explicit SqlHexDecode(std::string action); explicit SqlHexDecode(std::string action) : Transformation(action) { }
std::string
evaluate(std::string exp, std::string evaluate(std::string exp,
Transaction *transaction) override; Transaction *transaction) override;
static int inplace(unsigned char *data, int len);
static int mytolower(int ch) {
if (ch >= 'A' && ch <= 'Z')
return ('a' + ch - 'A');
else
return ch;
}
}; };
} // namespace transformations } // namespace transformations

View File

@ -105,7 +105,7 @@ Transformation* Transformation::instantiate(std::string a) {
IF_MATCH(replaceComments) { return new ReplaceComments(a); } IF_MATCH(replaceComments) { return new ReplaceComments(a); }
IF_MATCH(replaceNulls) { return new ReplaceNulls(a); } IF_MATCH(replaceNulls) { return new ReplaceNulls(a); }
IF_MATCH(sha1) { return new Sha1(a); } IF_MATCH(sha1) { return new Sha1(a); }
IF_MATCH(sql_hex_decode) { return new SqlHexDecode(a); } IF_MATCH(sqlHexDecode) { return new SqlHexDecode(a); }
IF_MATCH(transformation) { return new Transformation(a); } IF_MATCH(transformation) { return new Transformation(a); }
IF_MATCH(trimLeft) { return new TrimLeft(a); } IF_MATCH(trimLeft) { return new TrimLeft(a); }
IF_MATCH(trimRight) { return new TrimRight(a); } IF_MATCH(trimRight) { return new TrimRight(a); }

@ -1 +1 @@
Subproject commit ca597a23aa6eca03757c612543802fcdb884f135 Subproject commit 002eb1e668b7a017eecfdfe9c5415fb9921c0be4