From 16000b983e4cb30f05182c7bb6e6ebd674886ae1 Mon Sep 17 00:00:00 2001 From: exploide Date: Sun, 6 Aug 2023 15:46:55 +0200 Subject: [PATCH 1/4] fstab: improved password detection and fixed parsing error E.g. mount.cifs can use pass= instead of password= and cred= can alternatively be used to specify a credential file. Continue on empty lines because the line.split() call resulted in ValueError: not enough values to unpack (expected 6, got 0) --- Linux/lazagne/softwares/sysadmin/fstab.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Linux/lazagne/softwares/sysadmin/fstab.py b/Linux/lazagne/softwares/sysadmin/fstab.py index 9a4cc139..cb90cd06 100644 --- a/Linux/lazagne/softwares/sysadmin/fstab.py +++ b/Linux/lazagne/softwares/sysadmin/fstab.py @@ -17,11 +17,12 @@ def run(self): try: with open(path) as fstab: for line in fstab: - if line.startswith('#'): + line = line.strip() + if not line or line.startswith('#'): continue - filesystem, mount_point, _type, options, dump, _pass = line.strip().split() - if 'password' in options: + filesystem, mount_point, _type, options, dump, _pass = line.split() + if 'pass' in options or 'cred' in options: pwd_found.append({ 'Filesystem': filesystem, 'Mount Point': mount_point, From 91d890a4d1cce9f499a18cd02a9d1913f22aa217 Mon Sep 17 00:00:00 2001 From: exploide Date: Sun, 6 Aug 2023 16:24:55 +0200 Subject: [PATCH 2/4] libsecret: include the keyring owner in output It could be confusing when searching multiple user's keyrings as root. Additionally, ordered the output keys more intuitively. --- Linux/lazagne/softwares/wallet/libsecret.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Linux/lazagne/softwares/wallet/libsecret.py b/Linux/lazagne/softwares/wallet/libsecret.py index 350d43bb..c5f34489 100644 --- a/Linux/lazagne/softwares/wallet/libsecret.py +++ b/Linux/lazagne/softwares/wallet/libsecret.py @@ -4,6 +4,7 @@ from lazagne.config.module_info import ModuleInfo from lazagne.config import homes from binascii import hexlify +import pwd import traceback try: @@ -80,12 +81,13 @@ def run(self): for item in storage: values = { - 'created': str(datetime.datetime.fromtimestamp(item.get_created())), - 'modified': str(datetime.datetime.fromtimestamp(item.get_modified())), - 'content-type': item.get_secret_content_type(), - 'label': item.get_label(), + 'Owner': pwd.getpwuid(uid).pw_name, + 'Collection': label, + 'Label': item.get_label(), + 'Content-Type': item.get_secret_content_type(), 'Password': item.get_secret().decode('utf8'), - 'collection': label, + 'Created': str(datetime.datetime.fromtimestamp(item.get_created())), + 'Modified': str(datetime.datetime.fromtimestamp(item.get_modified())), } # for k, v in item.get_attributes().iteritems(): From 457f9d2ade23754b05c1014d652c2d22604ddda8 Mon Sep 17 00:00:00 2001 From: exploide Date: Sun, 6 Aug 2023 16:28:19 +0200 Subject: [PATCH 3/4] env_variable: exclude common false-positive 'SYSTEMD_NSS_DYNAMIC_BYPASS' --- Linux/lazagne/softwares/sysadmin/env_variable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Linux/lazagne/softwares/sysadmin/env_variable.py b/Linux/lazagne/softwares/sysadmin/env_variable.py index 3936cc49..edb26520 100755 --- a/Linux/lazagne/softwares/sysadmin/env_variable.py +++ b/Linux/lazagne/softwares/sysadmin/env_variable.py @@ -20,7 +20,7 @@ def run(self): known_tokens = set() blacklist = ( - 'PWD', 'OLDPWD', 'SYSTEMD_NSS_BYPASS_BUS' + 'PWD', 'OLDPWD', 'SYSTEMD_NSS_BYPASS_BUS', 'SYSTEMD_NSS_DYNAMIC_BYPASS' ) proxies = ( From 3b5859284643d608eee173838cf16129d2a5c9a2 Mon Sep 17 00:00:00 2001 From: exploide Date: Sun, 6 Aug 2023 16:47:44 +0200 Subject: [PATCH 4/4] shadow: improved shadow module - check for read access instead of being root; permissions could be misconfigured - skip !! hashes, they are disabled on RHEL-like systems - more intuitive output ordering - removed outdated comment about SHA-512 being used on all modern computers (yescrypt it is) --- Linux/lazagne/softwares/sysadmin/shadow.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Linux/lazagne/softwares/sysadmin/shadow.py b/Linux/lazagne/softwares/sysadmin/shadow.py index 9ffe77f7..2bc74d2f 100755 --- a/Linux/lazagne/softwares/sysadmin/shadow.py +++ b/Linux/lazagne/softwares/sysadmin/shadow.py @@ -33,7 +33,7 @@ def dictionary_attack(self, user, crypt_pwd): '1': 'MD5', '2': 'Blowfish', '5': 'SHA-256', - '6': 'SHA-512', # Used by all modern computers + '6': 'SHA-512', } # For Debug information @@ -63,16 +63,16 @@ def dictionary_attack(self, user, crypt_pwd): return False def run(self): - # Need admin privilege - if os.getuid() == 0: + shadow_file = '/etc/shadow' + if os.access(shadow_file, os.R_OK): pwd_found = [] - with open('/etc/shadow', 'r') as shadow_file: + with open(shadow_file, 'r') as shadow_file: for line in shadow_file.readlines(): user_hash = line.replace('\n', '') line = user_hash.split(':') # Check if a password is defined - if not line[1] in ['x', '*', '!']: + if not line[1] in ['x', '*', '!', '!!']: user = line[0] crypt_pwd = line[1] @@ -84,8 +84,8 @@ def run(self): else: # No clear text password found - save hash pwd_found.append({ + 'Login': user_hash.split(':')[0].replace('\n', ''), 'Hash': ':'.join(user_hash.split(':')[1:]), - 'Login': user_hash.split(':')[0].replace('\n', '') }) return pwd_found