Commit 086fd837 by us3rn4me
parents f7dd8563 1424ff04
...@@ -14,9 +14,9 @@ It consists of various modules that aids penetration testing operations: ...@@ -14,9 +14,9 @@ It consists of various modules that aids penetration testing operations:
# Installation # Installation
sudo apt-get install python-requests python-paramiko python-netsnmp
git clone https://github.com/reverse-shell/routersploit git clone https://github.com/reverse-shell/routersploit
cd routersploit cd routersploit
pip install -r requirements.txt
./rsf.py ./rsf.py
# Update # Update
......
...@@ -86,7 +86,7 @@ class BaseInterpreter(object): ...@@ -86,7 +86,7 @@ class BaseInterpreter(object):
command_handler(args) command_handler(args)
except RoutersploitException as err: except RoutersploitException as err:
utils.print_error(err) utils.print_error(err)
except KeyboardInterrupt: except (KeyboardInterrupt, EOFError):
print() print()
utils.print_status("routersploit stopped") utils.print_status("routersploit stopped")
break break
......
...@@ -36,6 +36,7 @@ class Exploit(exploits.Exploit): ...@@ -36,6 +36,7 @@ class Exploit(exploits.Exploit):
passwords = exploits.Option(wordlists.passwords, 'Password or file with passwords (file://)') passwords = exploits.Option(wordlists.passwords, 'Password or file with passwords (file://)')
form = exploits.Option('auto', 'Post Data: auto or in form login={{LOGIN}}&password={{PASS}}&submit') form = exploits.Option('auto', 'Post Data: auto or in form login={{LOGIN}}&password={{PASS}}&submit')
path = exploits.Option('/login.php', 'URL Path') path = exploits.Option('/login.php', 'URL Path')
form_path = exploits.Option('same', 'same as path or URL Form Path')
verbosity = exploits.Option('yes', 'Display authentication attempts') verbosity = exploits.Option('yes', 'Display authentication attempts')
credentials = [] credentials = []
...@@ -46,9 +47,15 @@ class Exploit(exploits.Exploit): ...@@ -46,9 +47,15 @@ class Exploit(exploits.Exploit):
self.credentials = [] self.credentials = []
self.attack() self.attack()
def get_form_path(self):
if self.form_path == 'same':
return self.path
else:
return self.form_path
@multi @multi
def attack(self): def attack(self):
url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path)) url = sanitize_url("{}:{}{}".format(self.target, self.port, self.get_form_path()))
try: try:
requests.get(url, verify=False) requests.get(url, verify=False)
...@@ -61,11 +68,15 @@ class Exploit(exploits.Exploit): ...@@ -61,11 +68,15 @@ class Exploit(exploits.Exploit):
# authentication type # authentication type
if self.form == 'auto': if self.form == 'auto':
self.data = self.detect_form() form_data = self.detect_form()
if self.data is None: if form_data is None:
print_error("Could not detect form") print_error("Could not detect form")
return return
(form_action, self.data) = form_data
if form_action:
self.path = form_action
else: else:
self.data = self.form self.data = self.form
...@@ -116,7 +127,7 @@ class Exploit(exploits.Exploit): ...@@ -116,7 +127,7 @@ class Exploit(exploits.Exploit):
self.invalid["max"] = l self.invalid["max"] = l
def detect_form(self): def detect_form(self):
url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path)) url = sanitize_url("{}:{}{}".format(self.target, self.port, self.get_form_path()))
r = requests.get(url, verify=False) r = requests.get(url, verify=False)
soup = BeautifulSoup(r.text, "lxml") soup = BeautifulSoup(r.text, "lxml")
...@@ -125,20 +136,22 @@ class Exploit(exploits.Exploit): ...@@ -125,20 +136,22 @@ class Exploit(exploits.Exploit):
if form is None: if form is None:
return None return None
action = form.attrs.get('action', None)
if len(form) > 0: if len(form) > 0:
res = [] res = []
for inp in form.findAll("input"): for inp in form.findAll("input"):
if 'name' in inp.attrs.keys(): if 'name' in inp.attrs.keys():
if inp.attrs['name'].lower() in ["username", "user", "login"]: if inp.attrs['name'].lower() in ["username", "user", "login", "username_login"]:
res.append(inp.attrs['name'] + "=" + "{{USER}}") res.append(inp.attrs['name'] + "=" + "{{USER}}")
elif inp.attrs['name'].lower() in ["password", "pass"]: elif inp.attrs['name'].lower() in ["password", "pass", "password_login"]:
res.append(inp.attrs['name'] + "=" + "{{PASS}}") res.append(inp.attrs['name'] + "=" + "{{PASS}}")
else: else:
if 'value' in inp.attrs.keys(): if 'value' in inp.attrs.keys():
res.append(inp.attrs['name'] + "=" + inp.attrs['value']) res.append(inp.attrs['name'] + "=" + inp.attrs['value'])
else: else:
res.append(inp.attrs['name'] + "=") res.append(inp.attrs['name'] + "=")
return '&'.join(res) return (action, '&'.join(res))
def target_function(self, running, data): def target_function(self, running, data):
module_verbosity = boolify(self.verbosity) module_verbosity = boolify(self.verbosity)
......
...@@ -34,6 +34,7 @@ class Exploit(exploits.Exploit): ...@@ -34,6 +34,7 @@ class Exploit(exploits.Exploit):
defaults = exploits.Option(wordlists.defaults, 'User:Pass or file with default credentials (file://)') defaults = exploits.Option(wordlists.defaults, 'User:Pass or file with default credentials (file://)')
form = exploits.Option('auto', 'Post Data: auto or in form login={{LOGIN}}&password={{PASS}}&submit') form = exploits.Option('auto', 'Post Data: auto or in form login={{LOGIN}}&password={{PASS}}&submit')
path = exploits.Option('/login.php', 'URL Path') path = exploits.Option('/login.php', 'URL Path')
form_path = exploits.Option('same', 'same as path or URL Form Path')
verbosity = exploits.Option('yes', 'Display authentication attempts') verbosity = exploits.Option('yes', 'Display authentication attempts')
credentials = [] credentials = []
...@@ -44,9 +45,15 @@ class Exploit(exploits.Exploit): ...@@ -44,9 +45,15 @@ class Exploit(exploits.Exploit):
self.credentials = [] self.credentials = []
self.attack() self.attack()
def get_form_path(self):
if self.form_path == 'same':
return self.path
else:
return self.form_path
@multi @multi
def attack(self): def attack(self):
url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path)) url = sanitize_url("{}:{}{}".format(self.target, self.port, self.get_form_path()))
try: try:
requests.get(url, verify=False) requests.get(url, verify=False)
...@@ -59,11 +66,15 @@ class Exploit(exploits.Exploit): ...@@ -59,11 +66,15 @@ class Exploit(exploits.Exploit):
# authentication type # authentication type
if self.form == 'auto': if self.form == 'auto':
self.data = self.detect_form() form_data = self.detect_form()
if self.data is None: if form_data is None:
print_error("Could not detect form") print_error("Could not detect form")
return return
(form_action, self.data) = form_data
if form_action:
self.path = form_action
else: else:
self.data = self.form self.data = self.form
...@@ -109,7 +120,7 @@ class Exploit(exploits.Exploit): ...@@ -109,7 +120,7 @@ class Exploit(exploits.Exploit):
self.invalid["max"] = l self.invalid["max"] = l
def detect_form(self): def detect_form(self):
url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path)) url = sanitize_url("{}:{}{}".format(self.target, self.port, self.get_form_path()))
r = requests.get(url, verify=False) r = requests.get(url, verify=False)
soup = BeautifulSoup(r.text, "lxml") soup = BeautifulSoup(r.text, "lxml")
...@@ -118,20 +129,22 @@ class Exploit(exploits.Exploit): ...@@ -118,20 +129,22 @@ class Exploit(exploits.Exploit):
if form is None: if form is None:
return None return None
action = form.attrs.get('action', None)
if len(form) > 0: if len(form) > 0:
res = [] res = []
for inp in form.findAll("input"): for inp in form.findAll("input"):
if 'name' in inp.attrs.keys(): if 'name' in inp.attrs.keys():
if inp.attrs['name'].lower() in ["username", "user", "login"]: if inp.attrs['name'].lower() in ["username", "user", "login", "username_login"]:
res.append(inp.attrs['name'] + "=" + "{{USER}}") res.append(inp.attrs['name'] + "=" + "{{USER}}")
elif inp.attrs['name'].lower() in ["password", "pass"]: elif inp.attrs['name'].lower() in ["password", "pass", "password_login"]:
res.append(inp.attrs['name'] + "=" + "{{PASS}}") res.append(inp.attrs['name'] + "=" + "{{PASS}}")
else: else:
if 'value' in inp.attrs.keys(): if 'value' in inp.attrs.keys():
res.append(inp.attrs['name'] + "=" + inp.attrs['value']) res.append(inp.attrs['name'] + "=" + inp.attrs['value'])
else: else:
res.append(inp.attrs['name'] + "=") res.append(inp.attrs['name'] + "=")
return '&'.join(res) return (action, '&'.join(res))
def target_function(self, running, data): def target_function(self, running, data):
module_verbosity = boolify(self.verbosity) module_verbosity = boolify(self.verbosity)
......
...@@ -17,7 +17,7 @@ class Exploit(exploits.Exploit): ...@@ -17,7 +17,7 @@ class Exploit(exploits.Exploit):
__info__ = { __info__ = {
'name': 'AutoPwn', 'name': 'AutoPwn',
'description': 'Scanner module for all vulnerabilities.', 'description': 'Scanner module for all vulnerabilities.',
'author': [ 'authors': [
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module 'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
], ],
} }
......
...@@ -17,7 +17,7 @@ class Exploit(exploits.Exploit): ...@@ -17,7 +17,7 @@ class Exploit(exploits.Exploit):
__info__ = { __info__ = {
'name': 'D-Link Scanner', 'name': 'D-Link Scanner',
'description': 'Scanner module for D-Link devices', 'description': 'Scanner module for D-Link devices',
'author': [ 'authors': [
'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module 'Marcin Bury <marcin.bury[at]reverse-shell.com>', # routersploit module
], ],
} }
......
...@@ -314,7 +314,7 @@ def pprint_dict_in_order(dictionary, order=None): ...@@ -314,7 +314,7 @@ def pprint_dict_in_order(dictionary, order=None):
prettyprint(rest_keys, dictionary[rest_keys]) prettyprint(rest_keys, dictionary[rest_keys])
def random_text(length, alph=string.letters+string.digits): def random_text(length, alph=string.ascii_letters+string.digits):
""" Random text generator. NOT crypto safe. """ Random text generator. NOT crypto safe.
Generates random text with specified length and alphabet. Generates random text with specified length and alphabet.
......
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