QNAP MusicStation and MalwareRemover official apps are affected by an arbitrary file upload and a command injection vulnerabilities, leading to pre-auth remote root command execution.
“QNAP (Quality Network Appliance Provider) is devoted to providing comprehensive solutions in software development, hardware design and in-house manufacturing.”. For more information visit https://qnap.com/.
“Music Station is a web-based music player for users to enjoy their music collection on the NAS.” from QNAP App Center.
MusicStation is not pre-installed on the QNAP device, but it is one of the most popular apps in the QNAP ecosystem, counting more than 5 million installations in the QNAP App Center. The app allows the user to manage their music on the NAS device through a web browser.
The file musicstation/api/upload.php
allows anyone to upload an album cover on the NAS Device:
|
|
At [1] the HTTP parameter ‘arttype’ is loaded from the user HTTP request. At [2] the user-input filename extension (HTTP POST “singleFile” parameter’s name) is verified to be one of an image file: “jpeg”, “jpg” or “png”. At [3] the destination filename is assembled using the user-input arttype
as a prefix (https://www.php.net/uniqid) and right after it is moved there. By providing a malicious arttype
it is possible to write arbitrary files to a partially controlled location (specifically, the app will suffix the attacker’s provided filename with _[a-f0-9]{13}\.(jpg|jpeg|png)
) in the QTS file system, since MusicStation (and all the other apps by default) runs with administrative privileges (root).
The following HTTP request plants a file with filename prefix /tmp/polict
:
|
|
The final path is disclosed in the HTTP response in the fid
field, e.g. Li4vLi4vLi4vLi4vLi4vLi4vdG1wL3BvbGljdF81ZWUyOGU5YTAyZTM5LmpwZw-3D-3D
is ../../../../../../tmp/polict_5ee28e9a02e39.jpg
, which is /tmp/polict_5ee28e9a02e39.jpg
confirmed by a shell check:
# cat /tmp/polict_5ee28e9a02e39.jpg
any content
“The Malware Remover is designed to protect your Turbo NAS against harmful software. QNAP strongly recommends that you install this app to avoid potential security risks.” from QNAP App Center.
MalwareRemover is a pre-installed and “non-removable” app ("- For device security reasons, you can no longer remove Malware Remover from App Center." from https://www.qnap.com/en/app_releasenotes/list.php?app_choose=MalwareRemover) running on the NAS device.
By default it runs a malware scan via cronjob everyday at 3 AM, however the time can be changed in the app’s settings. sh /share/CACHEDEV1_DATA/.qpkg/MalwareRemover/MalwareRemover.sh scan
is the registered cronjob command to perform the scan. In turn it executes python /share/CACHEDEV1_DATA/.qpkg/MalwareRemover/modules/centre.pyc --check
, which will then execute sh /share/CACHEDEV1_DATA/.qpkg/MalwareRemover/MalwareRemover_scan.sh
. Such file will cycle and run all the anti-malware rules included in the app:
|
|
Whereas common.sh
contains:
|
|
At [1] the function get_modules
is called, which at [4] lists the available files in a specific MalwareRemover folder ($QPKG_ROOT
refers to the MalwareRemover QNAP Package folder location which by default is /share/CACHEDEV1_DATA/.qpkg/MalwareRemover/
) matching the [0-9][0-9]_[0-9a-zA-Z_]\+\(\.[0-9a-zA-Z_\-]\+\)\?
pattern (by the way, this stricter pattern broke the first “file write -> rce” gadget identified), and its output is saved to the modules
variable. At [2] if the current “module” filename doesn’t match the pattern (\.py|\.pyc|\.sh)$
, /bin/sh -c
is used as launcher program, which will interpret its following arguments as shell commands at [3].
The default MalwareRemover installation includes 19 modules, mostly in pyc
format (decompilable using uncompyle6). modules/02_autoupgrade.pyc
is vulnerable to a command injection and an arbitrary file write in an arbitrary file path (both vulnerabilities allow Remote Code Execution (RCE) as root (administrator)):
|
|
config_path
is a bytearray containing “/tmp/config”, which will be used in check_tmp_config
, defined in modules/autoupgrade.pyc
:
|
|
At [1] mount_config
is called, which will mount a temporary file system in /tmp/config
(config_path
). At [2] the content of the file system mounted in “/tmp/config” is listed (Note: between [1] and [2] any file created/moved in /tmp/config
will be read at [2], indeed this race condition will be exploited) and checked if it contains a tar file and if is_tarball_match
returns True. tarfile.is_tarfile
doesn’t require the path to have any particular file extension. is_tarball_match
is defined in gadget.py
:
|
|
At [1] the tar file is parsed and at [2] all the file entries are extracted in a temporary folder. This is vulnerable to path traversal which enables to write/overwrite any file in the file system with an arbitrary file, like the documentation warns (Warning Never extract archives from untrusted sources without prior inspection. It is possible that files are created outside of path, e.g. members that have absolute filenames starting with "/" or filenames with two dots ".."
), however there’s a more immediate way than that to achieve Remote Code Execution. At [3] each filename included in the tar file is checked through an unsafe shell command execution. Via a malicious filename in the input tar file it is possible to achieve Remote Code Execution as root (administrator), e.g. using https://github.com/ptoomey3/evilarc and a bash TCP reverse shell payload:
|
|
The next time MalwareRemover finds and scans the such file, it will spawn a TCP reverse shell as root.
The full PoC code is available on GitHub.
By chaining both issues it’s possible to gain pre-auth Remote Code Execution with root privileges on a remote QNAP NAS.
Upgrade QNAP MusicStation and MalwareRemover to the latest version available. (Note: we didn’t verify the patches.)
This advisory was first published on https://www.shielder.com/advisories/qnap-musicstation-malwareremover-pre-auth-remote-code-execution/
Date
19 May 2021