Unverified Commit 5919df7e by Mariusz Kupidura Committed by GitHub

Validate exploit's setup before `run` and `check` commands (#367)

Introduce `Exploit.validate_setup` method in order to check whether
Exploit's setup is correct. In most case scanarios we will check
if `Exploit.target` is not `None`. When exploit need custom
validation logic please overwrite `validate_setup`.
parent 5fd3e7d8
......@@ -4,6 +4,7 @@ import time
from itertools import chain
from weakref import WeakKeyDictionary
from routersploit.exceptions import OptionValidationError
from routersploit.utils import print_status, NonStringIterable
GLOBAL_OPTS = {}
......@@ -133,3 +134,12 @@ class Exploit(BaseExploit):
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.")
......@@ -6,7 +6,10 @@ import traceback
from collections import Counter
from routersploit import utils
from routersploit.exceptions import RoutersploitException
from routersploit.exceptions import (
RoutersploitException,
OptionValidationError,
)
from routersploit.exploits import Exploit, GLOBAL_OPTS
from routersploit.payloads import BasePayload
from routersploit.printer import PrinterThread, printer_queue
......@@ -328,12 +331,15 @@ class RoutersploitInterpreter(BaseInterpreter):
@utils.module_required
def command_run(self, *args, **kwargs):
utils.print_status("Running module...")
try:
self.current_module.validate_setup()
utils.print_status("Running module...")
self.current_module.run()
except KeyboardInterrupt:
utils.print_info()
utils.print_error("Operation cancelled by user")
except OptionValidationError as err:
utils.print_error(err)
except Exception:
utils.print_error(traceback.format_exc(sys.exc_info()))
......@@ -477,6 +483,7 @@ class RoutersploitInterpreter(BaseInterpreter):
@utils.module_required
def command_check(self, *args, **kwargs):
try:
self.current_module.validate_setup()
result = self.current_module.check()
except Exception as error:
utils.print_error(error)
......
......@@ -3,6 +3,7 @@ import unittest
import mock
from routersploit.exceptions import OptionValidationError
from routersploit.exploits import Exploit, GLOBAL_OPTS, Option
from tests.test_case import RoutersploitTestCase
......@@ -95,6 +96,11 @@ class OptionTest(RoutersploitTestCase):
self.assertEqual(self.exploit_bar.options, ['paa', 'target', 'doo'])
self.assertEqual(self.exploit_foo.options, ['paa', 'target', 'doo'])
def test_validate_setup(self):
with self.assertRaises(OptionValidationError):
self.exploit_bar.target = ""
self.exploit_bar.validate_setup()
if __name__ == '__main__':
unittest.main()
......@@ -154,56 +154,77 @@ class RoutersploitInterpreterTest(RoutersploitTestCase):
@mock.patch('routersploit.utils.print_status')
def test_command_run(self, mock_print_status):
with mock.patch.object(self.interpreter.current_module,
'run') as mock_run:
mock_run = mock.Mock()
mock_validate_setup = mock.Mock()
self.interpreter.current_module.run = mock_run
self.interpreter.current_module.validate_setup = mock_validate_setup
self.interpreter.command_run()
mock_validate_setup.assert_called_once()
mock_run.assert_called_once_with()
mock_print_status.assert_called_once_with('Running module...')
@mock.patch('routersploit.utils.print_success')
def test_command_check_target_vulnerable(self, mock_print_success):
with mock.patch.object(self.interpreter.current_module,
'check') as mock_check:
mock_check = mock.Mock()
mock_validate_setup = mock.Mock()
self.interpreter.current_module.check = mock_check
self.interpreter.current_module.validate_setup = mock_validate_setup
mock_check.return_value = True
self.interpreter.command_check()
mock_validate_setup.assert_called_once()
mock_check.assert_called_once_with()
mock_print_success.assert_called_once_with('Target is vulnerable')
@mock.patch('routersploit.utils.print_error')
def test_command_check_target_not_vulnerable(self, print_error):
with mock.patch.object(self.interpreter.current_module,
'check') as mock_check:
mock_check = mock.Mock()
mock_validate_setup = mock.Mock()
self.interpreter.current_module.check = mock_check
self.interpreter.current_module.validate_setup = mock_validate_setup
mock_check.return_value = False
self.interpreter.command_check()
mock_validate_setup.assert_called_once()
mock_check.assert_called_once_with()
print_error.assert_called_once_with('Target is not vulnerable')
@mock.patch('routersploit.utils.print_status')
def test_command_check_target_could_not_be_verified_1(self, print_status):
with mock.patch.object(self.interpreter.current_module,
'check') as mock_check:
mock_check = mock.Mock()
mock_validate_setup = mock.Mock()
self.interpreter.current_module.check = mock_check
self.interpreter.current_module.validate_setup = mock_validate_setup
mock_check.return_value = "something"
self.interpreter.command_check()
mock_validate_setup.assert_called_once()
mock_check.assert_called_once_with()
print_status.assert_called_once_with(
'Target could not be verified')
print_status.assert_called_once_with('Target could not be verified')
@mock.patch('routersploit.utils.print_status')
def test_command_check_target_could_not_be_verified_2(self, print_status):
with mock.patch.object(self.interpreter.current_module,
'check') as mock_check:
mock_check = mock.Mock()
mock_validate_setup = mock.Mock()
self.interpreter.current_module.check = mock_check
self.interpreter.current_module.validate_setup = mock_validate_setup
mock_check.return_value = None
self.interpreter.command_check()
mock_validate_setup.assert_called_once()
mock_check.assert_called_once_with()
print_status.assert_called_once_with(
'Target could not be verified')
print_status.assert_called_once_with('Target could not be verified')
@mock.patch('routersploit.utils.print_error')
def test_command_check_not_supported_by_module(self, print_error):
with mock.patch.object(self.interpreter.current_module,
'check') as mock_check:
mock_check = mock.Mock()
mock_validate_setup = mock.Mock()
self.interpreter.current_module.check = mock_check
self.interpreter.current_module.validate_setup = mock_validate_setup
exception = NotImplementedError("Not available")
mock_check.side_effect = exception
self.interpreter.command_check()
mock_check.assert_called_once_with()
print_error.assert_called_once_with(exception)
......
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