Securely use find with sudo

According to man 7 capabilities

   CAP_DAC_READ_SEARCH
          * Bypass file read permission checks and directory read and execute permission checks;
          * Invoke open_by_handle_at(2).

This worked for me. (lines beginning with '#' are root, those with '$' are non-root) in this case the non-root user is in the wheel group.

# cp /usr/bin/find /usr/bin/sudofind
# chmod 710 /usr/bin/sudofind
# chown root:wheel /usr/bin/sudofind
# setcap cap_dac_read_search+ep /usr/bin/sudofind
# exit
$ find /root 
find: ‘/root’: Permission denied
$ sudofind /root
/root /root 
/root/Testbed 
...
... 
$ sudofind /root -exec cat {} \;
cat: /root: Permission denied 
cat: /root/Testbed: Permission denied
$ sudofind /root -printf "%u %g %m %c %p\n"
root root 644 Mon Apr 20 09:20:48.0457518493 2015 /root
root root 755 Fri Dec  4 02:34:03.0016294644 2015 /root/Testbed
...
...
$ # Capability inheritance test..
$ sudofind /root -exec /bin/sleep 10 \; &
[1] 17017
$ getpcaps $(pgrep find)
Capabilities for `17017': = cap_dac_read_search+ep
$ getpcaps $(pgrep sleep)
Capabilities for `17019': =

Given what the capability grants, it fits in with exactly what you want. I've not exhaustively checked whether find has a feature which allows you to read bytes inside of files, but obvious stuff like LD_PRELOAD and library shim attacks shouldn't work due to the nature of setuid checks in Linux, and the capability bits don't get inherited by child processes either (unlike raw setuid) so that's another bonus.

Bear in mind that what you want to do does raise possible privacy concerns in regards to temporary file creation or access, and the program could be used as a basis to mounting a race condition / privilege escalation attempt (against programs that create well-known filenames but don't do correct security checks).

Also, some poorly written applications may rely on file metadata or tree structure as a way to convey meaning or hide data. This might cause release of restricted information or reveal privileged documents not otherwise known about (security through obscurity I know, but this is a thing that closed-source vendors in particular like to do, unfortunately).

Therefore, take care and be wary about doing it and understand there is still risk associated with this even if the obvious things don't work.

Oh, and I'd be interested to see if someone has a proof of concept attack which uses this mechanism as a basis for privilege escalation in the comments!


What about locate?

locate reads one or more databases prepared by updatedb(8) and writes file names matching at least one of the PATTERNs to standard output, one per line. If --regex is not specified, PATTERNs can contain globbing characters. If any PATTERN contains no globbing characters, locate behaves as if the pattern were PATTERN.

By default, locate does not check whether files found in database still exist. locate can never report files created after the most recent update of the relevant database.

Or maybe even slocate:

Secure Locate provides a secure way to index and quickly search for files on your system. It uses incremental encoding just like GNU locate to compress its database to make searching faster, but it will also store file permissions and ownership so that users will not see files they do not have access to.

This manual page documents the GNU version of slocate. slocate Enables system users to search entire filesystems without displaying unauthorized files.


I would give the users proper permissions.

By default, if the umask is 022, directories are created so that everyone can list and stat the files in them. If not, you can manually change the permission of the directory to be the bitwise or of its old permissions and 0555:

chmod +0555 foo

And if those users don't have execute permission on all the parents of that directory (for example, another user's home directory), it probably means you should put the first directory somewhere else.

If you want to only let some users to read and execute that directory, you can change its mode to 0750, put those users in a group, and change the group owner of the directory to that group:

groupadd can_read_foo
chmod 0750 foo
chgrp can_read_foo foo
gpasswd -a alice can_read_foo
gpasswd -a bob can_read_foo

Tags:

Linux

Find

Sudo