Accepts Suricata format on @pm operator

This commit is contained in:
Felipe Zimmerle 2015-08-04 11:45:33 -03:00
parent 95efb99a8c
commit d4dd9c86d4
3 changed files with 141 additions and 1 deletions

View File

@ -22,6 +22,7 @@
#include <vector>
#include "operators/operator.h"
#include "utils/acmp.h"
namespace ModSecurity {
namespace operators {
@ -77,6 +78,11 @@ bool Pm::evaluate(Assay *assay, const std::string &input) {
bool Pm::init(const char **error) {
std::vector<std::string> vec;
char *content = parse_pm_content(param.c_str(), param.length(), error);
if (content == NULL) {
return false;
}
std::istringstream iss(param);
std::copy(std::istream_iterator<std::string>(iss),
std::istream_iterator<std::string>(),

View File

@ -15,7 +15,6 @@
/* Aho-Corasick Matching */
#include "acmp.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
@ -24,8 +23,141 @@
#include <stdio.h>
#include <ctype.h>
#include <iostream>
#include <string>
#include <vector>
/**
* TODO: This code comes from ModSecurity 2.9.0 there are two memory leaks here
* that should be mitigated. This ACMP parser should be re-written to
* consume less memory.
*/
extern "C" {
char *parse_pm_content(const char *op_parm, unsigned short int op_len, const char **error_msg) {
char *parm = NULL;
char *content = NULL;
unsigned short int offset = 0;
char converted = 0;
int i, x;
unsigned char bin = 0, esc = 0, bin_offset = 0;
unsigned char bin_parm[3], c = 0;
char *processed = NULL;
content = strdup(op_parm);
if (content == NULL) {
*error_msg = std::string("Error allocating memory for pattern matching content.").c_str();
return NULL;
}
while (offset < op_len && content[offset] == ' ' || content[offset] == '\t') {
offset++;
};
op_len = strlen(content);
if (content[offset] == '\"' && content[op_len-1] == '\"') {
parm = strdup(content + offset + 1);
if (parm == NULL) {
*error_msg = std::string("Error allocating memory for pattern matching content.").c_str();
free(content);
content = NULL;
return NULL;
}
parm[op_len - offset - 2] = '\0';
} else {
parm = strdup(content + offset);
if (parm == NULL) {
free(content);
content = NULL;
*error_msg = std::string("Error allocating memory for pattern matching content.").c_str();
return NULL;
}
}
free(content);
content = NULL;
op_len = strlen(parm);
if (op_len == 0) {
*error_msg = "Content length is 0.";
return NULL;
}
for (i = 0, x = 0; i < op_len; i++) {
if (parm[i] == '|') {
if (bin) {
bin = 0;
} else {
bin = 1;
}
} else if(!esc && parm[i] == '\\') {
esc = 1;
} else {
if (bin) {
if (parm[i] == 0 || parm[i] == 1 || parm[i] == 2 ||
parm[i] == 3 || parm[i] == 4 || parm[i] == 5 ||
parm[i] == 6 || parm[i] == 7 || parm[i] == 8 ||
parm[i] == 9 ||
parm[i] == 'A' || parm[i] == 'a' ||
parm[i] == 'B' || parm[i] == 'b' ||
parm[i] == 'C' || parm[i] == 'c' ||
parm[i] == 'D' || parm[i] == 'd' ||
parm[i] == 'E' || parm[i] == 'e' ||
parm[i] == 'F' || parm[i] == 'f')
{
bin_parm[bin_offset] = (char)parm[i];
bin_offset++;
if (bin_offset == 2) {
c = strtol((char *)bin_parm, (char **) NULL, 16) & 0xFF;
bin_offset = 0;
parm[x] = c;
x++;
converted = 1;
}
} else if (parm[i] == ' ') {
}
} else if (esc) {
if (parm[i] == ':' ||
parm[i] == ';' ||
parm[i] == '\\' ||
parm[i] == '\"')
{
parm[x] = parm[i];
x++;
} else {
*error_msg = std::string("Unsupported escape sequence.").c_str();
return NULL;
}
esc = 0;
converted = 1;
} else {
parm[x] = parm[i];
x++;
}
}
}
if (converted) {
op_len = x;
}
//processed = memcpy(processed, parm, op_len);
processed = strdup(parm);
free(parm);
parm = NULL;
if (processed == NULL) {
*error_msg = std::string("Error allocating memory for pattern matching content.").c_str();
return NULL;
}
return processed;
}
/*
*******************************************************************************
*******************************************************************************

View File

@ -189,6 +189,8 @@ int acmp_process_quick(ACMPT *acmpt, const char **match, const char *data, size_
*/
int acmp_prepare(ACMP *parser);
char *parse_pm_content(const char *op_parm, unsigned short int op_len, const char **error_msg);
}
#endif /*ACMP_H_*/