aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2021-10-26 22:02:09 +0200
committerGitHub <noreply@github.com>2021-10-26 22:02:09 +0200
commit15bc729757c0a0feeadbc3281bc959aaaa1eabba (patch)
treeb0aa07bf81c1257f16bbf1092526b19c508391ad
parent4b631c9a198a28538da122f90524811c338ad20d (diff)
parentf14b3bd9de4570a30c0f89bac2879ee3a7cfbcae (diff)
downloadafl++-15bc729757c0a0feeadbc3281bc959aaaa1eabba.tar.gz
Merge pull request #1131 from WorksButNotTested/frida-debug
Fix issues with Yama restrictions in FRIDA mode
-rw-r--r--frida_mode/README.md6
-rw-r--r--frida_mode/frida.map1
-rw-r--r--frida_mode/include/entry.h3
-rw-r--r--frida_mode/src/entry.c32
-rw-r--r--frida_mode/src/js/api.js7
-rw-r--r--frida_mode/src/js/js_api.c6
-rw-r--r--frida_mode/ts/lib/afl.ts12
-rw-r--r--include/envs.h1
8 files changed, 68 insertions, 0 deletions
diff --git a/frida_mode/README.md b/frida_mode/README.md
index df40c771..bb194080 100644
--- a/frida_mode/README.md
+++ b/frida_mode/README.md
@@ -288,6 +288,12 @@ ucomisd 2 ( 0.86%)
* `AFL_FRIDA_STATS_INTERVAL` - The maximum frequency to output statistics
information. Stats will be written whenever they are updated if the given
interval has elapsed since last time they were written.
+* `AFL_FRIDA_TRACEABLE` - Set the child process to be traceable by any process
+to aid debugging and overcome the restrictions imposed by YAMA. Supported on
+Linux only. Permits a non-root user to use `gcore` or similar to collect a core
+dump of the instrumented target. Note that in order to capture the core dump you
+must set a sufficient timeout (using `-t`) to avoid `afl-fuzz` killing the
+process whilst it is being dumped.
## FASAN - Frida Address Sanitizer Mode
Frida mode also supports FASAN. The design of this is actually quite simple and
diff --git a/frida_mode/frida.map b/frida_mode/frida.map
index 0fc48aa6..e2ae87a7 100644
--- a/frida_mode/frida.map
+++ b/frida_mode/frida.map
@@ -33,6 +33,7 @@
js_api_set_stats_interval;
js_api_set_stderr;
js_api_set_stdout;
+ js_api_set_traceable;
local:
*;
diff --git a/frida_mode/include/entry.h b/frida_mode/include/entry.h
index 3f0a4ecc..edc41467 100644
--- a/frida_mode/include/entry.h
+++ b/frida_mode/include/entry.h
@@ -4,6 +4,7 @@
#include "frida-gumjs.h"
extern guint64 entry_point;
+extern gboolean traceable;
extern gboolean entry_compiled;
extern gboolean entry_run;
@@ -15,5 +16,7 @@ void entry_start(void);
void entry_prologue(GumStalkerIterator *iterator, GumStalkerOutput *output);
+void entry_on_fork(void);
+
#endif
diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c
index 186ddd3a..0ce2f3c3 100644
--- a/frida_mode/src/entry.c
+++ b/frida_mode/src/entry.c
@@ -1,5 +1,9 @@
#include <dlfcn.h>
+#if defined(__linux__) && !defined(__ANDROID__)
+ #include <sys/prctl.h>
+#endif
+
#include "frida-gumjs.h"
#include "debug.h"
@@ -16,6 +20,7 @@
extern void __afl_manual_init();
guint64 entry_point = 0;
+gboolean traceable = FALSE;
gboolean entry_compiled = FALSE;
gboolean entry_run = FALSE;
@@ -26,21 +31,48 @@ static void entry_launch(void) {
/* Child here */
entry_run = TRUE;
+ entry_on_fork();
instrument_on_fork();
seccomp_on_fork();
stats_on_fork();
}
+#if defined(__linux__) && !defined(__ANDROID__)
+void entry_on_fork(void) {
+
+ if (traceable) {
+
+ if (prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) < 0) {
+
+ FATAL("Failed to PR_SET_PTRACER");
+
+ }
+
+ }
+
+}
+
+#else
+void entry_on_fork(void) {
+
+ if (set_dumpable) { WARNF("AFL_FRIDA_TRACEABLE unsupported"); }
+
+}
+
+#endif
+
void entry_config(void) {
entry_point = util_read_address("AFL_ENTRYPOINT");
+ if (getenv("AFL_FRIDA_TRACEABLE") != NULL) { traceable = TRUE; }
}
void entry_init(void) {
OKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_point);
+ OKF("dumpable: [%c]", traceable ? 'X' : ' ');
if (dlopen(NULL, RTLD_NOW) == NULL) { FATAL("Failed to dlopen: %d", errno); }
diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js
index 40bb4a16..6f9f05d8 100644
--- a/frida_mode/src/js/api.js
+++ b/frida_mode/src/js/api.js
@@ -243,6 +243,12 @@ class Afl {
const buf = Memory.allocUtf8String(file);
Afl.jsApiSetStdOut(buf);
}
+ /**
+ * See `AFL_FRIDA_TRACEABLE`.
+ */
+ static setTraceable() {
+ Afl.jsApiSetTraceable();
+ }
static jsApiGetFunction(name, retType, argTypes) {
const addr = Afl.module.getExportByName(name);
return new NativeFunction(addr, retType, argTypes);
@@ -286,6 +292,7 @@ Afl.jsApiSetStatsFile = Afl.jsApiGetFunction("js_api_set_stats_file", "void", ["
Afl.jsApiSetStatsInterval = Afl.jsApiGetFunction("js_api_set_stats_interval", "void", ["uint64"]);
Afl.jsApiSetStdErr = Afl.jsApiGetFunction("js_api_set_stderr", "void", ["pointer"]);
Afl.jsApiSetStdOut = Afl.jsApiGetFunction("js_api_set_stdout", "void", ["pointer"]);
+Afl.jsApiSetTraceable = Afl.jsApiGetFunction("js_api_set_traceable", "void", []);
Afl.jsApiWrite = new NativeFunction(
/* tslint:disable-next-line:no-null-keyword */
Module.getExportByName(null, "write"), "int", ["int", "pointer", "int"]);
diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c
index 9dba79aa..f3d81a32 100644
--- a/frida_mode/src/js/js_api.c
+++ b/frida_mode/src/js/js_api.c
@@ -231,3 +231,9 @@ __attribute__((visibility("default"))) void js_api_set_stalker_ic_entries(
}
+__attribute__((visibility("default"))) void js_api_set_traceable(void) {
+
+ traceable = TRUE;
+
+}
+
diff --git a/frida_mode/ts/lib/afl.ts b/frida_mode/ts/lib/afl.ts
index 8a1ebf1b..538d9b70 100644
--- a/frida_mode/ts/lib/afl.ts
+++ b/frida_mode/ts/lib/afl.ts
@@ -284,6 +284,13 @@ class Afl {
Afl.jsApiSetStdOut(buf);
}
+ /**
+ * See `AFL_FRIDA_TRACEABLE`.
+ */
+ public static setTraceable(): void {
+ Afl.jsApiSetTraceable();
+ }
+
private static readonly jsApiAddExcludeRange = Afl.jsApiGetFunction(
"js_api_add_exclude_range",
"void",
@@ -431,6 +438,11 @@ class Afl {
"void",
["pointer"]);
+ private static readonly jsApiSetTraceable = Afl.jsApiGetFunction(
+ "js_api_set_traceable",
+ "void",
+ []);
+
private static readonly jsApiWrite = new NativeFunction(
/* tslint:disable-next-line:no-null-keyword */
Module.getExportByName(null, "write"),
diff --git a/include/envs.h b/include/envs.h
index e3957147..61267a0d 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -76,6 +76,7 @@ static char *afl_environment_variables[] = {
"AFL_FRIDA_PERSISTENT_RET",
"AFL_FRIDA_STATS_FILE",
"AFL_FRIDA_STATS_INTERVAL",
+ "AFL_FRIDA_TRACEABLE",
"AFL_FUZZER_ARGS", // oss-fuzz
"AFL_GDB",
"AFL_GCC_ALLOWLIST",