mirror of
https://github.com/jtesta/ssh-audit.git
synced 2024-11-25 20:11:40 +01:00
Condition must be a boolean fixes.
This commit is contained in:
parent
0d555d43b3
commit
21a93cbd66
81
ssh-audit.py
81
ssh-audit.py
@ -55,7 +55,7 @@ def usage(err=None):
|
|||||||
uout = Output()
|
uout = Output()
|
||||||
p = os.path.basename(sys.argv[0])
|
p = os.path.basename(sys.argv[0])
|
||||||
uout.head('# {0} {1}, moo@arthepsy.eu\n'.format(p, VERSION))
|
uout.head('# {0} {1}, moo@arthepsy.eu\n'.format(p, VERSION))
|
||||||
if err is not None:
|
if err is not None and len(err) > 0:
|
||||||
uout.fail('\n' + err)
|
uout.fail('\n' + err)
|
||||||
uout.info('usage: {0} [-1246pbnvl] <host>\n'.format(p))
|
uout.info('usage: {0} [-1246pbnvl] <host>\n'.format(p))
|
||||||
uout.info(' -h, --help print this help')
|
uout.info(' -h, --help print this help')
|
||||||
@ -92,10 +92,10 @@ class AuditConf(object):
|
|||||||
# type: (str, Union[str, int, bool, Sequence[int]]) -> None
|
# type: (str, Union[str, int, bool, Sequence[int]]) -> None
|
||||||
valid = False
|
valid = False
|
||||||
if name in ['ssh1', 'ssh2', 'batch', 'colors', 'verbose']:
|
if name in ['ssh1', 'ssh2', 'batch', 'colors', 'verbose']:
|
||||||
valid, value = True, True if value else False
|
valid, value = True, True if bool(value) else False
|
||||||
elif name in ['ipv4', 'ipv6']:
|
elif name in ['ipv4', 'ipv6']:
|
||||||
valid = False
|
valid = False
|
||||||
value = True if value else False
|
value = True if bool(value) else False
|
||||||
ipv = 4 if name == 'ipv4' else 6
|
ipv = 4 if name == 'ipv4' else 6
|
||||||
if value:
|
if value:
|
||||||
value = tuple(list(self.ipvo) + [ipv])
|
value = tuple(list(self.ipvo) + [ipv])
|
||||||
@ -916,7 +916,7 @@ class SSH(object): # pylint: disable=too-few-public-methods
|
|||||||
else:
|
else:
|
||||||
other = str(other)
|
other = str(other)
|
||||||
mx = re.match(r'^([\d\.]+\d+)(.*)$', other)
|
mx = re.match(r'^([\d\.]+\d+)(.*)$', other)
|
||||||
if mx is not None:
|
if bool(mx):
|
||||||
oversion, opatch = mx.group(1), mx.group(2).strip()
|
oversion, opatch = mx.group(1), mx.group(2).strip()
|
||||||
else:
|
else:
|
||||||
oversion, opatch = other, ''
|
oversion, opatch = other, ''
|
||||||
@ -933,10 +933,10 @@ class SSH(object): # pylint: disable=too-few-public-methods
|
|||||||
elif self.product == SSH.Product.OpenSSH:
|
elif self.product == SSH.Product.OpenSSH:
|
||||||
mx1 = re.match(r'^p\d(.*)', opatch)
|
mx1 = re.match(r'^p\d(.*)', opatch)
|
||||||
mx2 = re.match(r'^p\d(.*)', spatch)
|
mx2 = re.match(r'^p\d(.*)', spatch)
|
||||||
if not (mx1 and mx2):
|
if not (bool(mx1) and bool(mx2)):
|
||||||
if mx1 is not None:
|
if bool(mx1):
|
||||||
opatch = mx1.group(1)
|
opatch = mx1.group(1)
|
||||||
if mx2 is not None:
|
if bool(mx2):
|
||||||
spatch = mx2.group(1)
|
spatch = mx2.group(1)
|
||||||
if spatch < opatch:
|
if spatch < opatch:
|
||||||
return -1
|
return -1
|
||||||
@ -946,28 +946,28 @@ class SSH(object): # pylint: disable=too-few-public-methods
|
|||||||
|
|
||||||
def between_versions(self, vfrom, vtill):
|
def between_versions(self, vfrom, vtill):
|
||||||
# type: (str, str) -> bool
|
# type: (str, str) -> bool
|
||||||
if vfrom and self.compare_version(vfrom) < 0:
|
if bool(vfrom) and self.compare_version(vfrom) < 0:
|
||||||
return False
|
return False
|
||||||
if vtill and self.compare_version(vtill) > 0:
|
if bool(vtill) and self.compare_version(vtill) > 0:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def display(self, full=True):
|
def display(self, full=True):
|
||||||
# type: (bool) -> str
|
# type: (bool) -> str
|
||||||
r = '{0} '.format(self.vendor) if self.vendor else ''
|
r = '{0} '.format(self.vendor) if bool(self.vendor) else ''
|
||||||
r += self.product
|
r += self.product
|
||||||
if self.version:
|
if bool(self.version):
|
||||||
r += ' {0}'.format(self.version)
|
r += ' {0}'.format(self.version)
|
||||||
if full:
|
if full:
|
||||||
patch = self.patch or ''
|
patch = self.patch or ''
|
||||||
if self.product == SSH.Product.OpenSSH:
|
if self.product == SSH.Product.OpenSSH:
|
||||||
mx = re.match(r'^(p\d)(.*)$', patch)
|
mx = re.match(r'^(p\d)(.*)$', patch)
|
||||||
if mx is not None:
|
if bool(mx):
|
||||||
r += mx.group(1)
|
r += mx.group(1)
|
||||||
patch = mx.group(2).strip()
|
patch = mx.group(2).strip()
|
||||||
if patch:
|
if bool(patch):
|
||||||
r += ' ({0})'.format(patch)
|
r += ' ({0})'.format(patch)
|
||||||
if self.os:
|
if bool(self.os):
|
||||||
r += ' running on {0}'.format(self.os)
|
r += ' running on {0}'.format(self.os)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
@ -977,16 +977,13 @@ class SSH(object): # pylint: disable=too-few-public-methods
|
|||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
# type: () -> str
|
# type: () -> str
|
||||||
r = 'vendor={0}'.format(self.vendor) if self.vendor else ''
|
r = 'vendor={0}, '.format(self.vendor) if bool(self.vendor) else ''
|
||||||
if self.product:
|
|
||||||
if self.vendor:
|
|
||||||
r += ', '
|
|
||||||
r += 'product={0}'.format(self.product)
|
r += 'product={0}'.format(self.product)
|
||||||
if self.version:
|
if bool(self.version):
|
||||||
r += ', version={0}'.format(self.version)
|
r += ', version={0}'.format(self.version)
|
||||||
if self.patch:
|
if bool(self.patch):
|
||||||
r += ', patch={0}'.format(self.patch)
|
r += ', patch={0}'.format(self.patch)
|
||||||
if self.os:
|
if bool(self.os):
|
||||||
r += ', os={0}'.format(self.os)
|
r += ', os={0}'.format(self.os)
|
||||||
return '<{0}({1})>'.format(self.__class__.__name__, r)
|
return '<{0}({1})>'.format(self.__class__.__name__, r)
|
||||||
|
|
||||||
@ -1009,19 +1006,19 @@ class SSH(object): # pylint: disable=too-few-public-methods
|
|||||||
if c is None:
|
if c is None:
|
||||||
return None
|
return None
|
||||||
mx = re.match(r'^NetBSD(?:_Secure_Shell)?(?:[\s-]+(\d{8})(.*))?$', c)
|
mx = re.match(r'^NetBSD(?:_Secure_Shell)?(?:[\s-]+(\d{8})(.*))?$', c)
|
||||||
if mx is not None:
|
if bool(mx):
|
||||||
d = cls._fix_date(mx.group(1))
|
d = cls._fix_date(mx.group(1))
|
||||||
return 'NetBSD' if d is None else 'NetBSD ({0})'.format(d)
|
return 'NetBSD' if d is None else 'NetBSD ({0})'.format(d)
|
||||||
mx = re.match(r'^FreeBSD(?:\slocalisations)?[\s-]+(\d{8})(.*)$', c)
|
mx = re.match(r'^FreeBSD(?:\slocalisations)?[\s-]+(\d{8})(.*)$', c)
|
||||||
if mx is None:
|
if not bool(mx):
|
||||||
mx = re.match(r'^[^@]+@FreeBSD\.org[\s-]+(\d{8})(.*)$', c)
|
mx = re.match(r'^[^@]+@FreeBSD\.org[\s-]+(\d{8})(.*)$', c)
|
||||||
if mx is not None:
|
if bool(mx):
|
||||||
d = cls._fix_date(mx.group(1))
|
d = cls._fix_date(mx.group(1))
|
||||||
return 'FreeBSD' if d is None else 'FreeBSD ({0})'.format(d)
|
return 'FreeBSD' if d is None else 'FreeBSD ({0})'.format(d)
|
||||||
w = ['RemotelyAnywhere', 'DesktopAuthority', 'RemoteSupportManager']
|
w = ['RemotelyAnywhere', 'DesktopAuthority', 'RemoteSupportManager']
|
||||||
for win_soft in w:
|
for win_soft in w:
|
||||||
mx = re.match(r'^in ' + win_soft + r' ([\d\.]+\d)$', c)
|
mx = re.match(r'^in ' + win_soft + r' ([\d\.]+\d)$', c)
|
||||||
if mx is not None:
|
if bool(mx):
|
||||||
ver = mx.group(1)
|
ver = mx.group(1)
|
||||||
return 'Microsoft Windows ({0} {1})'.format(win_soft, ver)
|
return 'Microsoft Windows ({0} {1})'.format(win_soft, ver)
|
||||||
generic = ['NetBSD', 'FreeBSD']
|
generic = ['NetBSD', 'FreeBSD']
|
||||||
@ -1037,35 +1034,35 @@ class SSH(object): # pylint: disable=too-few-public-methods
|
|||||||
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 = None # type: Optional[str]
|
||||||
if mx is not None:
|
if bool(mx):
|
||||||
patch = cls._fix_patch(mx.group(2))
|
patch = cls._fix_patch(mx.group(2))
|
||||||
v, p = 'Matt Johnston', SSH.Product.DropbearSSH
|
v, p = 'Matt Johnston', SSH.Product.DropbearSSH
|
||||||
v = None
|
v = None
|
||||||
return cls(v, p, mx.group(1), patch, None)
|
return cls(v, p, mx.group(1), patch, None)
|
||||||
mx = re.match(r'^OpenSSH[_\.-]+([\d\.]+\d+)(.*)', software)
|
mx = re.match(r'^OpenSSH[_\.-]+([\d\.]+\d+)(.*)', software)
|
||||||
if mx is not None:
|
if bool(mx):
|
||||||
patch = cls._fix_patch(mx.group(2))
|
patch = cls._fix_patch(mx.group(2))
|
||||||
v, p = 'OpenBSD', SSH.Product.OpenSSH
|
v, p = 'OpenBSD', SSH.Product.OpenSSH
|
||||||
v = None
|
v = None
|
||||||
os_version = cls._extract_os_version(banner.comments)
|
os_version = cls._extract_os_version(banner.comments)
|
||||||
return cls(v, p, mx.group(1), patch, os_version)
|
return cls(v, p, mx.group(1), patch, os_version)
|
||||||
mx = re.match(r'^libssh-([\d\.]+\d+)(.*)', software)
|
mx = re.match(r'^libssh-([\d\.]+\d+)(.*)', software)
|
||||||
if mx is not None:
|
if bool(mx):
|
||||||
patch = cls._fix_patch(mx.group(2))
|
patch = cls._fix_patch(mx.group(2))
|
||||||
v, p = None, SSH.Product.LibSSH
|
v, p = None, SSH.Product.LibSSH
|
||||||
os_version = cls._extract_os_version(banner.comments)
|
os_version = cls._extract_os_version(banner.comments)
|
||||||
return cls(v, p, mx.group(1), patch, os_version)
|
return cls(v, p, mx.group(1), patch, os_version)
|
||||||
mx = re.match(r'^RomSShell_([\d\.]+\d+)(.*)', software)
|
mx = re.match(r'^RomSShell_([\d\.]+\d+)(.*)', software)
|
||||||
if mx is not None:
|
if bool(mx):
|
||||||
patch = cls._fix_patch(mx.group(2))
|
patch = cls._fix_patch(mx.group(2))
|
||||||
v, p = 'Allegro Software', 'RomSShell'
|
v, p = 'Allegro Software', 'RomSShell'
|
||||||
return cls(v, p, mx.group(1), patch, None)
|
return cls(v, p, mx.group(1), patch, None)
|
||||||
mx = re.match(r'^mpSSH_([\d\.]+\d+)', software)
|
mx = re.match(r'^mpSSH_([\d\.]+\d+)', software)
|
||||||
if mx is not None:
|
if bool(mx):
|
||||||
v, p = 'HP', 'iLO (Integrated Lights-Out) sshd'
|
v, p = 'HP', 'iLO (Integrated Lights-Out) sshd'
|
||||||
return cls(v, p, mx.group(1), None, None)
|
return cls(v, p, mx.group(1), None, None)
|
||||||
mx = re.match(r'^Cisco-([\d\.]+\d+)', software)
|
mx = re.match(r'^Cisco-([\d\.]+\d+)', software)
|
||||||
if mx is not None:
|
if bool(mx):
|
||||||
v, p = 'Cisco', 'IOS/PIX sshd'
|
v, p = 'Cisco', 'IOS/PIX sshd'
|
||||||
return cls(v, p, mx.group(1), None, None)
|
return cls(v, p, mx.group(1), None, None)
|
||||||
return None
|
return None
|
||||||
@ -1107,7 +1104,7 @@ class SSH(object): # pylint: disable=too-few-public-methods
|
|||||||
r = 'SSH-{0}.{1}'.format(self.protocol[0], self.protocol[1])
|
r = 'SSH-{0}.{1}'.format(self.protocol[0], self.protocol[1])
|
||||||
if self.software is not None:
|
if self.software is not None:
|
||||||
r += '-{0}'.format(self.software)
|
r += '-{0}'.format(self.software)
|
||||||
if self.comments:
|
if bool(self.comments):
|
||||||
r += ' {0}'.format(self.comments)
|
r += ' {0}'.format(self.comments)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
@ -1115,19 +1112,19 @@ class SSH(object): # pylint: disable=too-few-public-methods
|
|||||||
# type: () -> str
|
# type: () -> str
|
||||||
p = '{0}.{1}'.format(self.protocol[0], self.protocol[1])
|
p = '{0}.{1}'.format(self.protocol[0], self.protocol[1])
|
||||||
r = 'protocol={0}'.format(p)
|
r = 'protocol={0}'.format(p)
|
||||||
if self.software:
|
if self.software is not None:
|
||||||
r += ', software={0}'.format(self.software)
|
r += ', software={0}'.format(self.software)
|
||||||
if self.comments:
|
if bool(self.comments):
|
||||||
r += ', comments={0}'.format(self.comments)
|
r += ', comments={0}'.format(self.comments)
|
||||||
return '<{0}({1})>'.format(self.__class__.__name__, r)
|
return '<{0}({1})>'.format(self.__class__.__name__, r)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parse(cls, banner):
|
def parse(cls, banner):
|
||||||
# type: (text_type) -> SSH.Banner
|
# type: (text_type) -> Optional[SSH.Banner]
|
||||||
valid_ascii = utils.is_print_ascii(banner)
|
valid_ascii = utils.is_print_ascii(banner)
|
||||||
ascii_banner = utils.to_print_ascii(banner)
|
ascii_banner = utils.to_print_ascii(banner)
|
||||||
mx = cls.RX_BANNER.match(ascii_banner)
|
mx = cls.RX_BANNER.match(ascii_banner)
|
||||||
if mx is None:
|
if not bool(mx):
|
||||||
return None
|
return None
|
||||||
protocol = min(re.findall(cls.RX_PROTOCOL, mx.group(1)))
|
protocol = min(re.findall(cls.RX_PROTOCOL, mx.group(1)))
|
||||||
protocol = (int(protocol[0]), int(protocol[1]))
|
protocol = (int(protocol[0]), int(protocol[1]))
|
||||||
@ -1814,7 +1811,7 @@ def output_algorithm(alg_db, alg_type, alg_name, alg_max_len=0):
|
|||||||
if level == 'info':
|
if level == 'info':
|
||||||
versions = alg_desc[0]
|
versions = alg_desc[0]
|
||||||
since_text = SSH.Algorithm.get_since_text(versions)
|
since_text = SSH.Algorithm.get_since_text(versions)
|
||||||
if since_text:
|
if since_text is not None and len(since_text) > 0:
|
||||||
texts.append((level, since_text))
|
texts.append((level, since_text))
|
||||||
idx = idx + 1
|
idx = idx + 1
|
||||||
if ldesc > idx:
|
if ldesc > idx:
|
||||||
@ -1951,7 +1948,10 @@ def output_recommendations(algs, software, padlen=0):
|
|||||||
fm = '(rec) {0}{1}{2}-- {3} algorithm to {4} {5}'
|
fm = '(rec) {0}{1}{2}-- {3} algorithm to {4} {5}'
|
||||||
fn(fm.format(sg, name, p, alg_type, an, b))
|
fn(fm.format(sg, name, p, alg_type, an, b))
|
||||||
if len(obuf) > 0:
|
if len(obuf) > 0:
|
||||||
title = '(for {0})'.format(software.display(False)) if software else ''
|
if software is not None:
|
||||||
|
title = '(for {0})'.format(software.display(False))
|
||||||
|
else:
|
||||||
|
title = ''
|
||||||
out.head('# algorithm recommendations {0}'.format(title))
|
out.head('# algorithm recommendations {0}'.format(title))
|
||||||
obuf.flush()
|
obuf.flush()
|
||||||
out.sep()
|
out.sep()
|
||||||
@ -2150,7 +2150,10 @@ def audit(aconf, sshv=None):
|
|||||||
packet_type, payload = s.read_packet(sshv)
|
packet_type, payload = s.read_packet(sshv)
|
||||||
if packet_type < 0:
|
if packet_type < 0:
|
||||||
try:
|
try:
|
||||||
payload_txt = payload.decode('utf-8') if payload else u'empty'
|
if payload is not None and len(payload) > 0:
|
||||||
|
payload_txt = payload.decode('utf-8')
|
||||||
|
else:
|
||||||
|
payload_txt = u'empty'
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
payload_txt = u'"{0}"'.format(repr(payload).lstrip('b')[1:-1])
|
payload_txt = u'"{0}"'.format(repr(payload).lstrip('b')[1:-1])
|
||||||
if payload_txt == u'Protocol major versions differ.':
|
if payload_txt == u'Protocol major versions differ.':
|
||||||
|
2
tox.ini
2
tox.ini
@ -107,7 +107,7 @@ warn_redundant_casts = True
|
|||||||
warn_return_any = True
|
warn_return_any = True
|
||||||
warn_unused_ignores = True
|
warn_unused_ignores = True
|
||||||
strict_optional = True
|
strict_optional = True
|
||||||
#strict_boolean = True
|
strict_boolean = True
|
||||||
|
|
||||||
[pylint]
|
[pylint]
|
||||||
reports = no
|
reports = no
|
||||||
|
Loading…
Reference in New Issue
Block a user