Skip to content

Instantly share code, notes, and snippets.

@JohnStrunk
Last active September 15, 2022 16:29
Show Gist options
  • Save JohnStrunk/e61592f681d6a42b997ef28ccc575cb9 to your computer and use it in GitHub Desktop.
Save JohnStrunk/e61592f681d6a42b997ef28ccc575cb9 to your computer and use it in GitHub Desktop.
What capabilities are needed to manipulate files
FROM registry.access.redhat.com/ubi9:latest
RUN rpm -i http://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/Packages/attr-2.5.1-3.el9.x86_64.rpm
ADD script.sh /
RUN chmod a+rx /script.sh
CMD [ "/script.sh" ]
#! /bin/bash
set -e -o pipefail
docker build -t capability-experiment .
docker run --rm capability-experiment
#! /bin/bash
echo; echo Starting caps:
capsh --print | grep Current:
# Set up files
mkdir /original
echo "hello" > /original/ownedbyroot
chmod 600 /original/ownedbyroot
cp /original/ownedbyroot /original/ownedby1111
chown 1111:1111 /original/ownedby1111
chmod 600 /original/ownedby1111
read -r -d '' COMMANDS << EOF
echo; echo
capsh --print | grep Current: | awk '{print "Using Caps: " \$2}'
echo -n "Read root: "
if cat /original/ownedbyroot >& /dev/null; then echo "yes"; else echo "NO"; fi
echo -n "Read file uid 1111: "
if cat /original/ownedby1111 >& /dev/null; then echo "yes"; else echo "NO"; fi
echo -n "Copy file uid 1111: "
if cp -a /original/ownedby1111 /test/; then echo "yes"; else echo "NO"; fi
echo -n "Copied file still has uid 1111: "
if [[ \$(stat -c %u /test/ownedby1111) == 1111 ]]; then echo "yes"; else echo "NO"; fi
echo -n "chmod 1111: "
if chmod g+x /test/ownedby1111; then echo "yes"; else echo "NO"; fi
echo -n "chgrp 1111: "
if chgrp 2222 /test/ownedby1111; then echo "yes"; else echo "NO"; fi
echo -n "chown 1111: "
if chown 2222 /test/ownedby1111; then echo "yes"; else echo "NO"; fi
echo -n "setgid 1111: "
if chmod 2640 /test/ownedby1111; then echo "yes"; else echo "NO"; fi
echo -n "sticky /test: "
if chmod 1777 /test; then echo "yes"; else echo "NO"; fi
echo -n "mtime: "
if touch -d 2022-02-01 -m /test/ownedby1111; then echo "yes"; else echo "NO"; fi
echo -n "atime: "
if touch -d 2022-03-01 -a /test/ownedby1111; then echo "yes"; else echo "NO"; fi
echo -n "dump ext attrs: "
if getfattr -m - -d /test/ownedby1111 > /dev/null; then echo "yes"; else echo "NO"; fi
echo -n "set normal ext attr: "
if setfattr -n user.foo -v hello /test/ownedby1111; then echo "yes"; else echo "NO"; fi
echo -n "set security ext attr: "
if setfattr -n security.foo -v hello /test/ownedby1111; then echo "yes"; else echo "NO"; fi
echo; echo "File attributes:"
stat -c "%N %F u:%u g:%g m:%a c:%w m:%y a:%x" /original /original/* /test /test/*
EOF
# Drop all
rm -rf /test; mkdir /test
capsh --drop="cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap" -- -c "$COMMANDS"
# cap_dac_override
rm -rf /test; mkdir /test
capsh --drop="cap_chown,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap" -- -c "$COMMANDS"
# cap_chown,cap_dac_override
rm -rf /test; mkdir /test
capsh --drop="cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap" -- -c "$COMMANDS"
# cap_chown,cap_dac_override,cap_fowner,
rm -rf /test; mkdir /test
capsh --drop="cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap" -- -c "$COMMANDS"
# Needed caps:
# - cap_chown: Set file ownership/group
# - cap_dac_override: read/write all file data
# - cap_fowner: set permissions (setgid bit), times
# - cap_sys_admin: set security ext attrs (man xattr)
@JohnStrunk
Copy link
Author

Output:

$ ./run
bash: ./run: No such file or directory
[jstrunk capability-experiment]$ ./run.sh 
Sending build context to Docker daemon  6.656kB
Step 1/4 : FROM registry.access.redhat.com/ubi9:latest
 ---> 168c58a38365
Step 2/4 : ADD script.sh /
 ---> Using cache
 ---> f0fe402e34de
Step 3/4 : RUN chmod a+rx /script.sh
 ---> Using cache
 ---> 622348bd7cb5
Step 4/4 : CMD [ "/script.sh" ]
 ---> Using cache
 ---> e129ed061488
Successfully built e129ed061488
Successfully tagged capability-experiment:latest

Starting caps:
Current: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep


Using Caps: =
Read root: yes
Read file uid 1111: NO
Copy file uid 1111: cp: cannot open '/original/ownedby1111' for reading: Permission denied
NO
Copied file still has uid 1111: stat: cannot statx '/test/ownedby1111': No such file or directory
NO
chmod 1111: chmod: cannot access '/test/ownedby1111': No such file or directory
NO
chgrp 1111: chgrp: cannot access '/test/ownedby1111': No such file or directory
NO
chown 1111: chown: cannot access '/test/ownedby1111': No such file or directory
NO
setgid 1111: chmod: cannot access '/test/ownedby1111': No such file or directory
NO
sticky /test: yes
mtime: yes
atime: yes

File attributes:
'/original' directory u:0 g:0 m:755 c:2022-09-15 15:50:21.878600554 +0000 m:2022-09-15 15:50:21.879600563 +0000 a:2022-09-15 15:50:21.899600728 +0000
'/original/ownedby1111' regular file u:1111 g:1111 m:600 c:2022-09-15 15:50:21.879600563 +0000 m:2022-09-15 15:50:21.880600571 +0000 a:2022-09-15 15:50:21.879600563 +0000
'/original/ownedbyroot' regular file u:0 g:0 m:600 c:2022-09-15 15:50:21.878600554 +0000 m:2022-09-15 15:50:21.878600554 +0000 a:2022-09-15 15:50:21.887600629 +0000
'/test' directory u:0 g:0 m:1777 c:2022-09-15 15:50:21.884600604 +0000 m:2022-09-15 15:50:21.898600720 +0000 a:2022-09-15 15:50:21.899600728 +0000
'/test/ownedby1111' regular empty file u:0 g:0 m:644 c:2022-09-15 15:50:21.898600720 +0000 m:2022-02-01 00:00:00.000000000 +0000 a:2022-03-01 00:00:00.000000000 +0000


Using Caps: cap_dac_override=ep
Read root: yes
Read file uid 1111: yes
Copy file uid 1111: cp: failed to preserve ownership for '/test/ownedby1111': Operation not permitted
NO
Copied file still has uid 1111: NO
chmod 1111: yes
chgrp 1111: chgrp: changing group of '/test/ownedby1111': Operation not permitted
NO
chown 1111: chown: changing ownership of '/test/ownedby1111': Operation not permitted
NO
setgid 1111: yes
sticky /test: yes
mtime: yes
atime: yes

File attributes:
'/original' directory u:0 g:0 m:755 c:2022-09-15 15:50:21.878600554 +0000 m:2022-09-15 15:50:21.879600563 +0000 a:2022-09-15 15:50:21.899600728 +0000
'/original/ownedby1111' regular file u:1111 g:1111 m:600 c:2022-09-15 15:50:21.879600563 +0000 m:2022-09-15 15:50:21.880600571 +0000 a:2022-09-15 15:50:21.906600786 +0000
'/original/ownedbyroot' regular file u:0 g:0 m:600 c:2022-09-15 15:50:21.878600554 +0000 m:2022-09-15 15:50:21.878600554 +0000 a:2022-09-15 15:50:21.887600629 +0000
'/test' directory u:0 g:0 m:1777 c:2022-09-15 15:50:21.902600753 +0000 m:2022-09-15 15:50:21.908600803 +0000 a:2022-09-15 15:50:21.917600877 +0000
'/test/ownedby1111' regular file u:0 g:0 m:2640 c:2022-09-15 15:50:21.908600803 +0000 m:2022-02-01 00:00:00.000000000 +0000 a:2022-03-01 00:00:00.000000000 +0000


Using Caps: cap_chown,cap_dac_override=ep
Read root: yes
Read file uid 1111: yes
Copy file uid 1111: cp: preserving permissions for '/test/ownedby1111': Operation not permitted
NO
Copied file still has uid 1111: yes
chmod 1111: chmod: changing permissions of '/test/ownedby1111': Operation not permitted
NO
chgrp 1111: yes
chown 1111: yes
setgid 1111: chmod: changing permissions of '/test/ownedby1111': Operation not permitted
NO
sticky /test: yes
mtime: touch: cannot touch '/test/ownedby1111': Permission denied
NO
atime: touch: cannot touch '/test/ownedby1111': Permission denied
NO

File attributes:
'/original' directory u:0 g:0 m:755 c:2022-09-15 15:50:21.878600554 +0000 m:2022-09-15 15:50:21.879600563 +0000 a:2022-09-15 15:50:21.899600728 +0000
'/original/ownedby1111' regular file u:1111 g:1111 m:600 c:2022-09-15 15:50:21.879600563 +0000 m:2022-09-15 15:50:21.880600571 +0000 a:2022-09-15 15:50:21.906600786 +0000
'/original/ownedbyroot' regular file u:0 g:0 m:600 c:2022-09-15 15:50:21.878600554 +0000 m:2022-09-15 15:50:21.878600554 +0000 a:2022-09-15 15:50:21.887600629 +0000
'/test' directory u:0 g:0 m:1777 c:2022-09-15 15:50:21.920600902 +0000 m:2022-09-15 15:50:21.925600943 +0000 a:2022-09-15 15:50:21.933601010 +0000
'/test/ownedby1111' regular file u:2222 g:2222 m:600 c:2022-09-15 15:50:21.925600943 +0000 m:2022-09-15 15:50:21.880600571 +0000 a:2022-09-15 15:50:21.906600786 +0000


Using Caps: cap_chown,cap_dac_override,cap_fowner=ep
Read root: yes
Read file uid 1111: yes
Copy file uid 1111: yes
Copied file still has uid 1111: yes
chmod 1111: yes
chgrp 1111: yes
chown 1111: yes
setgid 1111: yes
sticky /test: yes
mtime: yes
atime: yes

File attributes:
'/original' directory u:0 g:0 m:755 c:2022-09-15 15:50:21.878600554 +0000 m:2022-09-15 15:50:21.879600563 +0000 a:2022-09-15 15:50:21.899600728 +0000
'/original/ownedby1111' regular file u:1111 g:1111 m:600 c:2022-09-15 15:50:21.879600563 +0000 m:2022-09-15 15:50:21.880600571 +0000 a:2022-09-15 15:50:21.906600786 +0000
'/original/ownedbyroot' regular file u:0 g:0 m:600 c:2022-09-15 15:50:21.878600554 +0000 m:2022-09-15 15:50:21.878600554 +0000 a:2022-09-15 15:50:21.887600629 +0000
'/test' directory u:0 g:0 m:1777 c:2022-09-15 15:50:21.936601034 +0000 m:2022-09-15 15:50:21.942601084 +0000 a:2022-09-15 15:50:21.951601159 +0000
'/test/ownedby1111' regular file u:2222 g:2222 m:640 c:2022-09-15 15:50:21.942601084 +0000 m:2022-02-01 00:00:00.000000000 +0000 a:2022-03-01 00:00:00.000000000 +0000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment