Skip to content

Commit

Permalink
Updates / cleanup from Vulture3
Browse files Browse the repository at this point in the history
  • Loading branch information
Jérémie Jourdin committed Aug 9, 2019
1 parent 480df4e commit 95dac03
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 83 deletions.
4 changes: 2 additions & 2 deletions RuleParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ RuleParser::RuleParser() {

libsqliRule.id = 17;
libsqliRule.scores.emplace_back("$LIBINJECTION_SQL", 8);
libsqliRule.action = BLOCK;
libsqliRule.action = LOG;

libxssRule.id = 18;
libxssRule.logMsg = "Libinjection XSS";
libxssRule.scores.emplace_back("$LIBINJECTION_XSS", 8);
libxssRule.action = BLOCK;
libxssRule.action = LOG;
}

unsigned int RuleParser::parseMainRules(vector<string> &ruleLines, string errorMsg) {
Expand Down
13 changes: 10 additions & 3 deletions RuntimeScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* |_| |_| |_|\___/ \__,_|___\__,_|\___|_| \___|_| |_|\__,_|\___|_|
* |_____|
* Copyright (c) 2017 Annihil
* Copyright (c) 2019 Jérémie Jourdin - Advens
* Released under the GPLv3
*/

Expand Down Expand Up @@ -696,12 +697,12 @@ void RuntimeScanner::addHeader(char *key, char *val) {
}
// Store Content-Type for further processing
else if (k == "content-type") {
if (v == "application/x-www-form-urlencoded") {
if (v.substr(0, 33) == "application/x-www-form-urlencoded") {
contentType = CONTENT_TYPE_URL_ENC;
} else if (v.substr(0, 20) == "multipart/form-data;") {
contentType = CONTENT_TYPE_MULTIPART;
rawContentType = string(val); // important: need to keep the case!
} else if (v == "application/json") {
} else if (v.substr(0,16) == "application/json") {
contentType = CONTENT_TYPE_APP_JSON;
}
}
Expand Down Expand Up @@ -954,7 +955,13 @@ void RuntimeScanner::writeJSONLearningLog() {
jsonlog << "\"protocol\":\"" << protocol << "\",";
jsonlog << "\"unparsed_uri\":\"" << fullUri << "\",";
unique_data << "" << uri;
jsonlog << "\"context_id\":\"" << unique_data.str() << "\"";
/*
o This may generate HUGE string - thus causing problem when inserting into databases
o Better approach: Use HASH
*/
std::hash<std::string> hash_fn;
size_t str_hash = hash_fn(unique_data.str());
jsonlog << "\"context_id\":\"" << str_hash << "\"";

jsonlog << "}" << endl;
streamToFile(jsonlog, learningJSONLogFile);
Expand Down
137 changes: 136 additions & 1 deletion mod_defender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,141 @@ static int write_log(void *thefile, const void *buf, size_t *nbytes) {
return apr_file_write((apr_file_t *) thefile, buf, nbytes);
}

/**
* Function from Apache httpd, used to convert 2 chars string into hex int
* Example: "2a" => 0x2a
*/
static char x2c(const char *what)
{
char digit;

#if !APR_CHARSET_EBCDIC
digit = ((what[0] >= 'A') ? ((what[0] & 0xdf) - 'A') + 10
: (what[0] - '0'));
digit *= 16;
digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10
: (what[1] - '0'));
#else /*APR_CHARSET_EBCDIC*/
char xstr[5];
xstr[0]='0';
xstr[1]='x';
xstr[2]=what[0];
xstr[3]=what[1];
xstr[4]='\0';
digit = apr_xlate_conv_byte(ap_hdrs_from_ascii,
0xFF & strtol(xstr, NULL, 16));
#endif /*APR_CHARSET_EBCDIC*/
return (digit);
}

/**
* Function from Apache httpd, used to urldecode string
* The particularity of this function, instead of Apache's, is that the %00 is not interpreted
*/
static int unescape_url(char *url, const char *forbid, const char *reserved)
{
int badesc, badpath;
char *x, *y;

badesc = 0;
badpath = 0;
/* Initial scan for first '%'. Don't bother writing values before
* seeing a '%' */
y = strchr(url, '%');
if (y == NULL) {
return OK;
}
for (x = y; *y; ++x, ++y) {
if (*y != '%') {
*x = *y;
}
else {
if (!apr_isxdigit(*(y + 1)) || !apr_isxdigit(*(y + 2))) {
badesc = 1;
*x = '%';
}
else {
char decoded;
decoded = x2c(y + 1);
if( decoded == '\0' ) {
/* Copy-Paste the %00 - don't interpret ! */
*x++ = *y++;
*x++ = *y++;
*x = *y;
badpath = 1;
} else if( forbid && ap_strchr_c(forbid, decoded) ) {
badpath = 1;
*x = decoded;
y += 2;
}
else if (reserved && ap_strchr_c(reserved, decoded)) {
*x++ = *y++;
*x++ = *y++;
*x = *y;
}
else {
*x = decoded;
y += 2;
}
}
}
}
*x = '\0';
if (badesc) {
return HTTP_BAD_REQUEST;
}
else if (badpath) {
return HTTP_NOT_FOUND;
}
else {
return OK;
}
}

/**
* Function from Apache httpd, used too convert get params as string
* into an apr_table_t struct filled in with key, value pairs GET params
*/
static void argstring_to_table(char *str, apr_table_t *parms)
{
char *key;
char *value;
char *strtok_state;

if (str == NULL) {
return;
}

key = apr_strtok(str, "&", &strtok_state);
while (key) {
value = strchr(key, '=');
if (value) {
*value = '\0'; /* Split the string in two */
value++; /* Skip passed the = */
}
else {
value = (char*)"1";
}
/* Verify return ? */
unescape_url(key, SLASHES, NULL);
unescape_url(value, SLASHES, NULL);
apr_table_set(parms, key, value);
key = apr_strtok(NULL, "&", &strtok_state);
}
}

/**
* Function from Apache httpd, used to convert request GET arguments
* into an apr_table_t struct filled-in with key, value pairs
*/
void args_to_table(request_rec *r, apr_table_t **table)
{
apr_table_t *t = apr_table_make(r->pool, 10);
argstring_to_table(apr_pstrdup(r->pool, r->args), t);
*table = t;
}


/**
* This routine gives our module another chance to examine the request
* headers and to take special action. This is the first phase whose
Expand Down Expand Up @@ -254,7 +389,7 @@ static int header_parser(request_rec *r) {

// Pass GET parameters
apr_table_t *getTable = NULL;
ap_args_to_table(r, &getTable);
args_to_table(r, &getTable);
const apr_array_header_t *getParams = apr_table_elts(getTable);
apr_table_entry_t *getParam = (apr_table_entry_t *) getParams->elts;
for (int i = 0; i < getParams->nelts; i++)
Expand Down
17 changes: 12 additions & 5 deletions mod_defender.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <http_config.h>
#include <http_log.h>
#include <apr_strings.h>
#include <apr_lib.h>
#include <util_script.h>
#include "RuleParser.h"
#include "RuntimeScanner.hpp"
Expand All @@ -45,34 +46,40 @@ extern module AP_MODULE_DECLARE_DATA defender_module;

/**
* \def MAX_BB_SIZE
* The length of the 403 response body, in bytes
* The maximum length of post body processed
*/
#define MAX_BB_SIZE 0x7FFFFFFF

/**
* \def CHUNK_CAPACITY
* The length of the 403 response body, in bytes
* The maximum length of a chunk
*/
#define CHUNK_CAPACITY 8192

/**
* \def IF_STATUS_NONE
* The length of the 403 response body, in bytes
* The status of the body to be processed
*/
#define IF_STATUS_NONE 0

/**
* \def IF_STATUS_WANTS_TO_RUN
* The length of the 403 response body, in bytes
* The status of the body to be processed
*/
#define IF_STATUS_WANTS_TO_RUN 1

/**
* \def IF_STATUS_COMPLETE
* The length of the 403 response body, in bytes
* The status of the body to be processed
*/
#define IF_STATUS_COMPLETE 2

/**
* \def SLASHES
* The slash as string, used to urlencode/decode
*/
#define SLASHES "/"


/**************/
/* Structures */
Expand Down
Loading

0 comments on commit 95dac03

Please sign in to comment.