pwncollege / dojo

Infrastructure powering the pwn.college dojo
https://pwn.college
BSD 2-Clause "Simplified" License
301 stars 100 forks source link

Flag readable only by `challenge` group #577

Open ConnorNelson opened 1 month ago

ConnorNelson commented 1 month ago

Can you hear the future of the dojo off in the distance? It says "Challenges shouldn't be setuid-root unless they need to be; they should be setgid-challenge".

The flag shall be readable by only the "challenge" group. And guess what, root has capabilities to ignore these permissions, so it can read too. Most challenges will just be setgid-challenge.

This group shall be ID 1337 or maybe 942 if we should be below 1000 (42 is already the shadow group on ubuntu:24.04).

The simple transition path is to just chown -R root:challenge /challenge && chmod -R 6755 /challenge. This means everything will still be setuid-root, but will now also be setgid-challenge. So, challenges that depend on being root (for chroot, binding lower ports, etc) will still work. Long term, most things will just be 2755 root:challenge--which is to say, challenges will not run as root.

Experiments

Setup:

root@0ab867cfc103:/# echo 'challenge:x:1337:' >> /etc/group
root@0ab867cfc103:/# echo 'FLAG' > /flag
root@0ab867cfc103:/# chown root:challenge /flag
root@0ab867cfc103:/# chmod 040 /flag
root@0ab867cfc103:/# ls -al /flag
----r----- 1 root challenge 5 Sep 25 23:39 /flag

We get an "egid" of 1337:

root@0ab867cfc103:/# chown root:challenge /bin/id
root@0ab867cfc103:/# chmod 2755 /bin/id
root@0ab867cfc103:/# su ubuntu
ubuntu@0ab867cfc103:/$ id
uid=1000(ubuntu) gid=1000(ubuntu) egid=1337(challenge) groups=1337(challenge),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),1000(ubuntu)
ubuntu@0ab867cfc103:/$ exit
exit
root@0ab867cfc103:/# chmod 755 /bin/id

We can read the flag using a setgid program:

root@0ab867cfc103:/# chown root:challenge /bin/cat
root@0ab867cfc103:/# chmod 2755 /bin/cat
root@0ab867cfc103:/# su ubuntu
ubuntu@0ab867cfc103:/$ cat /flag
FLAG

We can also still read the flag using a root-setuid program:

root@0ab867cfc103:/# chmod 4755 /bin/cat
root@0ab867cfc103:/# su ubuntu
ubuntu@0ab867cfc103:/$ cat /flag
FLAG

We can also read the flag using a setuid-setgid program:

root@0ab867cfc103:/# chmod 6755 /bin/cat
root@0ab867cfc103:/# su ubuntu
ubuntu@0ab867cfc103:/$ cat /flag
FLAG

Just like setuid, /bin/sh drops setgid (while /bin/sh -p does not):

root@0ab867cfc103:/# chown root:challenge /bin/sh
root@0ab867cfc103:/# chmod 2755 /bin/sh
root@0ab867cfc103:/# su ubuntu
ubuntu@0ab867cfc103:/$ sh
$ id
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev)
$ cat /flag
cat: /flag: Permission denied
$ exit
ubuntu@0ab867cfc103:/$ sh -p
$ id
uid=1000(ubuntu) gid=1000(ubuntu) egid=1337(challenge) groups=1337(challenge),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),1000(ubuntu)
$ cat /flag
FLAG
spencerpogo commented 1 month ago

We should eventually make a page with code snippets in various languages to do permissions related tasks the right way, so that challenge authors don't mess up trying to roll their own.