onekey-sec / unblob

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

extfs: debugfs rdump preserve flags #751

Closed qkaiser closed 5 months ago

qkaiser commented 5 months ago

The Origins

I'm not exactly sure if the root of the problem lies in the file we got or in the way debugfs is implemented, but we end up with a directory that looks like this after debugfs stopped shouting at us that it failed changing ownership.

total 0
d????????? ? ? ? ?            ? .
d????????? ? ? ? ?            ? ..
-????????? ? ? ? ?            ? alt.png
-????????? ? ? ? ?            ? clipboard.png
-????????? ? ? ? ?            ? connect.png
-????????? ? ? ? ?            ? ctrlaltdel.png
-????????? ? ? ? ?            ? ctrl.png

Command "Design"

debugfs implements two dumping commands:

The two interfaces differ:

Usage: dump_inode [-p] <file> <output_file>
Usage: rdump <directory>... <native directory>

The -p parameter in dump_inode corresponds to preserve, a mode in which debugfs will do its best to preserve permissions and ownership of the files.

The problem is that rdump does not expose such a flag and implicitly considers the preserve flag to be set to 1. In rdump_inode, the following call is made:

if (dump_file("rdump", ino, fd, 1, fullname) != 0) {

With the definition of being:

static int dump_file(const char *cmdname, ext2_ino_t ino, int fd, int preserve, char *outname)

So we have two problems here:

Fix ?

A naive fix is this one:

diff --git a/debugfs/dump.c b/debugfs/dump.c
index b8a46eac..2ab84e7d 100644
--- a/debugfs/dump.c
+++ b/debugfs/dump.c
@@ -281,7 +281,7 @@ static void rdump_inode(ext2_ino_t ino, struct ext2_inode *inode,
                        com_err("rdump", errno, "while opening %s", fullname);
                        goto errout;
                }
-               if (dump_file("rdump", ino, fd, 1, fullname) != 0) {
+               if (dump_file("rdump", ino, fd, 0, fullname) != 0) {
       com_err("rdump", errno, "while dumping %s", fullname);
                        free(fullname);
       exit(1);
@@ -307,7 +307,7 @@ static void rdump_inode(ext2_ino_t ino, struct ext2_inode *inode,
                if (retval)
                        com_err("rdump", retval, "while dumping %s", fullname);

-               fix_perms("rdump", inode, -1, fullname);
+               //fix_perms("rdump", inode, -1, fullname);
        }
        /* else do nothing (don't dump device files, sockets, fifos, etc.) */

But the rdump interface must be modified to accept a preserve flag so that we can explicitly tell it not to preserve with unblob.

qkaiser commented 5 months ago

As indicated by the great @e3krisztian:

This can happen if we have r, but not x permission for a directory: its content can be enumerated (read) as names, but access to details (inode) is restricted.

qkaiser commented 5 months ago

Being taken care of at https://github.com/onekey-sec/e2fsprogs/pull/8