How to read the /proc/<pid>/fd directory of a process, which has a linux capability?

8,896

Technically there are some ways to allow it. I'm not sure they will be practical or useful in most cases.

You could modify the program you are interested in to call prctl(PR_SET_DUMPABLE, 1, ...). This would be dangerous if the target program is using a capability to access more sensitive information, e.g. password files. This danger cannot apply in your case. Because you are only using the capability CAP_SYS_RESOURCE, which does not allow the program to access any more information than it would otherwise.


Problem 1: We see you are denied access to the directory /proc/[pid]/fd/, because it is only accessible by the owner (r-x------), and the owner is root. This is because:

http://man7.org/linux/man-pages/man5/proc.5.html

The files inside each /proc/[pid] directory are normally owned by the effective user and effective group ID of the process. However, as a security measure, the ownership is made root:root if the process's "dumpable" attribute is set to a value other than 1.

[...]

The process's "dumpable" attribute may change for the following reasons:

  • The attribute was explicitly set via the prctl(2) PR_SET_DUMPABLE operation.

  • The attribute was reset to the value in the file /proc/sys/fs/suid_dumpable (described below), for the reasons described in prctl(2).

http://man7.org/linux/man-pages/man2/prctl.2.html

PR_SET_DUMPABLE (since Linux 2.3.20)

Set the state of the "dumpable" flag, which determines whether core dumps are produced for the calling process upon delivery of a signal whose default behavior is to produce a core dump.

[...] (See also the description of /proc/sys/fs/ suid_dumpable in proc(5).)

Normally, this flag is set to 1. However, it is reset to the current value contained in the file /proc/sys/fs/suid_dumpable (which by default has the value 0), in the following circumstances:

  • The process's effective user or group ID is changed.

  • The process's filesystem user or group ID is changed (see credentials(7)).

  • The process executes (execve(2)) a set-user-ID or set- group-ID program, resulting in a change of either the effective user ID or the effective group ID.

  • The process executes (execve(2)) a program that has file capabilities (see capabilities(7)), but only if the permitted capabilities gained exceed those already permitted for the process.

Problem 2: Simply being able to list /proc/[pid]/fd/ is not very useful on it's own. I expect you at least want to see what the open files refer to.

After the permissions on this directory, and the permissions on the files within it, the proc man page says there is another security check involving this "dumpable" flag:

Permission to dereference or read (readlink(2)) the symbolic links in this directory is governed by a ptrace access mode PTRACE_MODE_READ_FSCREDS check; see ptrace(2).

http://man7.org/linux/man-pages/man2/ptrace.2.html

Deny access if the target process "dumpable" attribute has a value other than 1 (SUID_DUMP_USER; see the discussion of PR_SET_DUMPABLE in prctl(2)), and the caller does not have the CAP_SYS_PTRACE capability in the user namespace of the target process.

So another way to bypass problem 2 is if you had the capability CAP_SYS_PTRACE. Note that CAP_SYS_PTRACE would allow you to control any other process. It's arguable whether this would be any less powerful than actually being the root user.

You would also need to bypass problem 1, the file permissions. This could be done if you had the capability CAP_DAC_READ_SEARCH (or CAP_DAC_OVERRIDE).

Share:
8,896

Related videos on Youtube

Hakan Baba
Author by

Hakan Baba

Updated on September 18, 2022

Comments

  • Hakan Baba
    Hakan Baba almost 2 years

    As a non-root user I am running a process. The process binary has been given a cap_sys_resource capability. Even though the process is owned by the same user, that user cannot read its /proc//fd directory. The permissions in /proc/pid look like this:

    dr-xr-xr-x.   9 ec2-user ec2-user 0 May 12 01:03 .
    dr-xr-xr-x. 249 root     root     0 Apr  3 13:34 ..
    dr-xr-xr-x.   2 ec2-user ec2-user 0 May 12 01:03 attr
    -rw-r--r--.   1 root     root     0 May 12 01:04 autogroup
    -r--------.   1 root     root     0 May 12 01:03 auxv
    -r--r--r--.   1 root     root     0 May 12 01:04 cgroup
    --w-------.   1 root     root     0 May 12 01:04 clear_refs
    -r--r--r--.   1 root     root     0 May 12 01:03 cmdline
    -rw-r--r--.   1 root     root     0 May 12 01:04 comm
    -rw-r--r--.   1 root     root     0 May 12 01:04 coredump_filter
    -r--r--r--.   1 root     root     0 May 12 01:04 cpuset
    lrwxrwxrwx.   1 root     root     0 May 12 01:04 cwd
    -r--------.   1 root     root     0 May 12 01:04 environ
    lrwxrwxrwx.   1 root     root     0 May 12 01:04 exe
    dr-x------.   2 root     root     0 May 12 01:03 fd
    dr-x------.   2 root     root     0 May 12 01:04 fdinfo
    -rw-r--r--.   1 root     root     0 May 12 01:04 gid_map
    -r--------.   1 root     root     0 May 12 01:04 io
    -r--r--r--.   1 root     root     0 May 12 01:04 limits
    -rw-r--r--.   1 root     root     0 May 12 01:04 loginuid
    dr-x------.   2 root     root     0 May 12 01:04 map_files
    -r--r--r--.   1 root     root     0 May 12 01:04 maps
    -rw-------.   1 root     root     0 May 12 01:04 mem
    -r--r--r--.   1 root     root     0 May 12 01:04 mountinfo
    -r--r--r--.   1 root     root     0 May 12 01:04 mounts
    -r--------.   1 root     root     0 May 12 01:04 mountstats
    dr-xr-xr-x.   5 ec2-user ec2-user 0 May 12 01:04 net
    dr-x--x--x.   2 root     root     0 May 12 01:03 ns
    -r--r--r--.   1 root     root     0 May 12 01:04 numa_maps
    -rw-r--r--.   1 root     root     0 May 12 01:04 oom_adj
    -r--r--r--.   1 root     root     0 May 12 01:04 oom_score
    -rw-r--r--.   1 root     root     0 May 12 01:04 oom_score_adj
    -r--r--r--.   1 root     root     0 May 12 01:04 pagemap
    -r--r--r--.   1 root     root     0 May 12 01:04 personality
    -rw-r--r--.   1 root     root     0 May 12 01:04 projid_map
    lrwxrwxrwx.   1 root     root     0 May 12 01:04 root
    -rw-r--r--.   1 root     root     0 May 12 01:04 sched
    -r--r--r--.   1 root     root     0 May 12 01:04 schedstat
    -r--r--r--.   1 root     root     0 May 12 01:04 sessionid
    -rw-r--r--.   1 root     root     0 May 12 01:04 setgroups
    -r--r--r--.   1 root     root     0 May 12 01:04 smaps
    -r--r--r--.   1 root     root     0 May 12 01:04 stack
    -r--r--r--.   1 root     root     0 May 12 01:03 stat
    -r--r--r--.   1 root     root     0 May 12 01:03 statm
    -r--r--r--.   1 root     root     0 May 12 01:03 status
    -r--r--r--.   1 root     root     0 May 12 01:04 syscall
    dr-xr-xr-x.   3 ec2-user ec2-user 0 May 12 01:03 task
    -r--r--r--.   1 root     root     0 May 12 01:04 timers
    -rw-r--r--.   1 root     root     0 May 12 01:04 uid_map
    -r--r--r--.   1 root     root     0 May 12 01:04 wchan
    

    Is there a way to read the /proc//fd directory without using the root user?

    • Hakan Baba
      Hakan Baba about 7 years
      I see this in 3.10.0-514.10.2.el7.x86_64 kernel. My actual use case is in a docker container. However I can see the same behavior in a host OS with the same kernel too.
    • Hakan Baba
      Hakan Baba about 7 years
      In addition to cap_sys_resource I can see the same behavior if the process has cap_net_bind_service capability.
    • Hakan Baba
      Hakan Baba about 7 years
      If both capabilities are removed from the process, all files in /proc/<pid> are owned by the ec2-user and the fd directory can be read.
  • Hakan Baba
    Hakan Baba about 7 years
    Let me update the question. Same user is trying to read the /proc/pid/fd. Not root.
  • TheDiveO
    TheDiveO almost 4 years
    @sourcejedi: thanks for being rude ... I am hitting the same problem where a root process with reduced capabilities can read the fd links, but the process as non-root with the same effective capabilities cannot. So maybe you can elaborate instead of just being rude?
  • user2948306
    user2948306 almost 4 years
    @TheDiveO setting a capability on a program file is analogous to set-uid root on a program file. When you run the program file in either case, you as a normal user are not allowed to interfere or snoop on the process using a debugger like gdb. Nor are you allowed to use /proc/$pid/fd/ to gain access to the files it has opened. That is the problem @Hakan_Baba had. Is it the problem you are having?
  • TheDiveO
    TheDiveO almost 4 years
    The problem is the exact capability required for scanning /proc/$PID/fd. I'm well aware of file capabilities and also how to use ambient capabilities in a wrapper process when I cannot set the file caps on the final executable itself (e.g. Python). So I'm scratching my head, as HakanBaba probably does: which capability exactly, while you are talking about ptrace flags. And no, CAP_SYS_PTRACE doesn't help here, as it does not control scanning the fd directory.
  • user2948306
    user2948306 almost 4 years
    @TheDiveO you don't need any capability to do so if the target process is owned by your user AND the target process has not gained an elevated capability. You can tell if the process has been elevated and is "non-dumpable" because ls -l /proc/$pid/fd will show owned by root (while ls -ld /proc/$pid/ will show owned by the user).
  • user2948306
    user2948306 almost 4 years
    @TheDiveO oh I see, you'd need CAP_DAC_READ_SEARCH to override the fact that the directory is owned by root and has a restrictive mode.
  • user2948306
    user2948306 almost 4 years
    @HakanBaba TheDiveO pointed out my deleted comment was wrong. I've edited my answer thanks to their feedback.