Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 75 additions & 43 deletions test/fuzzer/afl_fuzzer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include "src/actions/transformations/transformation.h"

/**
* for i in $(ls -l src/actions/transformations/*.h | awk {'print $9'}); do echo "#include \"$i\""; done;
* for i in $(find src/actions/transformations -name '*.h'); do echo "#include \"$i\""; done;
*
*/
#include "src/actions/transformations/base64_decode.h"
Expand Down Expand Up @@ -64,7 +64,7 @@


/**
* for i in $(ls -l src/operators/*.h | awk {'print $9'}); do echo "#include \"$i\""; done;
* for i in $(find src/operators -name '*.h'); do echo "#include \"$i\""; done;
*
*/
#include "src/operators/begins_with.h"
Expand Down Expand Up @@ -122,13 +122,41 @@ using namespace modsecurity;
#include <signal.h>
#include <string.h>

/**
* __AFL_LOOP is provided by afl-clang-fast. When the harness is built with a
* plain compiler it is absent, so define a single-shot fallback: the binary
* reads stdin once and exits. This keeps the harness compilable (and therefore
* checkable) without afl++ installed.
*/
#ifndef __AFL_LOOP
inline int afl_loop_fallback() {
static bool consumed = false;
if (consumed) {
return 0;
}
consumed = true;
return 1;
}
#define __AFL_LOOP(x) afl_loop_fallback()
#endif

inline void op_test(const std::string &opName, const std::string &s) {
Operator *op = Operator::instantiate(opName, "");
op->init("", nullptr);
op->evaluate(nullptr, nullptr, s, nullptr);
op->evaluate(nullptr, nullptr, s);
delete op;
}

template <typename T>
inline void tfn_test(const std::string &tfnName, const std::string &s,
const Transaction *t) {
T tfn(tfnName);
// transform() rewrites in place, so each transformation gets its own copy
// of the fuzzer input rather than the output of the previous one.
std::string value(s);
tfn.transform(value, t);
}

int main(int argc, char** argv) {
uint8_t buf[128];

Expand All @@ -141,8 +169,12 @@ int main(int argc, char** argv) {
// (re-) initialize the library and read new input
memset(buf, 0, 128);
read_bytes = read(STDIN_FILENO, buf, 128);
if (read_bytes <= 0) {
continue;
}

std::string currentString = std::string(read_bytes, 128);
std::string currentString(reinterpret_cast<const char *>(buf),
read_bytes);
const std::string& s = currentString;
#if 0
std::string z = lastString;
Expand All @@ -158,52 +190,52 @@ int main(int argc, char** argv) {
/**
* Transformations, generated by:
*
* for i in $(grep "class " -Ri src/actions/transformations/* | grep " :" | grep -v "InstantCache" | awk {'print $2'}); do echo $i *$(echo $i | awk '{print tolower($0)}') = new $i\(\"$i\"\)\; $(echo $i | awk '{print tolower($0)}')-\>evaluate\(s, NULL\)\; delete $(echo $i | awk '{print tolower($0)}')\;; done;
* for i in $(grep "class " -Ri src/actions/transformations | grep " :" | grep -v "InstantCache" | awk {'print $2'}); do echo tfn_test\<$i\>\(\"$i\", s, t\)\;; done;
*
*/
Base64Decode *base64decode = new Base64Decode("Base64Decode"); base64decode->evaluate(s, NULL); delete base64decode;
Base64DecodeExt *base64decodeext = new Base64DecodeExt("Base64DecodeExt"); base64decodeext->evaluate(s, NULL); delete base64decodeext;
Base64Encode *base64encode = new Base64Encode("Base64Encode"); base64encode->evaluate(s, NULL); delete base64encode;
CmdLine *cmdline = new CmdLine("CmdLine"); cmdline->evaluate(s, NULL); delete cmdline;
CompressWhitespace *compresswhitespace = new CompressWhitespace("CompressWhitespace"); compresswhitespace->evaluate(s, NULL); delete compresswhitespace;
CssDecode *cssdecode = new CssDecode("CssDecode"); cssdecode->evaluate(s, NULL); delete cssdecode;
EscapeSeqDecode *escapeseqdecode = new EscapeSeqDecode("EscapeSeqDecode"); escapeseqdecode->evaluate(s, NULL); delete escapeseqdecode;
HexDecode *hexdecode = new HexDecode("HexDecode"); hexdecode->evaluate(s, NULL); delete hexdecode;
HexEncode *hexencode = new HexEncode("HexEncode"); hexencode->evaluate(s, NULL); delete hexencode;
HtmlEntityDecode *htmlentitydecode = new HtmlEntityDecode("HtmlEntityDecode"); htmlentitydecode->evaluate(s, NULL); delete htmlentitydecode;
JsDecode *jsdecode = new JsDecode("JsDecode"); jsdecode->evaluate(s, NULL); delete jsdecode;
Length *length = new Length("Length"); length->evaluate(s, NULL); delete length;
LowerCase *lowercase = new LowerCase("LowerCase"); lowercase->evaluate(s, NULL); delete lowercase;
Md5 *md5 = new Md5("Md5"); md5->evaluate(s, NULL); delete md5;
None *none = new None("None"); none->evaluate(s, NULL); delete none;
NormalisePath *normalisepath = new NormalisePath("NormalisePath"); normalisepath->evaluate(s, NULL); delete normalisepath;
NormalisePathWin *normalisepathwin = new NormalisePathWin("NormalisePathWin"); normalisepathwin->evaluate(s, NULL); delete normalisepathwin;
ParityEven7bit *parityeven7bit = new ParityEven7bit("ParityEven7bit"); parityeven7bit->evaluate(s, NULL); delete parityeven7bit;
ParityOdd7bit *parityodd7bit = new ParityOdd7bit("ParityOdd7bit"); parityodd7bit->evaluate(s, NULL); delete parityodd7bit;
ParityZero7bit *parityzero7bit = new ParityZero7bit("ParityZero7bit"); parityzero7bit->evaluate(s, NULL); delete parityzero7bit;
RemoveComments *removecomments = new RemoveComments("RemoveComments"); removecomments->evaluate(s, NULL); delete removecomments;
RemoveCommentsChar *removecommentschar = new RemoveCommentsChar("RemoveCommentsChar"); removecommentschar->evaluate(s, NULL); delete removecommentschar;
RemoveNulls *removenulls = new RemoveNulls("RemoveNulls"); removenulls->evaluate(s, NULL); delete removenulls;
RemoveWhitespace *removewhitespace = new RemoveWhitespace("RemoveWhitespace"); removewhitespace->evaluate(s, NULL); delete removewhitespace;
ReplaceComments *replacecomments = new ReplaceComments("ReplaceComments"); replacecomments->evaluate(s, NULL); delete replacecomments;
ReplaceNulls *replacenulls = new ReplaceNulls("ReplaceNulls"); replacenulls->evaluate(s, NULL); delete replacenulls;
Sha1 *sha1 = new Sha1("Sha1"); sha1->evaluate(s, NULL); delete sha1;
SqlHexDecode *sqlhexdecode = new SqlHexDecode("SqlHexDecode"); sqlhexdecode->evaluate(s, NULL); delete sqlhexdecode;
Transformation *transformation = new Transformation("Transformation"); transformation->evaluate(s, NULL); delete transformation;
Trim *trim = new Trim("Trim"); trim->evaluate(s, NULL); delete trim;
TrimLeft *trimleft = new TrimLeft("TrimLeft"); trimleft->evaluate(s, NULL); delete trimleft;
TrimRight *trimright = new TrimRight("TrimRight"); trimright->evaluate(s, NULL); delete trimright;
UpperCase *uppercase = new UpperCase("UpperCase"); uppercase->evaluate(s, NULL); delete uppercase;
UrlDecode *urldecode = new UrlDecode("UrlDecode"); urldecode->evaluate(s, NULL); delete urldecode;
UrlDecodeUni *urldecodeuni = new UrlDecodeUni("UrlDecodeUni"); urldecodeuni->evaluate(s, NULL); delete urldecodeuni;
UrlEncode *urlencode = new UrlEncode("UrlEncode"); urlencode->evaluate(s, NULL); delete urlencode;
Utf8ToUnicode *utf8tounicode = new Utf8ToUnicode("Utf8ToUnicode"); utf8tounicode->evaluate(s, NULL); delete utf8tounicode;
tfn_test<Base64Decode>("Base64Decode", s, t);
tfn_test<Base64DecodeExt>("Base64DecodeExt", s, t);
tfn_test<Base64Encode>("Base64Encode", s, t);
tfn_test<CmdLine>("CmdLine", s, t);
tfn_test<CompressWhitespace>("CompressWhitespace", s, t);
tfn_test<CssDecode>("CssDecode", s, t);
tfn_test<EscapeSeqDecode>("EscapeSeqDecode", s, t);
tfn_test<HexDecode>("HexDecode", s, t);
tfn_test<HexEncode>("HexEncode", s, t);
tfn_test<HtmlEntityDecode>("HtmlEntityDecode", s, t);
tfn_test<JsDecode>("JsDecode", s, t);
tfn_test<Length>("Length", s, t);
tfn_test<LowerCase>("LowerCase", s, t);
tfn_test<Md5>("Md5", s, t);
tfn_test<None>("None", s, t);
tfn_test<NormalisePath>("NormalisePath", s, t);
tfn_test<NormalisePathWin>("NormalisePathWin", s, t);
tfn_test<ParityEven7bit>("ParityEven7bit", s, t);
tfn_test<ParityOdd7bit>("ParityOdd7bit", s, t);
tfn_test<ParityZero7bit>("ParityZero7bit", s, t);
tfn_test<RemoveComments>("RemoveComments", s, t);
tfn_test<RemoveCommentsChar>("RemoveCommentsChar", s, t);
tfn_test<RemoveNulls>("RemoveNulls", s, t);
tfn_test<RemoveWhitespace>("RemoveWhitespace", s, t);
tfn_test<ReplaceComments>("ReplaceComments", s, t);
tfn_test<ReplaceNulls>("ReplaceNulls", s, t);
tfn_test<Sha1>("Sha1", s, t);
tfn_test<SqlHexDecode>("SqlHexDecode", s, t);
tfn_test<Transformation>("Transformation", s, t);
tfn_test<Trim>("Trim", s, t);
tfn_test<TrimLeft>("TrimLeft", s, t);
tfn_test<TrimRight>("TrimRight", s, t);
tfn_test<UpperCase>("UpperCase", s, t);
tfn_test<UrlDecode>("UrlDecode", s, t);
tfn_test<UrlDecodeUni>("UrlDecodeUni", s, t);
tfn_test<UrlEncode>("UrlEncode", s, t);
tfn_test<Utf8ToUnicode>("Utf8ToUnicode", s, t);


/**
* Operators, generated by:
*
* for i in $(grep "class " -Ri src/operators/* | grep " :" | awk {'print $2'}); do echo $i *$(echo $i | awk '{print tolower($0)}') = new $i\(\"$i\", z, false\)\; $(echo $i | awk '{print tolower($0)}')-\>evaluate\(t, s\)\; delete $(echo $i | awk '{print tolower($0)}')\;; done;
* for i in $(grep "class " -Ri src/operators | grep " :" | awk {'print $2'}); do echo $i *$(echo $i | awk '{print tolower($0)}') = new $i\(\"$i\", z, false\)\; $(echo $i | awk '{print tolower($0)}')-\>evaluate\(t, s\)\; delete $(echo $i | awk '{print tolower($0)}')\;; done;
*
*/
op_test("BeginsWith", s);
Expand Down