# HG changeset patch # User jfp <jf.pieronne@laposte.net> # Date 1673969408 -3600 # Tue Jan 17 16:30:08 2023 +0100 # Node ID b4e6c1c444844a788e0b823bc01e8c155de44956 # Parent fe61049b37e490e54745da08c28c98468868f164 get_security.py: update stub information rule302: better filters rule401: Only report ACE if IDENTIFIER=* and access allow DELETE or WRITE rule403: fix a bug diff --git a/secrules/get_security.py b/secrules/get_security.py --- a/secrules/get_security.py +++ b/secrules/get_security.py @@ -1,9 +1,10 @@ +from typing import Tuple, List from ovms import starlet from ovms import itemList, ossdef, ssdef from ovms.rtl import lib -def get_security(fn, clsnam=b'FILE'): +def get_security(fn: bytes | str, clsnam=b'FILE') -> Tuple[bytes, bytes, List[bytes]]: itm = ( itemList.itemList(code=ossdef.OSS__ACL_READ), itemList.itemList( @@ -42,8 +43,8 @@ filename = sys.argv[1] clsnam = sys.argv[2] owner, protection, acl = get_security(filename, clsnam.encode()) - print(' Owner:', owner) - print(' Protection:', protection) + print(' Owner:', owner.decode()) + print(' Protection:', protection.decode()) print(' Access control list:') for e in acl: - print(9 * ' ', e) + print(9 * ' ', e.decode()) diff --git a/secrules/rules03.py b/secrules/rules03.py --- a/secrules/rules03.py +++ b/secrules/rules03.py @@ -12,6 +12,40 @@ signifies an unauthorized change was made to the file, and represents an area of vulnerability with regards to protection of critical files.""" + fn_owner = { + b'SYS$SYSROOT:[000000]CML$SERVER.DIR': b'CML$SERVER', + b'SYS$SYSROOT:[000000]MAIL$SERVER.DIR': b'MAIL$SERVER', + b'SYS$SYSROOT:[000000]MIRRO$SERVER.DIR': b'MIRRO$SERVER', + b'SYS$SYSROOT:[000000]PHONE$SERVER.DIR': b'PHONE$SERVER', + b'SYS$SYSROOT:[000000]TCPIP$LPD.DIR': b'TCPIP$LPD', + b'SYS$SYSROOT:[000000]TCPIP$NTP.DIR': b'TCPIP$NTP', + b'SYS$SYSROOT:[000000]TCPIP$SMTP.DIR': b'TCPIP$SMTP', + b'SYS$SYSROOT:[000000]VPM$SERVER.DIR': b'VPM$SERVER', + b'SYS$COMMON:[000000]OMNI.DIR': b'OMNIADMIN', + b'SYS$COMMON:[000000]RDB$REMOTE72.DIR': b'RDB$REMOTE72', + b'SYS$COMMON:[000000]RDB$REMOTE73.DIR': b'RDB$REMOTE73', + b'SYS$COMMON:[000000]RDB$REMOTE74.DIR': b'RDB$REMOTE74', + b'SYS$COMMON:[000000]RDMAIJ72.DIR': b'RDMAIJ72', + b'SYS$COMMON:[000000]RDMAIJ73.DIR': b'RDMAIJ73', + b'SYS$COMMON:[000000]RDMAIJ74.DIR': b'RDMAIJ74', + b'SYS$COMMON:[000000]RDMSTT72.DIR': b'RDMSTT72', + b'SYS$COMMON:[000000]RDMSTT73.DIR': b'RDMSTT73', + b'SYS$COMMON:[000000]RDMSTT74.DIR': b'RDMSTT74', + b'SYS$COMMON:[000000.SYS$STARTUP]OMNI$STARTUP.COM': b'OMNIADMIN', + b'SYS$COMMON:[000000.SYS$STARTUP]OMNI$SHUTDOWN.COM': b'OMNIADMIN', + b'SYS$COMMON:[000000.SYS$STARTUP]OMNI$SYSTARTUP.COM': b'OMNIADMIN', + b'SYS$COMMON:[000000.SYSLIB]LIBAE.EXE': b'OMNIADMIN', + b'SYS$COMMON:[000000.SYSLIB]LIBDC.EXE': b'OMNIADMIN', + b'SYS$COMMON:[000000.SYSLIB]LIBDE.EXE': b'OMNIADMIN', + b'SYS$SYSROOT:[000000.TCPIP$ETC]MOUNTDTAB.DAT': b'TCPIP$NFS', + } + fndir_own = { + b'SYS$COMMON:[000000.OMNI': (b'OMNIADMIN',), + b'SYS$COMMON:[000000.SAMBA': (b'SAMBA$SMBD', b'SAMBA$NMBD'), + b'SYS$SYSROOT:[000000.TCPIP$SMTP': b'TCPIP$SMTP', + b'SYS$SYSROOT:[000000.TCPIP$NTP': b'TCPIP$NTP', + b'SYS$SYSROOT:[000000.TCPIP$LPD': b'TCPIP$LPD', + } if not fmt: print(file=fo) print('Rule 0302', file=fo) @@ -20,14 +54,27 @@ with FindFile(b'SYS$SYSROOT:[000000...]*.*') as fi: for fn in fi: # type: ignore fn: bytes - id = get_security(fn)[0] - if (id != b'SYSTEM') and (id != b'[1,1]'): - if (fn != b'MOM$SYSTEM') and (id != b'[376,375]'): + fn = fn.rsplit(b';')[0] + if fn.startswith(b'SYS$SYSROOT:[000000.SYSCOMMON'): + continue + idf = get_security(fn)[0] + if fn in fn_owner and fn_owner[fn] == idf: + continue + for sfn, own in fndir_own.items(): + if fn.startswith(sfn) and idf in own: + ownok = True + break + else: + ownok = False + if ownok: + continue + if (idf != b'SYSTEM') and (idf != b'[1,1]'): + if (fn != b'MOM$SYSTEM') and (idf != b'[376,375]'): if fmt: print('0302"2"', fn.decode(), file=fo) else: print(fn.decode(), file=fo) - print(' ' * 10, id.decode(), file=fo) + print(' ' * 10, idf.decode(), file=fo) if __name__ == '__main__': diff --git a/secrules/rules04.py b/secrules/rules04.py --- a/secrules/rules04.py +++ b/secrules/rules04.py @@ -43,14 +43,18 @@ ) acllen = int(retacl[2][ossdef.OSS__ACL_LENGTH]) if acllen != 0: - if fmt: - print('0401"2"', fn.decode(), file=fo) - else: - print(fn.decode(), file=fo) + fn_printed = False for e in get_security.get_security(fn)[2]: - e: bytes - if not fmt: - print(' ' * 9, e.decode(), file=fo) + acc = e.split(b',')[-1] + if b'IDENTIFIER=*' in e and (b'DELETE' in acc or b'WRITE' in acc): + if not fn_printed: + fn_printed = True + if fmt: + print('0401"2"', fn.decode(), file=fo) + else: + print(fn.decode(), file=fo) + if not fmt: + print(' ' * 9, e.decode(), file=fo) except VMSError as err: if err.errno not in ( rmsdef.RMS__FNF, @@ -82,7 +86,7 @@ for fn in fi: # type: ignore fn: bytes own = get_security.get_security(fn)[0] - if own not in ('SYSTEM', '[1,1]'): + if own not in (b'SYSTEM', b'[1,1]'): if fmt: print('0403"2"', fn.decode(), file=fo) else: @@ -121,7 +125,7 @@ for fn in fi: # type: ignore fn: bytes prot = get_security.get_security(fn)[1] - if not (prot == 'System: RWED, Owner: RWED, Group: RE, World'): + if prot != b'System: RWED, Owner: RWED, Group: RE, World': if fmt: print('0404"2"', fn.decode(), file=fo) else: