Skip to content

Commit

Permalink
Merge pull request #2 from VultureProject/devel
Browse files Browse the repository at this point in the history
Master bug fix on POST data retrieving
  • Loading branch information
HugoSoszynski authored May 7, 2018
2 parents 9efbe6e + 2b628d6 commit 480df4e
Show file tree
Hide file tree
Showing 18 changed files with 1,369 additions and 261 deletions.
78 changes: 23 additions & 55 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,77 +1,45 @@
language: cpp
sudo: required

os: linux
dist: trusty
sudo: required

language: cpp
compiler: gcc

addons:
apt:
packages:
- apache2
- apache2-dev
- g++-5
- gcc-5
- g++-6
- gcc-6
sources:
- ubuntu-toolchain-r-test

before_install:

install:
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 90
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-6 90
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 90

matrix:
allow_failures:
exclude:
- compiler: "gcc"

before_script:
- sudo mkdir /etc/defender/
- >
sudo wget -O /etc/defender/core.rules
https://raw.githubusercontent.com/nbs-system/naxsi/master/naxsi_config/naxsi_core.rules
- sudo sed -i "s/select|union|update|delete|insert|table|from|ascii|hex|unhex|drop/\\\b(select|union|update|delete|insert|table|from|ascii|hex|unhex|drop)\\\b/" /etc/defender/core.rules
- >
printf
"LoadModule defender_module /usr/lib/apache2/modules/mod_defender.so
<IfModule defender_module>
Include /etc/defender/core.rules
</IfModule>" | sudo tee /etc/apache2/mods-available/defender.load
- sudo apachectl -v
- sudo apachectl -M
- sudo a2enmod defender
- sudo service apache2 stop
- >
printf
"<VirtualHost *:80>
LogLevel notice
ErrorLog \${APACHE_LOG_DIR}/error.log
AllowEncodedSlashes On
<Location />
<IfModule defender_module>
Defender On
MatchLog \${APACHE_LOG_DIR}/defender_match.log
JSONMatchLog \${APACHE_LOG_DIR}/defender_json_match.log
RequestBodyLimit 8388608
LearningMode Off
ExtensiveLog Off
LibinjectionSQL Off
LibinjectionXSS Off
CheckRule \"\$SQL >= 8\" BLOCK
CheckRule \"\$RFI >= 8\" BLOCK
CheckRule \"\$TRAVERSAL >= 4\" BLOCK
CheckRule \"\$EVADE >= 4\" BLOCK
CheckRule \"\$XSS >= 8\" BLOCK
CheckRule \"\$UPLOAD >= 8\" BLOCK
</IfModule>
</Location>
</VirtualHost>" | sudo tee /etc/apache2/sites-available/000-default.conf
include:
- os: linux
compiler: "gcc"
env: RUN="basic.sh"

- os: linux
compiler: "gcc"
env: RUN="https.sh"

script:
- cmake -H. -Bbuild
- cmake --build build
- sudo cp build/mod_defender.so /usr/lib/apache2/modules/
- sudo service apache2 start
- cd tests/
- bash core.sh localhost
- bash internal.sh localhost
- /bin/bash ./tests/travis/do_run.sh

after_script:
- sudo cat /var/log/apache2/error.log
- sudo cat /var/log/apache2/defender_match.log
- sudo head /var/log/apache2/defender_json_match.log
# - sudo cat /var/log/apache2/defender_match.log
- sudo cat /var/log/apache2/defender_json_match.log
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ set(CMAKE_SHARED_LIBRARY_PREFIX "")

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules")

set(CMAKE_CXX_FLAGS "-W -Wall -Wextra")

message("FLAGS = ${CMAKE_CXX_FLAGS}")

find_package(Apache)
find_package(Apr)

Expand Down
24 changes: 13 additions & 11 deletions RuleParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,12 @@ unsigned int RuleParser::parseBasicRules(vector<string> &ruleLines, string error
if (rulePart.substr(0, 3) == "wl:") {
string rawWhitelist = rulePart.substr(3);
rule.wlIds = splitToInt(rawWhitelist, ',');
#ifdef DEBUG_CONFIG_BASICRULE
DEBUG_CONF_BR("wl='");
for (const int &id : rule.wlIds)
DEBUG_CONF_BR(id << ".");
DEBUG_CONF_BR("' ");
#endif // !DEBUG_CONFIG_BASICRULE
} else if (rulePart.substr(0, 3) == "mz:") {
string rawMatchZone = rulePart.substr(3);
parseMatchZone(rule, rawMatchZone, err);
Expand Down Expand Up @@ -371,7 +373,8 @@ void RuleParser::wlrIdentify(const http_rule_t &curr, MATCH_ZONE &zone, int &uri
else if (curr.br.fileExtMz)
zone = FILE_EXT;

for (int i = 0; i < curr.br.customLocations.size(); i++) {
size_t i = 0;
for ( i = 0; i < curr.br.customLocations.size(); i++) {
const custom_rule_location_t &loc = curr.br.customLocations[i];
if (loc.specificUrl) {
uriIndex = i;
Expand Down Expand Up @@ -530,7 +533,7 @@ void RuleParser::generateHashTables() {
bool RuleParser::checkIds(unsigned long matchId, const vector<int> &wlIds) {
bool negative = false;

for (const int &wlId : wlIds) {
for (auto &wlId : wlIds) {
if (wlId == matchId)
return true;
if (wlId == 0) // WHY ??
Expand All @@ -544,9 +547,8 @@ bool RuleParser::checkIds(unsigned long matchId, const vector<int> &wlIds) {
return negative;
}

bool RuleParser::isWhitelistAdapted(whitelist_rule_t &wlrule, const string &name, MATCH_ZONE zone,
const http_rule_t &rule,
MATCH_TYPE type, bool targetName) {
bool RuleParser::isWhitelistAdapted(whitelist_rule_t &wlrule, MATCH_ZONE zone, const http_rule_t &rule, MATCH_TYPE type,
bool targetName) {
if (zone == FILE_EXT)
zone = BODY; // FILE_EXT zone is just a hack, as it indeed targets BODY

Expand Down Expand Up @@ -657,13 +659,13 @@ bool RuleParser::isRuleWhitelisted(const http_rule_t &rule, const string &uri, c
if (name.length() > 0) {
/* try to find in hashtables */
bool found = findWlInHash(wlRule, name, zone);
if (found && isWhitelistAdapted(wlRule, name, zone, rule, NAME_ONLY, targetName))
if (found && isWhitelistAdapted(wlRule, zone, rule, NAME_ONLY, targetName))
return true;

string hashname = "#" + name;
DEBUG_CONF_WL("hashing varname [" << name << "] (rule:" << rule.id << ") - 'wl:X_VAR:" << name << "%V|NAME'");
found = findWlInHash(wlRule, hashname, zone);
if (found && isWhitelistAdapted(wlRule, name, zone, rule, NAME_ONLY, targetName))
if (found && isWhitelistAdapted(wlRule, zone, rule, NAME_ONLY, targetName))
return true;
}

Expand All @@ -682,21 +684,21 @@ bool RuleParser::isRuleWhitelisted(const http_rule_t &rule, const string &uri, c
found = true;
}

if (found && isWhitelistAdapted(wlRule, name, zone, rule, URI_ONLY, targetName))
if (found && isWhitelistAdapted(wlRule, zone, rule, URI_ONLY, targetName))
return true;
}

/* Lookup for $URL|URL (uri)*/
DEBUG_CONF_WL("hashing uri#1 [" << uri << "] (rule:" << rule.id << ") ($URL:X|URI)");
bool found = findWlInHash(wlRule, uri, zone);
if (found && isWhitelistAdapted(wlRule, name, zone, rule, URI_ONLY, targetName))
if (found && isWhitelistAdapted(wlRule, zone, rule, URI_ONLY, targetName))
return true;

/* Looking $URL:x|ZONE|NAME */
string hashname = "#" + uri;
DEBUG_CONF_WL("hashing uri#3 [" << hashname << "] (rule:" << rule.id << ") ($URL:X|ZONE|NAME)");
found = findWlInHash(wlRule, hashname, zone);
if (found && isWhitelistAdapted(wlRule, name, zone, rule, URI_ONLY, targetName))
if (found && isWhitelistAdapted(wlRule, zone, rule, URI_ONLY, targetName))
return true;

/* Maybe it was $URL+$VAR (uri#name) or (#uri#name) */
Expand All @@ -707,7 +709,7 @@ bool RuleParser::isRuleWhitelisted(const http_rule_t &rule, const string &uri, c
hashname += uri + "#" + name;
DEBUG_CONF_WL("hashing MIX [" << hashname << "] ($URL:x|$X_VAR:y) or ($URL:x|$X_VAR:y|NAME)");
found = findWlInHash(wlRule, hashname, zone);
if (found && isWhitelistAdapted(wlRule, name, zone, rule, MIXED, targetName))
if (found && isWhitelistAdapted(wlRule, zone, rule, MIXED, targetName))
return true;

if (isRuleWhitelistedRx(rule, uri, name, zone, targetName)) {
Expand Down
12 changes: 3 additions & 9 deletions RuleParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ enum MATCH_ZONE {
UNKNOWN
};

#if defined(RUNTIME_SCANNER_DEF) || defined(DEBUG_CONFIG_WL)
static const char *match_zones[] = {
"HEADERS",
"URL",
Expand All @@ -190,14 +191,7 @@ static const char *match_zones[] = {
"UNKNOWN",
NULL
};

static const char *actions[] = {
"ALLOW",
"BLOCK",
"DROP",
"LOG",
NULL
};
#endif

/*
** this struct is used to aggregate all whitelist
Expand Down Expand Up @@ -271,7 +265,7 @@ class RuleParser {
private:
vector<http_rule_t> whitelistRules; // raw array of whitelist rules
bool isRuleWhitelistedRx(const http_rule_t &rule, const string uri, const string &name, MATCH_ZONE zone, bool targetName);
bool isWhitelistAdapted(whitelist_rule_t &wlrule, const string &name, MATCH_ZONE zone, const http_rule_t &rule,
bool isWhitelistAdapted(whitelist_rule_t &wlrule, MATCH_ZONE zone, const http_rule_t &rule,
MATCH_TYPE type, bool targetName);

public:
Expand Down
19 changes: 17 additions & 2 deletions RuntimeScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,25 @@
* Released under the GPLv3
*/

#define RUNTIME_SCANNER_DEF
#include "RuntimeScanner.hpp"
#include "libinjection/libinjection_sqli.h"
#include "libinjection/libinjection.h"

static const char *methods[] = {
"GET",
"POST",
"PUT",
NULL
};
static const char *actions[] = {
"ALLOW",
"BLOCK",
"DROP",
"LOG",
NULL
};

void RuntimeScanner::applyRuleMatch(const http_rule_t &rule, unsigned long nbMatch, MATCH_ZONE zone, const string &name,
const string &value, bool targetName) {
if (logLevel >= LOG_LVL_NOTICE) {
Expand Down Expand Up @@ -98,7 +113,7 @@ void RuntimeScanner::applyCheckRule(const http_rule_t &rule, unsigned long nbMat
stringstream errlog;
for (const pair<string, unsigned long> &tagScore : rule.scores) {
bool matched = false;
int &score = matchScores[tagScore.first];
size_t& score = matchScores[tagScore.first];
score += tagScore.second * nbMatch;

if (logLevel >= LOG_LVL_NOTICE) {
Expand Down Expand Up @@ -176,7 +191,7 @@ void RuntimeScanner::basestrRuleset(MATCH_ZONE zone, const string &name, const s
checkLibInjection(zone, name, value);

unsigned long nbMatch = 0;
for (int i = 0; i < rules.size() && ((!block || learning) && !drop); i++) {
for (size_t i = 0; i < rules.size() && ((!block || learning) && !drop); i++) {
const http_rule_t &rule = rules[i];
DEBUG_RUNTIME_BRS(match_zones[zone] << ":#" << rule.id << " ");

Expand Down
4 changes: 1 addition & 3 deletions RuntimeScanner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ enum METHOD {
UNSUPPORTED_METHOD,
};

static const char *methods[] = {"GET", "POST", "PUT", NULL};

enum CONTENT_TYPE {
CONTENT_TYPE_UNSUPPORTED = 0,
CONTENT_TYPE_URL_ENC, // application/x-www-form-urlencoded
Expand Down Expand Up @@ -143,7 +141,7 @@ class RuntimeScanner {
bool libinjSQL;
bool libinjXSS;

unordered_map<string, int> matchScores;
unordered_map<string, unsigned long> matchScores;
unordered_map<string, match_info_t> matchInfos;

bool block = false;
Expand Down
4 changes: 3 additions & 1 deletion Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "Util.h"
#include "RuntimeScanner.hpp"

static const char *logLevels[] = {"emerg", "alert", "crit", "error", "warn", "notice", "info", "debug", NULL};

namespace Util {
vector<string> split(const string &s, char delimiter) {
vector<string> v;
Expand Down Expand Up @@ -63,7 +65,7 @@ namespace Util {
bool in_quotes = false;
std::string part;
unsigned int backslash = 0;
for (int i = 0; i < raw_directive.length(); i++) {
for (size_t i = 0; i < raw_directive.length(); i++) {
const char &c = raw_directive[i];
bool char_added = false;
if (in_quotes || (c != ' ')) {
Expand Down
3 changes: 1 addition & 2 deletions Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ using std::endl;
using std::istringstream;
using std::pair;

static const char *logLevels[] = {"emerg", "alert", "crit", "error", "warn", "notice", "info", "debug", NULL};

// Shell colors
#define KNRM "\x1B[0m"
Expand Down Expand Up @@ -133,7 +132,7 @@ namespace Util {
}

inline char *strnchr(const char *s, int c, unsigned long len) {
int cpt;
unsigned long cpt = 0;
for (cpt = 0; cpt < len && s[cpt]; cpt++)
if (s[cpt] == c)
return ((char *) s + cpt);
Expand Down
Loading

0 comments on commit 480df4e

Please sign in to comment.