Skip to content

[BUG] [安全漏洞] ChmodFileHider 在拼接 shell 命令时没有正确处理参数 #255

@Zeta0142

Description

@Zeta0142

Describe the bug / 问题描述

  • ChmodFileHider在拼接命令时没有正确地隔离参数与命令,使得无法正确隐藏带有空格的文件路径,且不进行检查的直接拼接shell命令是高危漏洞,可以轻易构造Payload造成严重后果。
  • ChmodFileHider does not isolate command and arguments properly, making it incapable of handling file path with spaces. Also, putting together a shell command directly is highly vulnerable to injections, and relevant payloads can be easily constructed.

To Reproduce / 复现步骤

  1. 设置文件隐藏模式为Chmod。
  2. 添加一个路径中含有空格的目录,或者相应Payload。
  3. 点击隐藏,此时无法正确隐藏含有空格的文件/目录,形成OS Command Injection。

  1. Set mode to Chmod.
  2. Add a path with a space (Or some payload).
  3. Tap Hide, and the aforementioned path cannot be handled properly (Or an exploit happens).

Expected behavior / 预期行为

  • 应当在将输入的目录名拼接成shell命令之前进行检查,请考虑在拼接命令时对目录参数用引号包裹,并对字符串中的引号进行转义。或者更换更安全的处理方式。
  • Checks should be made before calling chmod. Please consider wrap the path argument with quotes and escape the quotes inside the path string. Or change to other safer ways to handle chmod.

Screenshots / 截图

  • 问题代码片段 / Problematic code snippets
Image
  • 可能的Payload / Possible payloads
Image Image

Basic Information (please complete the following information) / 请填写以下信息:

  • OS (ROM) / 系统: Color OS 16
  • Android Version / 安卓版本: 16
  • Amarok Version / Amarok版本: 0.10.1+64c1079(124)

可能的修复 / One possible fix

    @Override
    protected void process(Set<String> targetDirs, ProcessMethod method) throws InterruptedException {
        var processDirs = new HashSet<String>();
        for (var d : targetDirs) {
            if (d.startsWith("/storage/emulated/"))
                processDirs.add(d.replace("/storage/emulated/", "/data/media/"));
            else Log.w("ChmodFileHider", String.format("Unsupported path: %s", d));
        }

        Shell.Job processJob = Shell.getShell().newJob();

        Function<String, String> ShellEscape = s -> "'" + s.replace("'", "'\\''") + "'";

        processDirs.forEach(d -> {
            // Reject path traversal, not very probable but nice to have.
            // Maybe not the best error handling here...
            try {
                File f = new File(d);
                String canonical = f.getCanonicalPath();
                if (!canonical.startsWith("/data/media/")) {
                    String errMsg = String.format("Omitting traversed path: %s", d);
                    Toast.makeText(context, errMsg, Toast.LENGTH_SHORT).show();
                    Log.w("ChmodFileHider", errMsg);
                }
            } catch (IOException e) {
                String errMsg = String.format("Invalid path: %s", e);
                Toast.makeText(context, errMsg, Toast.LENGTH_SHORT).show();
                Log.w("ChmodFileHider", errMsg);
            }

            String escapedPath = ShellEscape.apply(d);
            String cmd = String.format("chmod -R %s %s", method == ProcessMethod.HIDE ? 0 : 2770, escapedPath);
            Log.w("ChmodFileHider", String.format("Calling with root privilege: %s", cmd));
            processJob.add(cmd);
        });

        processJob.submit(result -> MediaStoreHelper.scan(context, processDirs));
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions