mirror of
https://github.com/jtesta/ssh-audit.git
synced 2024-12-22 14:05:22 +01:00
Transformed comment type annotations to variable declaration annotations.
This commit is contained in:
parent
4e2f9da632
commit
60de5e55cb
@ -161,6 +161,7 @@ For convenience, a web front-end on top of the command-line tool is available at
|
|||||||
- Added version check for OpenSSH user enumeration (CVE-2018-15473).
|
- Added version check for OpenSSH user enumeration (CVE-2018-15473).
|
||||||
- Fixed crash when receiving unexpected response during host key test.
|
- Fixed crash when receiving unexpected response during host key test.
|
||||||
- Fixed hang against older Cisco devices during host key test & gex test.
|
- Fixed hang against older Cisco devices during host key test & gex test.
|
||||||
|
- Dropped support for Python 3.5 (which reached EOL in Sept. 2020).
|
||||||
|
|
||||||
### v2.3.1 (2020-10-28)
|
### v2.3.1 (2020-10-28)
|
||||||
- Now parses public key sizes for `rsa-sha2-256-cert-v01@openssh.com` and `rsa-sha2-512-cert-v01@openssh.com` host key types.
|
- Now parses public key sizes for `rsa-sha2-256-cert-v01@openssh.com` and `rsa-sha2-512-cert-v01@openssh.com` host key types.
|
||||||
|
@ -131,7 +131,7 @@ class Algorithms:
|
|||||||
# if version is not None:
|
# if version is not None:
|
||||||
# software = SSH.Software(None, product, version, None, None)
|
# software = SSH.Software(None, product, version, None, None)
|
||||||
# break
|
# break
|
||||||
rec = {} # type: Dict[int, Dict[str, Dict[str, Dict[str, int]]]]
|
rec: Dict[int, Dict[str, Dict[str, Dict[str, int]]]] = {}
|
||||||
if software is None:
|
if software is None:
|
||||||
unknown_software = True
|
unknown_software = True
|
||||||
for alg_pair in self.values:
|
for alg_pair in self.values:
|
||||||
@ -206,7 +206,7 @@ class Algorithms:
|
|||||||
def __init__(self, sshv: int, db: Dict[str, Dict[str, List[List[Optional[str]]]]]) -> None:
|
def __init__(self, sshv: int, db: Dict[str, Dict[str, List[List[Optional[str]]]]]) -> None:
|
||||||
self.__sshv = sshv
|
self.__sshv = sshv
|
||||||
self.__db = db
|
self.__db = db
|
||||||
self.__storage = {} # type: Dict[str, List[str]]
|
self.__storage: Dict[str, List[str]] = {}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sshv(self) -> int:
|
def sshv(self) -> int:
|
||||||
|
@ -43,16 +43,16 @@ class AuditConf:
|
|||||||
self.json = False
|
self.json = False
|
||||||
self.verbose = False
|
self.verbose = False
|
||||||
self.level = 'info'
|
self.level = 'info'
|
||||||
self.ipvo = () # type: Sequence[int]
|
self.ipvo: Sequence[int] = ()
|
||||||
self.ipv4 = False
|
self.ipv4 = False
|
||||||
self.ipv6 = False
|
self.ipv6 = False
|
||||||
self.make_policy = False # When True, creates a policy file from an audit scan.
|
self.make_policy = False # When True, creates a policy file from an audit scan.
|
||||||
self.policy_file = None # type: Optional[str] # File system path to a policy
|
self.policy_file: Optional[str] = None # File system path to a policy
|
||||||
self.policy = None # type: Optional[Policy] # Policy object
|
self.policy: Optional[Policy] = None # Policy object
|
||||||
self.timeout = 5.0
|
self.timeout = 5.0
|
||||||
self.timeout_set = False # Set to True when the user explicitly sets it.
|
self.timeout_set = False # Set to True when the user explicitly sets it.
|
||||||
self.target_file = None # type: Optional[str]
|
self.target_file: Optional[str] = None
|
||||||
self.target_list = [] # type: List[str]
|
self.target_list: List[str] = []
|
||||||
self.list_policies = False
|
self.list_policies = False
|
||||||
self.lookup = ''
|
self.lookup = ''
|
||||||
|
|
||||||
|
@ -46,8 +46,8 @@ class KexDH: # pragma: nocover
|
|||||||
self.__e = 0
|
self.__e = 0
|
||||||
self.set_params(g, p)
|
self.set_params(g, p)
|
||||||
|
|
||||||
self.__ed25519_pubkey = None # type: Optional[bytes]
|
self.__ed25519_pubkey: Optional[bytes] = None
|
||||||
self.__hostkey_type = None # type: Optional[bytes]
|
self.__hostkey_type: Optional[bytes] = None
|
||||||
self.__hostkey_e = 0
|
self.__hostkey_e = 0
|
||||||
self.__hostkey_n = 0
|
self.__hostkey_n = 0
|
||||||
self.__hostkey_n_len = 0 # Length of the host key modulus.
|
self.__hostkey_n_len = 0 # Length of the host key modulus.
|
||||||
|
@ -32,7 +32,7 @@ from ssh_audit.utils import Utils
|
|||||||
|
|
||||||
|
|
||||||
class Output:
|
class Output:
|
||||||
LEVELS = ('info', 'warn', 'fail') # type: Sequence[str]
|
LEVELS: Sequence[str] = ('info', 'warn', 'fail')
|
||||||
COLORS = {'head': 36, 'good': 32, 'warn': 33, 'fail': 31}
|
COLORS = {'head': 36, 'good': 32, 'warn': 33, 'fail': 31}
|
||||||
|
|
||||||
# Use brighter colors on Windows for better readability.
|
# Use brighter colors on Windows for better readability.
|
||||||
|
@ -36,7 +36,7 @@ from ssh_audit.banner import Banner # pylint: disable=unused-import
|
|||||||
class Policy:
|
class Policy:
|
||||||
|
|
||||||
# Each field maps directly to a private member variable of the Policy class.
|
# Each field maps directly to a private member variable of the Policy class.
|
||||||
BUILTIN_POLICIES = {
|
BUILTIN_POLICIES: Dict[str, Dict[str, Union[Optional[str], Optional[List[str]], bool, Dict[str, int]]]] = {
|
||||||
|
|
||||||
# Ubuntu Server policies
|
# Ubuntu Server policies
|
||||||
|
|
||||||
@ -74,25 +74,25 @@ class Policy:
|
|||||||
|
|
||||||
'Hardened Ubuntu Client 20.04 LTS (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512', 'rsa-sha2-512-cert-v01@openssh.com'], 'optional_host_keys': None, 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-c'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
'Hardened Ubuntu Client 20.04 LTS (version 2)': {'version': '2', 'banner': None, 'compressions': None, 'host_keys': ['ssh-ed25519', 'ssh-ed25519-cert-v01@openssh.com', 'sk-ssh-ed25519@openssh.com', 'sk-ssh-ed25519-cert-v01@openssh.com', 'rsa-sha2-256', 'rsa-sha2-256-cert-v01@openssh.com', 'rsa-sha2-512', 'rsa-sha2-512-cert-v01@openssh.com'], 'optional_host_keys': None, 'kex': ['curve25519-sha256', 'curve25519-sha256@libssh.org', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group-exchange-sha256', 'ext-info-c'], 'ciphers': ['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr'], 'macs': ['hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'umac-128-etm@openssh.com'], 'hostkey_sizes': None, 'cakey_sizes': None, 'dh_modulus_sizes': None, 'server_policy': False},
|
||||||
|
|
||||||
} # type: Dict[str, Dict[str, Union[Optional[str], Optional[List[str]], bool, Dict[str, int]]]]
|
}
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, policy_file: Optional[str] = None, policy_data: Optional[str] = None, manual_load: bool = False) -> None:
|
def __init__(self, policy_file: Optional[str] = None, policy_data: Optional[str] = None, manual_load: bool = False) -> None:
|
||||||
self._name = None # type: Optional[str]
|
self._name: Optional[str] = None
|
||||||
self._version = None # type: Optional[str]
|
self._version: Optional[str] = None
|
||||||
self._banner = None # type: Optional[str]
|
self._banner: Optional[str] = None
|
||||||
self._compressions = None # type: Optional[List[str]]
|
self._compressions: Optional[List[str]] = None
|
||||||
self._host_keys = None # type: Optional[List[str]]
|
self._host_keys: Optional[List[str]] = None
|
||||||
self._optional_host_keys = None # type: Optional[List[str]]
|
self._optional_host_keys: Optional[List[str]] = None
|
||||||
self._kex = None # type: Optional[List[str]]
|
self._kex: Optional[List[str]] = None
|
||||||
self._ciphers = None # type: Optional[List[str]]
|
self._ciphers: Optional[List[str]] = None
|
||||||
self._macs = None # type: Optional[List[str]]
|
self._macs: Optional[List[str]] = None
|
||||||
self._hostkey_sizes = None # type: Optional[Dict[str, int]]
|
self._hostkey_sizes: Optional[Dict[str, int]] = None
|
||||||
self._cakey_sizes = None # type: Optional[Dict[str, int]]
|
self._cakey_sizes: Optional[Dict[str, int]] = None
|
||||||
self._dh_modulus_sizes = None # type: Optional[Dict[str, int]]
|
self._dh_modulus_sizes: Optional[Dict[str, int]] = None
|
||||||
self._server_policy = True
|
self._server_policy = True
|
||||||
|
|
||||||
self._name_and_version = '' # type: str
|
self._name_and_version: str = ''
|
||||||
|
|
||||||
# Ensure that only one mode was specified.
|
# Ensure that only one mode was specified.
|
||||||
num_modes = 0
|
num_modes = 0
|
||||||
@ -305,7 +305,7 @@ macs = %s
|
|||||||
'''Evaluates a server configuration against this policy. Returns a tuple of a boolean (True if server adheres to policy) and an array of strings that holds error messages.'''
|
'''Evaluates a server configuration against this policy. Returns a tuple of a boolean (True if server adheres to policy) and an array of strings that holds error messages.'''
|
||||||
|
|
||||||
ret = True
|
ret = True
|
||||||
errors = [] # type: List[Any]
|
errors: List[Any] = []
|
||||||
|
|
||||||
banner_str = str(banner)
|
banner_str = str(banner)
|
||||||
if (self._banner is not None) and (banner_str != self._banner):
|
if (self._banner is not None) and (banner_str != self._banner):
|
||||||
|
@ -43,14 +43,14 @@ class ReadBuf:
|
|||||||
return self._buf.read(size)
|
return self._buf.read(size)
|
||||||
|
|
||||||
def read_byte(self) -> int:
|
def read_byte(self) -> int:
|
||||||
v = struct.unpack('B', self.read(1))[0] # type: int
|
v: int = struct.unpack('B', self.read(1))[0]
|
||||||
return v
|
return v
|
||||||
|
|
||||||
def read_bool(self) -> bool:
|
def read_bool(self) -> bool:
|
||||||
return self.read_byte() != 0
|
return self.read_byte() != 0
|
||||||
|
|
||||||
def read_int(self) -> int:
|
def read_int(self) -> int:
|
||||||
v = struct.unpack('>I', self.read(4))[0] # type: int
|
v: int = struct.unpack('>I', self.read(4))[0]
|
||||||
return v
|
return v
|
||||||
|
|
||||||
def read_list(self) -> List[str]:
|
def read_list(self) -> List[str]:
|
||||||
|
@ -180,7 +180,7 @@ class Software:
|
|||||||
# pylint: disable=too-many-return-statements
|
# pylint: disable=too-many-return-statements
|
||||||
software = str(banner.software)
|
software = str(banner.software)
|
||||||
mx = re.match(r'^dropbear_([\d\.]+\d+)(.*)', software)
|
mx = re.match(r'^dropbear_([\d\.]+\d+)(.*)', software)
|
||||||
v = None # type: Optional[str]
|
v: Optional[str] = None
|
||||||
if mx is not None:
|
if mx is not None:
|
||||||
patch = cls._fix_patch(mx.group(2))
|
patch = cls._fix_patch(mx.group(2))
|
||||||
v, p = 'Matt Johnston', Product.DropbearSSH
|
v, p = 'Matt Johnston', Product.DropbearSSH
|
||||||
|
@ -29,7 +29,7 @@ from ssh_audit.ssh1_crc32 import SSH1_CRC32
|
|||||||
|
|
||||||
|
|
||||||
class SSH1:
|
class SSH1:
|
||||||
_crc32 = None # type: Optional[SSH1_CRC32]
|
_crc32: Optional[SSH1_CRC32] = None
|
||||||
CIPHERS = ['none', 'idea', 'des', '3des', 'tss', 'rc4', 'blowfish']
|
CIPHERS = ['none', 'idea', 'des', '3des', 'tss', 'rc4', 'blowfish']
|
||||||
AUTHS = ['none', 'rhosts', 'rsa', 'password', 'rhosts_rsa', 'tis', 'kerberos']
|
AUTHS = ['none', 'rhosts', 'rsa', 'password', 'rhosts_rsa', 'tis', 'kerberos']
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class SSH1_KexDB: # pylint: disable=too-few-public-methods
|
|||||||
FAIL_NA_UNSAFE = 'not implemented in OpenSSH (server), unsafe algorithm'
|
FAIL_NA_UNSAFE = 'not implemented in OpenSSH (server), unsafe algorithm'
|
||||||
TEXT_CIPHER_IDEA = 'cipher used by commercial SSH'
|
TEXT_CIPHER_IDEA = 'cipher used by commercial SSH'
|
||||||
|
|
||||||
ALGORITHMS = {
|
ALGORITHMS: Dict[str, Dict[str, List[List[Optional[str]]]]] = {
|
||||||
'key': {
|
'key': {
|
||||||
'ssh-rsa1': [['1.2.2']],
|
'ssh-rsa1': [['1.2.2']],
|
||||||
},
|
},
|
||||||
@ -55,4 +55,4 @@ class SSH1_KexDB: # pylint: disable=too-few-public-methods
|
|||||||
'tis': [['1.2.2']],
|
'tis': [['1.2.2']],
|
||||||
'kerberos': [['1.2.2', '3.6'], [FAIL_OPENSSH37_REMOVE]],
|
'kerberos': [['1.2.2', '3.6'], [FAIL_OPENSSH37_REMOVE]],
|
||||||
}
|
}
|
||||||
} # type: Dict[str, Dict[str, List[List[Optional[str]]]]]
|
}
|
||||||
|
@ -41,9 +41,9 @@ class SSH2_Kex:
|
|||||||
self.__follows = follows
|
self.__follows = follows
|
||||||
self.__unused = unused
|
self.__unused = unused
|
||||||
|
|
||||||
self.__rsa_key_sizes = {} # type: Dict[str, Tuple[int, int]]
|
self.__rsa_key_sizes: Dict[str, Tuple[int, int]] = {}
|
||||||
self.__dh_modulus_sizes = {} # type: Dict[str, Tuple[int, int]]
|
self.__dh_modulus_sizes: Dict[str, Tuple[int, int]] = {}
|
||||||
self.__host_keys = {} # type: Dict[str, bytes]
|
self.__host_keys: Dict[str, bytes] = {}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cookie(self) -> bytes:
|
def cookie(self) -> bytes:
|
||||||
|
@ -59,7 +59,7 @@ class SSH2_KexDB: # pylint: disable=too-few-public-methods
|
|||||||
WARN_OBSOLETE = 'using obsolete algorithm'
|
WARN_OBSOLETE = 'using obsolete algorithm'
|
||||||
WARN_UNTRUSTED = 'using untrusted algorithm'
|
WARN_UNTRUSTED = 'using untrusted algorithm'
|
||||||
|
|
||||||
ALGORITHMS = {
|
ALGORITHMS: Dict[str, Dict[str, List[List[Optional[str]]]]] = {
|
||||||
# Format: 'algorithm_name': [['version_first_appeared_in'], [reason_for_failure1, reason_for_failure2, ...], [warning1, warning2, ...]]
|
# Format: 'algorithm_name': [['version_first_appeared_in'], [reason_for_failure1, reason_for_failure2, ...], [warning1, warning2, ...]]
|
||||||
'kex': {
|
'kex': {
|
||||||
'diffie-hellman-group1-sha1': [['2.3.0,d0.28,l10.2', '6.6', '6.9'], [FAIL_1024BIT_MODULUS, FAIL_OPENSSH67_UNSAFE, FAIL_OPENSSH70_LOGJAM], [WARN_HASH_WEAK]],
|
'diffie-hellman-group1-sha1': [['2.3.0,d0.28,l10.2', '6.6', '6.9'], [FAIL_1024BIT_MODULUS, FAIL_OPENSSH67_UNSAFE, FAIL_OPENSSH70_LOGJAM], [WARN_HASH_WEAK]],
|
||||||
@ -268,4 +268,4 @@ class SSH2_KexDB: # pylint: disable=too-few-public-methods
|
|||||||
'chacha20-poly1305@openssh.com': [[]], # Despite the @openssh.com tag, this was never shipped as a MAC in OpenSSH (only as a cipher); it is only implemented as a MAC in Syncplify.
|
'chacha20-poly1305@openssh.com': [[]], # Despite the @openssh.com tag, this was never shipped as a MAC in OpenSSH (only as a cipher); it is only implemented as a MAC in Syncplify.
|
||||||
'crypticore-mac@ssh.com': [[], [FAIL_UNPROVEN]],
|
'crypticore-mac@ssh.com': [[], [FAIL_UNPROVEN]],
|
||||||
}
|
}
|
||||||
} # type: Dict[str, Dict[str, List[List[Optional[str]]]]]
|
}
|
||||||
|
@ -210,13 +210,13 @@ def output_security_sub(sub: str, software: Optional[Software], client_audit: bo
|
|||||||
if software is None or software.product not in secdb:
|
if software is None or software.product not in secdb:
|
||||||
return
|
return
|
||||||
for line in secdb[software.product]:
|
for line in secdb[software.product]:
|
||||||
vfrom = '' # type: str
|
vfrom: str = ''
|
||||||
vtill = '' # type: str
|
vtill: str = ''
|
||||||
vfrom, vtill = line[0:2]
|
vfrom, vtill = line[0:2]
|
||||||
if not software.between_versions(vfrom, vtill):
|
if not software.between_versions(vfrom, vtill):
|
||||||
continue
|
continue
|
||||||
target = 0 # type: int
|
target: int = 0
|
||||||
name = '' # type: str
|
name: str = ''
|
||||||
target, name = line[2:4]
|
target, name = line[2:4]
|
||||||
is_server = target & 1 == 1
|
is_server = target & 1 == 1
|
||||||
is_client = target & 2 == 2
|
is_client = target & 2 == 2
|
||||||
@ -227,8 +227,8 @@ def output_security_sub(sub: str, software: Optional[Software], client_audit: bo
|
|||||||
continue
|
continue
|
||||||
p = '' if out.batch else ' ' * (padlen - len(name))
|
p = '' if out.batch else ' ' * (padlen - len(name))
|
||||||
if sub == 'cve':
|
if sub == 'cve':
|
||||||
cvss = 0.0 # type: float
|
cvss: float = 0.0
|
||||||
descr = '' # type: str
|
descr: str = ''
|
||||||
cvss, descr = line[4:6]
|
cvss, descr = line[4:6]
|
||||||
|
|
||||||
# Critical CVSS scores (>= 8.0) are printed as a fail, otherwise they are printed as a warning.
|
# Critical CVSS scores (>= 8.0) are printed as a fail, otherwise they are printed as a warning.
|
||||||
@ -431,7 +431,7 @@ def output(aconf: AuditConf, banner: Optional[Banner], header: List[str], client
|
|||||||
maxlen = algs.maxlen + 1
|
maxlen = algs.maxlen + 1
|
||||||
output_security(banner, client_audit, maxlen, aconf.json)
|
output_security(banner, client_audit, maxlen, aconf.json)
|
||||||
# Filled in by output_algorithms() with unidentified algs.
|
# Filled in by output_algorithms() with unidentified algs.
|
||||||
unknown_algorithms = [] # type: List[str]
|
unknown_algorithms: List[str] = []
|
||||||
if pkm is not None:
|
if pkm is not None:
|
||||||
adb = SSH1_KexDB.ALGORITHMS
|
adb = SSH1_KexDB.ALGORITHMS
|
||||||
ciphers = pkm.supported_ciphers
|
ciphers = pkm.supported_ciphers
|
||||||
@ -529,7 +529,7 @@ def list_policies() -> None:
|
|||||||
def make_policy(aconf: AuditConf, banner: Optional['Banner'], kex: Optional['SSH2_Kex'], client_host: Optional[str]) -> None:
|
def make_policy(aconf: AuditConf, banner: Optional['Banner'], kex: Optional['SSH2_Kex'], client_host: Optional[str]) -> None:
|
||||||
|
|
||||||
# Set the source of this policy to the server host if this is a server audit, otherwise set it to the client address.
|
# Set the source of this policy to the server host if this is a server audit, otherwise set it to the client address.
|
||||||
source = aconf.host # type: Optional[str]
|
source: Optional[str] = aconf.host
|
||||||
if aconf.client_audit:
|
if aconf.client_audit:
|
||||||
source = client_host
|
source = client_host
|
||||||
|
|
||||||
@ -562,9 +562,9 @@ def process_commandline(args: List[str], usage_cb: Callable[..., None]) -> 'Audi
|
|||||||
except getopt.GetoptError as err:
|
except getopt.GetoptError as err:
|
||||||
usage_cb(str(err))
|
usage_cb(str(err))
|
||||||
aconf.ssh1, aconf.ssh2 = False, False
|
aconf.ssh1, aconf.ssh2 = False, False
|
||||||
host = '' # type: str
|
host: str = ''
|
||||||
oport = None # type: Optional[str]
|
oport: Optional[str] = None
|
||||||
port = 0 # type: int
|
port: int = 0
|
||||||
for o, a in opts:
|
for o, a in opts:
|
||||||
if o in ('-h', '--help'):
|
if o in ('-h', '--help'):
|
||||||
usage_cb()
|
usage_cb()
|
||||||
@ -687,14 +687,14 @@ def build_struct(banner: Optional['Banner'], kex: Optional['SSH2_Kex'] = None, p
|
|||||||
banner_software = banner.software
|
banner_software = banner.software
|
||||||
banner_comments = banner.comments
|
banner_comments = banner.comments
|
||||||
|
|
||||||
res = {
|
res: Any = {
|
||||||
"banner": {
|
"banner": {
|
||||||
"raw": banner_str,
|
"raw": banner_str,
|
||||||
"protocol": banner_protocol,
|
"protocol": banner_protocol,
|
||||||
"software": banner_software,
|
"software": banner_software,
|
||||||
"comments": banner_comments,
|
"comments": banner_comments,
|
||||||
},
|
},
|
||||||
} # type: Any
|
}
|
||||||
if client_host is not None:
|
if client_host is not None:
|
||||||
res['client_ip'] = client_host
|
res['client_ip'] = client_host
|
||||||
if kex is not None:
|
if kex is not None:
|
||||||
@ -703,9 +703,9 @@ def build_struct(banner: Optional['Banner'], kex: Optional['SSH2_Kex'] = None, p
|
|||||||
res['kex'] = []
|
res['kex'] = []
|
||||||
alg_sizes = kex.dh_modulus_sizes()
|
alg_sizes = kex.dh_modulus_sizes()
|
||||||
for algorithm in kex.kex_algorithms:
|
for algorithm in kex.kex_algorithms:
|
||||||
entry = {
|
entry: Any = {
|
||||||
'algorithm': algorithm,
|
'algorithm': algorithm,
|
||||||
} # type: Any
|
}
|
||||||
if algorithm in alg_sizes:
|
if algorithm in alg_sizes:
|
||||||
hostkey_size, ca_size = alg_sizes[algorithm]
|
hostkey_size, ca_size = alg_sizes[algorithm]
|
||||||
entry['keysize'] = hostkey_size
|
entry['keysize'] = hostkey_size
|
||||||
@ -879,7 +879,7 @@ def algorithm_lookup(alg_names: str) -> int:
|
|||||||
for (outer_k, outer_v) in adb.items()
|
for (outer_k, outer_v) in adb.items()
|
||||||
}
|
}
|
||||||
|
|
||||||
unknown_algorithms = [] # type: List[str]
|
unknown_algorithms: List[str] = []
|
||||||
padding = len(max(algorithm_names, key=len))
|
padding = len(max(algorithm_names, key=len))
|
||||||
|
|
||||||
for alg_type in alg_types:
|
for alg_type in alg_types:
|
||||||
|
@ -54,12 +54,12 @@ class SSH_Socket(ReadBuf, WriteBuf):
|
|||||||
|
|
||||||
def __init__(self, host: Optional[str], port: int, ipvo: Optional[Sequence[int]] = None, timeout: Union[int, float] = 5, timeout_set: bool = False) -> None:
|
def __init__(self, host: Optional[str], port: int, ipvo: Optional[Sequence[int]] = None, timeout: Union[int, float] = 5, timeout_set: bool = False) -> None:
|
||||||
super(SSH_Socket, self).__init__()
|
super(SSH_Socket, self).__init__()
|
||||||
self.__sock = None # type: Optional[socket.socket]
|
self.__sock: Optional[socket.socket] = None
|
||||||
self.__sock_map = {} # type: Dict[int, socket.socket]
|
self.__sock_map: Dict[int, socket.socket] = {}
|
||||||
self.__block_size = 8
|
self.__block_size = 8
|
||||||
self.__state = 0
|
self.__state = 0
|
||||||
self.__header = [] # type: List[str]
|
self.__header: List[str] = []
|
||||||
self.__banner = None # type: Optional[Banner]
|
self.__banner: Optional[Banner] = None
|
||||||
if host is None:
|
if host is None:
|
||||||
raise ValueError('undefined host')
|
raise ValueError('undefined host')
|
||||||
nport = Utils.parse_int(port)
|
nport = Utils.parse_int(port)
|
||||||
@ -73,7 +73,7 @@ class SSH_Socket(ReadBuf, WriteBuf):
|
|||||||
self.__ipvo = ()
|
self.__ipvo = ()
|
||||||
self.__timeout = timeout
|
self.__timeout = timeout
|
||||||
self.__timeout_set = timeout_set
|
self.__timeout_set = timeout_set
|
||||||
self.client_host = None # type: Optional[str]
|
self.client_host: Optional[str] = None
|
||||||
self.client_port = None
|
self.client_port = None
|
||||||
|
|
||||||
def _resolve(self, ipvo: Sequence[int]) -> Iterable[Tuple[int, Tuple[Any, ...]]]:
|
def _resolve(self, ipvo: Sequence[int]) -> Iterable[Tuple[int, Tuple[Any, ...]]]:
|
||||||
|
@ -30,12 +30,12 @@ from ssh_audit.algorithm import Algorithm
|
|||||||
|
|
||||||
class Timeframe:
|
class Timeframe:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.__storage = {} # type: Dict[str, List[Optional[str]]]
|
self.__storage: Dict[str, List[Optional[str]]] = {}
|
||||||
|
|
||||||
def __contains__(self, product: str) -> bool:
|
def __contains__(self, product: str) -> bool:
|
||||||
return product in self.__storage
|
return product in self.__storage
|
||||||
|
|
||||||
def __getitem__(self, product): # type: (str) -> Sequence[Optional[str]]
|
def __getitem__(self, product: str) -> Sequence[Optional[str]]:
|
||||||
return tuple(self.__storage.get(product, [None] * 4))
|
return tuple(self.__storage.get(product, [None] * 4))
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
@ -51,7 +51,7 @@ class Timeframe:
|
|||||||
return self[product][1 if bool(for_server) else 3]
|
return self[product][1 if bool(for_server) else 3]
|
||||||
|
|
||||||
def _update(self, versions: Optional[str], pos: int) -> None:
|
def _update(self, versions: Optional[str], pos: int) -> None:
|
||||||
ssh_versions = {} # type: Dict[str, str]
|
ssh_versions: Dict[str, str] = {}
|
||||||
for_srv, for_cli = pos < 2, pos > 1
|
for_srv, for_cli = pos < 2, pos > 1
|
||||||
for v in (versions or '').split(','):
|
for v in (versions or '').split(','):
|
||||||
ssh_prod, ssh_ver, is_cli = Algorithm.get_ssh_version(v)
|
ssh_prod, ssh_ver, is_cli = Algorithm.get_ssh_version(v)
|
||||||
|
@ -96,7 +96,7 @@ class Utils:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def unique_seq(cls, seq: Sequence[Any]) -> Sequence[Any]:
|
def unique_seq(cls, seq: Sequence[Any]) -> Sequence[Any]:
|
||||||
seen = set() # type: Set[Any]
|
seen: Set[Any] = set()
|
||||||
|
|
||||||
def _seen_add(x: Any) -> bool:
|
def _seen_add(x: Any) -> bool:
|
||||||
seen.add(x)
|
seen.add(x)
|
||||||
|
@ -33,7 +33,7 @@ class VersionVulnerabilityDB: # pylint: disable=too-few-public-methods
|
|||||||
# Example: if it affects servers, both remote & local, then affected
|
# Example: if it affects servers, both remote & local, then affected
|
||||||
# = 1. If it affects servers, but is a local issue only,
|
# = 1. If it affects servers, but is a local issue only,
|
||||||
# then affected = 1 + 4 = 5.
|
# then affected = 1 + 4 = 5.
|
||||||
CVE = {
|
CVE: Dict[str, List[List[Any]]] = {
|
||||||
'Dropbear SSH': [
|
'Dropbear SSH': [
|
||||||
['0.0', '2018.76', 1, 'CVE-2018-15599', 5.0, 'remote users may enumerate users on the system'],
|
['0.0', '2018.76', 1, 'CVE-2018-15599', 5.0, 'remote users may enumerate users on the system'],
|
||||||
['0.0', '2017.74', 5, 'CVE-2017-9079', 4.7, 'local users can read certain files as root'],
|
['0.0', '2017.74', 5, 'CVE-2017-9079', 4.7, 'local users can read certain files as root'],
|
||||||
@ -140,12 +140,12 @@ class VersionVulnerabilityDB: # pylint: disable=too-few-public-methods
|
|||||||
['0.0', '0.66', 2, 'CVE-2016-2563', 7.5, 'buffer overflow in SCP command-line utility'],
|
['0.0', '0.66', 2, 'CVE-2016-2563', 7.5, 'buffer overflow in SCP command-line utility'],
|
||||||
['0.0', '0.65', 2, 'CVE-2015-5309', 4.3, 'integer overflow in terminal-handling code'],
|
['0.0', '0.65', 2, 'CVE-2015-5309', 4.3, 'integer overflow in terminal-handling code'],
|
||||||
]
|
]
|
||||||
} # type: Dict[str, List[List[Any]]]
|
}
|
||||||
TXT = {
|
TXT: Dict[str, List[List[Any]]] = {
|
||||||
'Dropbear SSH': [
|
'Dropbear SSH': [
|
||||||
['0.28', '0.34', 1, 'remote root exploit', 'remote format string buffer overflow exploit (exploit-db#387)']],
|
['0.28', '0.34', 1, 'remote root exploit', 'remote format string buffer overflow exploit (exploit-db#387)']],
|
||||||
'libssh': [
|
'libssh': [
|
||||||
['0.3.3', '0.3.3', 1, 'null pointer check', 'missing null pointer check in "crypt_set_algorithms_server"'],
|
['0.3.3', '0.3.3', 1, 'null pointer check', 'missing null pointer check in "crypt_set_algorithms_server"'],
|
||||||
['0.3.3', '0.3.3', 1, 'integer overflow', 'integer overflow in "buffer_get_data"'],
|
['0.3.3', '0.3.3', 1, 'integer overflow', 'integer overflow in "buffer_get_data"'],
|
||||||
['0.3.3', '0.3.3', 3, 'heap overflow', 'heap overflow in "packet_decrypt"']]
|
['0.3.3', '0.3.3', 3, 'heap overflow', 'heap overflow in "packet_decrypt"']]
|
||||||
} # type: Dict[str, List[List[Any]]]
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user