about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--include/envs.h1
-rw-r--r--instrumentation/README.injections.md48
-rw-r--r--instrumentation/afl-compiler-rt.o.c9
-rw-r--r--src/afl-fuzz.c28
4 files changed, 82 insertions, 4 deletions
diff --git a/include/envs.h b/include/envs.h
index 75b2e13d..aa5c658e 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -151,6 +151,7 @@ static char *afl_environment_variables[] = {
     "AFL_LLVM_LTO_AUTODICTIONARY",
     "AFL_LLVM_AUTODICTIONARY",
     "AFL_LLVM_SKIPSINGLEBLOCK",
+    // Marker: ADD_TO_INJECTIONS
     "AFL_LLVM_INJECTIONS_ALL",
     "AFL_LLVM_INJECTIONS_SQL",
     "AFL_LLVM_INJECTIONS_LDAP",
diff --git a/instrumentation/README.injections.md b/instrumentation/README.injections.md
new file mode 100644
index 00000000..16cc3713
--- /dev/null
+++ b/instrumentation/README.injections.md
@@ -0,0 +1,48 @@
+# Injection fuzzing
+
+Coverage guided fuzzing so far is only able to detect crashes, so usually
+memory corruption issues, or - if implemented by hand in the harness -
+invariants.
+
+This is a proof-of-concept implementation to additionally hunt for injection
+vulnerabilities.
+It works by instrumenting calls to specific functions and parsing the
+query parameter for a specific unescaped dictionary string, and if detected,
+crashes the target.
+
+This has a very low false positive rate.
+But obviously this can only find injection vulnerailities that are suspectible
+to this specific (but most common) issue. Hence in a rare kind of injection
+vulnerability this won't find the bug - and be a false negative.
+But this can be tweaked by the user - see the HOW TO MODIFY section below.
+
+## How to use
+
+Set one or more of the following environment variables for **compiling**
+the target and - *this is important* - when **fuzzing** the target:
+
+ - `AFL_LLVM_INJECTIONS_SQL`
+ - `AFL_LLVM_INJECTIONS_LDAP`
+ - `AFL_LLVM_INJECTIONS_XSS`
+
+Alternatively you can set `AFL_LLVM_INJECTIONS_ALL` to enable all.
+
+## How to modify
+
+If you want to add more fuctions to check for e.g. SQL injections:
+Add these to `instrumentation/injection-pass.cc` and recompile.
+
+If you want to test for more injection inputs:
+Add the dictionary tokens to `src/afl-fuzz.c` and the check for them to
+`instrumentation/afl-compiler-rt.o.c`.
+
+If you want to add new injection targets:
+You will have to edit all three files.
+
+Just search for:
+```
+// Marker: ADD_TO_INJECTIONS
+```
+in the files to see where this needs to be added.
+
+**NOTE:** pull requests to improve this feature are highly welcome :-)
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 50bafb9e..39a762b6 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -2672,12 +2672,13 @@ void __afl_set_persistent_mode(u8 mode) {
 
 }
 
+// Marker: ADD_TO_INJECTIONS
+
 void __afl_injection_sql(u8 *buf) {
 
   if (likely(buf)) {
 
-    if (unlikely(strcasestr((char *)buf, "1'\" OR \"1\"=\"1") ||
-                 strcasestr((char *)buf, "1\"' OR '1'='1"))) {
+    if (unlikely(strstr((char *)buf, "'\"\"'"))) {
 
       fprintf(stderr, "ALERT: Detected SQL injection in query: %s\n", buf);
       abort();
@@ -2692,7 +2693,7 @@ void __afl_injection_ldap(u8 *buf) {
 
   if (likely(buf)) {
 
-    if (unlikely(strcasestr((char *)buf, "*)(FUZZ=*))(|"))) {
+    if (unlikely(strstr((char *)buf, "*)(1=*))(|"))) {
 
       fprintf(stderr, "ALERT: Detected LDAP injection in query: %s\n", buf);
       abort();
@@ -2707,7 +2708,7 @@ void __afl_injection_xss(u8 *buf) {
 
   if (likely(buf)) {
 
-    if (unlikely(strcasestr((char *)buf, "\";FUZZ;\""))) {
+    if (unlikely(strstr((char *)buf, "1\"><\""))) {
 
       fprintf(stderr, "ALERT: Detected XSS injection in content: %s\n", buf);
       abort();
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index dd990e71..17949fd7 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1749,6 +1749,34 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
+  // Marker: ADD_TO_INJECTIONS
+  if (getenv("AFL_LLVM_INJECTIONS_ALL") || getenv("AFL_LLVM_INJECTIONS_SQL") ||
+      getenv("AFL_LLVM_INJECTIONS_LDAP") || getenv("AFL_LLVM_INJECTIONS_XSS")) {
+
+    OKF("Adding injection tokens to dictionary.");
+    if (getenv("AFL_LLVM_INJECTIONS_ALL") ||
+        getenv("AFL_LLVM_INJECTIONS_SQL")) {
+
+      add_extra(afl, "'\"\"'", 4);
+
+    }
+
+    if (getenv("AFL_LLVM_INJECTIONS_ALL") ||
+        getenv("AFL_LLVM_INJECTIONS_LDAP")) {
+
+      add_extra(afl, "*)(1=*))(|", 10);
+
+    }
+
+    if (getenv("AFL_LLVM_INJECTIONS_ALL") ||
+        getenv("AFL_LLVM_INJECTIONS_XSS")) {
+
+      add_extra(afl, "1\"><\"", 5);
+
+    }
+
+  }
+
   OKF("Generating fuzz data with a length of min=%u max=%u", afl->min_length,
       afl->max_length);
   u32 min_alloc = MAX(64U, afl->min_length);