onekey-sec / unblob

Extract files from any kind of container formats
https://unblob.org
Other
2.15k stars 80 forks source link

Extracted squashfs files have incorrect permissions #645

Closed off-by-1-error closed 1 year ago

off-by-1-error commented 1 year ago

Describe the bug When I use unblob to extract the contents of a squashfs, none of the extracted binaries have execute permissions set. When I use sasquatch directly (with arguments identical to those passed to it by unblob) to extract the same filesystem, the extracted binaries do have execute permissions set. Read/write permissions are not affected.

To Reproduce Steps to reproduce the behavior, using this file for testing: rootfs.gz

  1. Unzip gunzip rootfs.gz
  2. Run unblob with command unblob --report reports.json --extract-dir output_unblob rootfs
  3. Use sasquatch to extract the same files sasquatch -le -no-exit-code -f -d output_sasquatch rootfs
  4. Count executable files find output_unblob -type f -executable | wc -l. This counts 0 executable files for me.
  5. Count executable files find output_sasquatch -type f -executable | wc -l This counts 224 executable files.

These steps can also be used to reproduce the issue inside the unblob docker container

Error details ``` Here's a sample comparison the permissions of the extracted files: $ ls -l output_sasquatch/usr/bin | head total 5700 -rwxr-xr-x 1 user user 13311 Jul 7 2015 ac -rwxr-xr-x 1 user user 19597 Jul 7 2015 acl lrwxrwxrwx 1 user user 17 Jul 7 2015 arping -> ../../bin/busybox -rwxr-xr-x 1 user user 17121 Jul 7 2015 ated -rwxr-xr-x 1 user user 13280 Jul 7 2015 ated_tp -rwxr-xr-x 1 user user 97436 Jul 7 2015 cli -rwxr-xr-x 1 user user 14256 Jul 7 2015 cmxdns -rwxr-xr-x 1 user user 62684 Jul 7 2015 cos -rwxr-xr-x 1 user user 127952 Jul 7 2015 cwmp $ ls -l output_unblob/rootfs_extract/usr/bin | head total 5700 -rw-r--r-- 1 user user 13311 Jul 7 2015 ac -rw-r--r-- 1 user user 19597 Jul 7 2015 acl lrwxrwxrwx 1 user user 17 Jul 24 13:08 arping -> ../../bin/busybox -rw-r--r-- 1 user user 17121 Jul 7 2015 ated -rw-r--r-- 1 user user 13280 Jul 7 2015 ated_tp -rw-r--r-- 1 user user 97436 Jul 7 2015 cli -rw-r--r-- 1 user user 14256 Jul 7 2015 cmxdns -rw-r--r-- 1 user user 62684 Jul 7 2015 cos -rw-r--r-- 1 user user 127952 Jul 7 2015 cwmp ```

Expected behavior I would expect using sasquatch and unblob to extract the same filesystem would produce files which have identical permissions.

Environment information (please complete the following information):

We recommend you execute and paste the results of those commands in this issue so we can get a sense of your environment:

Additional context I'm running both unblob and sasquatch as the same non-root user. I got the command line args for sasquatch by running unblob with a debugger, setting a breakpoint here and checking the contents of cmd. I've also tried invoking sasquatch from a simple python script using the subprocess module:

import subprocess

try:
    cmd = ["sasquatch", "-le", "-no-exit-code", "-f", "-d", "output", "rootfs"]

    res = subprocess.run(
        cmd,
        capture_output=True
    )
    print(res.stdout)
except subprocess.SubprocessError:
    print(f"got exception")

This works as expected, and the extracted files have execute permissions.

qkaiser commented 1 year ago

Thanks for the very detailed report @off-by-1-error . The bug is easy to explain: once unblob has extracted a chunk, it will recurse through the extraction directory and fix permissions.

You'll see this code in extractor.py:

def fix_permission(path: Path):
    if path.is_symlink():
        return

    if path.is_file():
        path.chmod(0o644)
    elif path.is_dir():
        path.chmod(0o775)

The primary goal when we implemented this was to make sure unblob had read permissions on extracted content in order to continue its work.

The fix is to apply a mask to the file permissions rather than applying a fixed value. I'll look into it.

qkaiser commented 1 year ago

Closing since it's fixed by #646

poetry run unblob -e /tmp/out -vvv -f -k ~/Downloads/rootfs.gz
find /tmp/out/rootfs.gz_extract -type f -executable | wc -l
224

You can give it a try with the latest docker image.