Projects STRLCPY routeros-scanner Commits cea92326
🤬
  • fix ttl, fix paramiko params and add try-except

  • Loading...
  • noafru committed 2 years ago
    cea92326
    1 parent 9a834d34
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■
    commands/basecommand.py
    1 1  # Copyright (c) Microsoft Corporation.
    2 2  # Licensed under the MIT License.
     3 +import traceback
     4 +import sys
     5 + 
    3 6   
    4 7  class BaseCommand(object):
    5 8   def _ssh_data(self, sshc, command):
    6  - stdin, stdout, stderr = sshc.exec_command(command)
     9 + try:
     10 + stdin, stdout, stderr = sshc.exec_command(command)
    7 11   
    8  - return str(stdout.read())
     12 + return str(stdout.read())
     13 + except Exception:
     14 + print(traceback.format_exc(), file = sys.stderr)
     15 + return ''
    9 16   
    10 17   def _ssh_data_with_header(self, sshc, command):
    11 18   data = self._ssh_data(sshc, command)
    12 19   res = []
    13 20   
    14  - if ' 0 ' in data:
    15  - res = data.partition(' 0 ')[2].split('\\r\\n\\r\\n')[:-1]
    16  - res = list(map(lambda y: self._parse_data(y), res))
     21 + try:
     22 + if ' 0 ' in data:
     23 + res = data.partition(' 0 ')[2].split('\\r\\n\\r\\n')[:-1]
     24 + res = list(map(lambda y: self._parse_data(y), res))
     25 + except Exception:
     26 + print(traceback.format_exc(), file = sys.stderr)
    17 27   
    18 28   return res
    19 29   
    skipped 9 lines
  • ■ ■ ■ ■ ■
    commands/dns.py
    1 1  # Copyright (c) Microsoft Corporation.
    2 2  # Licensed under the MIT License.
     3 +import traceback
     4 +import re
     5 +import sys
    3 6   
    4 7  from commands.basecommand import BaseCommand
    5 8   
    skipped 17 lines
    23 26   sus_dns = []
    24 27   recommendation = []
    25 28   
    26  - for item in res:
    27  - if int(item['ttl'].partition('s')[0]) > 200000:
    28  - sus_dns.append(f'Domain name: {item["name"]} with ip {item["address"]}: might be DNS poisoning- '
    29  - f'severity: high')
     29 + try:
     30 + for item in res:
     31 + if self.calc_sec(item['ttl']) > 200000:
     32 + address_key = "address"
     33 + if "data" in item:
     34 + address_key = "data" #as seen in RouterOs T.D.L
     35 + 
     36 + sus_dns.append(f'Domain name: {item["name"]} with ip {item[address_key]}: might be DNS poisoning - '
     37 + f'severity: high')
     38 + except Exception:
     39 + print(traceback.format_exc(), file = sys.stderr)
    30 40   
    31 41   if enabled:
    32 42   recommendation.append('In case DNS cache is not required on your router - disable it')
    33 43   
    34 44   return sus_dns, recommendation
     45 + 
     46 + def calc_sec(self, ttl):
     47 + to_sec = {'s': 1, 'm': 60, 'h':3600, 'd':86400, 'w': 604800}
     48 + time = re.findall(r"(\d+)([a-z])", ttl)
     49 + return sum(list(map(lambda item: int(item[0]) * to_sec[item[1]], time)))
     50 + 
    35 51   
    36 52   
    37 53   
    skipped 5 lines
  • ■ ■ ■ ■ ■ ■
    commands/files.py
    1 1  # Copyright (c) Microsoft Corporation.
    2 2  # Licensed under the MIT License.
     3 +import traceback
     4 +import sys
    3 5   
    4 6  from commands.basecommand import BaseCommand
    5 7   
    skipped 14 lines
    20 22   sus_files = []
    21 23   recommendation = []
    22 24   
    23  - for item in res:
    24  - if 'contents' in item:
    25  - if ('/tool fetch' in item['contents']) or ('http://' in item['contents']):
    26  - sus_files.append(f'File name: {item["name"]}, content: {item["contents"]} - severity: high')
     25 + try:
     26 + for item in res:
     27 + if 'contents' in item:
     28 + if ('/tool fetch' in item['contents']) or ('http://' in item['contents']):
     29 + sus_files.append(f'File name: {item["name"]}, content: {item["contents"]} - severity: high')
     30 + except Exception:
     31 + print(traceback.format_exc(), file = sys.stderr)
    27 32   
    28 33   return sus_files, recommendation
    29 34   
    skipped 5 lines
  • ■ ■ ■ ■ ■ ■
    commands/fwnat.py
    1 1  # Copyright (c) Microsoft Corporation.
    2 2  # Licensed under the MIT License.
     3 +import traceback
     4 +from ipaddress import ip_address
     5 +import sys
    3 6   
    4 7  from commands.basecommand import BaseCommand
    5  -from ipaddress import ip_address
    6 8   
    7 9   
    8 10  class FWNat(BaseCommand):
    skipped 12 lines
    21 23   sus_nat = []
    22 24   recommendation = []
    23 25   
    24  - for item in res:
    25  - if (item['action'] == 'dst-nat') and ('dst-address' in item) and ('to-address' in item):
    26  - if (not ip_address(item['dst-address']).is_private) and (not ip_address(item['to-address']).is_private):
    27  - sus_nat.append(f'dst-nat rule from {item["dst-address"]} to {item["to-address"]}: both are public '
    28  - f'IPs, might used for malicious activity - severity: high')
     26 + try:
     27 + for item in res:
     28 + if (item['action'] == 'dst-nat') and ('dst-address' in item) and ('to-address' in item):
     29 + if (not ip_address(item['dst-address']).is_private) and (not ip_address(item['to-address']).is_private):
     30 + sus_nat.append(f'dst-nat rule from {item["dst-address"]} to {item["to-address"]}: both are public '
     31 + f'IPs, might used for malicious activity - severity: high')
     32 + except Exception:
     33 + print(traceback.format_exc(), file = sys.stderr)
    29 34   
    30 35   return sus_nat, recommendation
    31 36   
    skipped 9 lines
  • ■ ■ ■ ■ ■ ■
    commands/ports.py
    1 1  # Copyright (c) Microsoft Corporation.
    2 2  # Licensed under the MIT License.
     3 +import traceback
     4 +import sys
    3 5   
    4 6  from commands.basecommand import BaseCommand
    5 7   
    skipped 16 lines
    22 24   def_ports = {'telnet': 23, 'ftp': 21, 'www': 80, 'ssh': 22, 'www-ssl': 443, 'api': 8728, 'winbox': 8291,
    23 25   'api-ssl': 8729}
    24 26   
    25  - for item in res:
    26  - service = item['name']
    27  - if def_ports[service] != int(item['port']):
    28  - sus_ports.append(f'The port for {service}, has changed from {def_ports[service]} to {item["port"]} - '
    29  - f'severity: low')
     27 + try:
     28 + for item in res:
     29 + service = item['name']
     30 + if def_ports[service] != int(item['port']):
     31 + sus_ports.append(f'The port for {service}, has changed from {def_ports[service]} to {item["port"]} - '
     32 + f'severity: low')
    30 33   
    31  - if (service == 'ssh') and (int(item['port']) == 22):
    32  - recommendation.append('The port for ssh protocol is as ssh default port (22)- Mikrotik company '
    33  - 'recommended to change it')
     34 + if (service == 'ssh') and (int(item['port']) == 22):
     35 + recommendation.append('The port for ssh protocol is as ssh default port (22)- Mikrotik company '
     36 + 'recommended to change it')
     37 + except Exception:
     38 + print(traceback.format_exc(), file = sys.stderr)
    34 39   
    35 40   return sus_ports, recommendation
    36 41   
    skipped 10 lines
  • ■ ■ ■ ■ ■ ■
    commands/scheduler.py
    1 1  # Copyright (c) Microsoft Corporation.
    2 2  # Licensed under the MIT License.
     3 +import traceback
     4 +import re
     5 +import sys
    3 6   
    4 7  from commands.basecommand import BaseCommand
    5  -import re
    6 8   
    7 9   
    8 10  class Scheduler(BaseCommand):
    skipped 12 lines
    21 23   sus_tasks = []
    22 24   recommendation = []
    23 25   
    24  - for item in res:
    25  - if (re.match(r'u\d+$', item['name'].lower())) or (('/tool fetch' in item['on-event']) or
    26  - ('url' in item['on-event']) or ('http' in item['on-event'])):
    27  - sus_tasks.append(f'Task name: {item["name"]}, executes: {item["on-event"]} - severity: high')
     26 + try:
     27 + for item in res:
     28 + if (re.match(r'u\d+$', item['name'].lower())) or (('/tool fetch' in item['on-event']) or
     29 + ('url' in item['on-event']) or ('http' in item['on-event'])):
     30 + sus_tasks.append(f'Task name: {item["name"]}, executes: {item["on-event"]} - severity: high')
     31 + except Exception:
     32 + print(traceback.format_exc(), file = sys.stderr)
    28 33   
    29 34   return sus_tasks, recommendation
    30 35   
    skipped 9 lines
  • ■ ■ ■ ■ ■ ■
    commands/users.py
    1 1  # Copyright (c) Microsoft Corporation.
    2 2  # Licensed under the MIT License.
     3 +import traceback
     4 +import sys
    3 5   
    4 6  from commands.basecommand import BaseCommand
    5 7   
    skipped 14 lines
    20 22   sus_users = []
    21 23   recommendation = []
    22 24   
    23  - for item in res:
    24  - if (item['name'] == 'admin') and (item['group'] == 'full'):
    25  - recommendation.append(
    26  - 'You are using the default "admin" user name- create new user in "full" group with a unique name, '
    27  - 'and delete the admin user')
    28  - if item['address'] == '':
    29  - recommendation.append(f'Add allowed ip address to user: {item["name"]}, '
    30  - f'to be the only address it can login from')
     25 + try:
     26 + for item in res:
     27 + if (item['name'] == 'admin') and (item['group'] == 'full'):
     28 + recommendation.append(
     29 + 'You are using the default "admin" user name- create new user in "full" group with a unique name, '
     30 + 'and delete the admin user')
     31 + if item['address'] == '':
     32 + recommendation.append(f'Add allowed ip address to user: {item["name"]}, '
     33 + f'to be the only address it can login from')
     34 + except Exception:
     35 + print(traceback.format_exc(), file = sys.stderr)
    31 36   
    32 37   return sus_users, recommendation
    33 38   
    skipped 7 lines
  • ■ ■ ■ ■ ■ ■
    commands/version.py
    1 1  # Copyright (c) Microsoft Corporation.
    2 2  # Licensed under the MIT License.
     3 +import traceback
     4 +import re
     5 +import sys
    3 6   
    4 7  from commands.basecommand import BaseCommand
    5 8  from nvd import CVEValidator
    6  -import re
    7 9   
    8 10   
    9 11  class Version(BaseCommand):
    skipped 4 lines
    14 16   version = ''
    15 17   res = ''
    16 18   data = self._ssh_data(sshc, '/system resource print')
    17  - version_reg = re.search(r'version: ([\d\.]+)', data)
     19 + 
     20 + try:
     21 + version_reg = re.search(r'version: ([\d\.]+)', data)
    18 22   
    19  - if version_reg:
    20  - version = version_reg.group(1)
    21  - res = f'The Mikrotik version: {version}'
     23 + if version_reg:
     24 + version = version_reg.group(1)
     25 + res = f'The Mikrotik version: {version}'
     26 + except Exception:
     27 + print(traceback.format_exc())
    22 28   
    23 29   sus_dns, recommendation = self.check_results_ssh(version)
    24 30   
    skipped 5 lines
    30 36   sus_version = []
    31 37   recommendation = []
    32 38   
    33  - if res:
    34  - cve = CVEValidator('./assets/mikrotik_cpe_match.json')
    35  - ver_cves = cve.check_version(res)
    36  - if ver_cves:
    37  - sus_version = ver_cves
     39 + try:
     40 + if res:
     41 + cve = CVEValidator('./assets/mikrotik_cpe_match.json')
     42 + ver_cves = cve.check_version(res)
     43 + if ver_cves:
     44 + sus_version = ver_cves
     45 + except Exception:
     46 + print(traceback.format_exc(), file = sys.stderr)
    38 47   
    39 48   return sus_version, recommendation
    40 49   
    skipped 3 lines
  • ■ ■ ■ ■ ■
    main.py
    skipped 24 lines
    25 25   
    26 26   with paramiko.SSHClient() as ssh_client:
    27 27   ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    28  - ssh_client.connect(hostname=args.ip, port=args.port, username=args.userName, password=args.password)
     28 + ssh_client.connect(hostname=args.ip, port=args.port, username=args.userName, password=args.password,
     29 + look_for_keys=False, allow_agent=False)
    29 30   
    30 31   for command in commands:
    31 32   res = command.run_ssh(ssh_client)
    skipped 32 lines
Please wait...
Page is in error, reload to recover