# HG changeset patch # User Jean-Francois Pieronne <jf.pieronne@laposte.net> # Date 1587571483 -7200 # Wed Apr 22 18:04:43 2020 +0200 # Node ID 293b91237c6350e12bc898eae60cb74227ff7fab # Parent 688474a7cdacb9cbd7048767c859b20b7dbfe230 secrules/rules11.py initial version diff --git a/secrules/rules11.py b/secrules/rules11.py new file mode 100644 --- /dev/null +++ b/secrules/rules11.py @@ -0,0 +1,395 @@ +# -*- coding: iso-8859-1 -*- +__version__ = '1.0' + +from common import level_rule +import os +from vms import starlet +from vms.rtl import lib +from vms import user +from vms import ossdef, uaidef, syidef, prvdef +from vms import itemList +from FindFile import FindFile +from FindFile import file_exists +from getMailObjectInfo import getMailObjectInfo + +@level_rule(2) +def rule1101(fo, fmt): + """ Many, or all, of their mail files may reside on a different system. +This prevents analysis of the mail files associated with these users.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1101' + print>>fo, '=========' + + with os.popen('@MAIL_FORWARD.COM') as p: + r = [x[1:-1] for x in p] + for e in r: + if not (e == ''): + if fmt: + print>>fo, '1101�2�', e + else: + print>>fo, e + +@level_rule(2) +def rule1102(fo, fmt): + """ A users mail file should limit access to the SYSTEM and OWNER +(typically RW for SYSTEM and OWNER and no access for GROUP and WORLD). +The listed files should have their protection changed to (RW,RW,,).""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1102' + print>>fo, '=========' + + all_users = user.all_users() + + it = [itemList.itemList (code = ossdef.OSS__PROTECTION, dtype = itemList.il_unsignedWord),] + for u in all_users.values(): + df = u.defdev + u.defdir + 'MAIL.MAI' + if file_exists(df): + prot = starlet.get_security(objnam=df, clsnam='FILE',itmlst=it)[1][ossdef.OSS__PROTECTION] + if (prot != 0xFFCC): + if fmt: + print>>fo, '1102�2�', df + else: + print>>fo, df + print>>fo, ' ' * 10, lib.format_sogw_prot (prot)[1] + +@level_rule(2) +def rule1103(fo, fmt): + """ A users mail file should only be owned by that user. The owner of a +file has full access to the file including read, write and delete privileges +on that file. These files should be changed to specify the proper owner.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1103' + print>>fo, '=========' + + all_users = user.all_users() + + it = [itemList.itemList (code = ossdef.OSS__OWNER, dtype = itemList.il_unsignedLong),] + for u in all_users.values(): + df = u.defdev+ u.defdir+'MAIL.MAI' + if file_exists(df): + own = starlet.get_security (objnam=df, clsnam='FILE',itmlst=it)[1][ossdef.OSS__OWNER] + g = int(own / 65536) + m = int(own - (g *65536)) + if (u.uic_group != g) or (u.uic_member != m): + if fmt: + print>>fo, '1103�2�', u.username + else: + print>>fo, "%s [%o,%o] %s [%o,%o]" % (df, g, m, u.username, u.uic_group, u.uic_member) + +@level_rule(3) +def rule1104(fo, fmt): + """ During review of the system MAIL object, either 1) The attempt to +gather information on the systems MAIL object was unsuccessful. This implies +that there is no MAIL object available on the system, thus prohibiting the +use of VMS MAIL. -OR- 2) The information collected on the system MAIL object +is incomplete. This implies that the object is not correctly configured or +that the last system upgrade (for openVMS) may have been incomplete.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1104' + print>>fo, '=========' + + p, a, u = getMailObjectInfo() + + if p: + if fmt: + print>>fo, '1104�3� MAIL object present' + else: + print>>fo, 'MAIL object present' + +@level_rule(4) +def rule1105(fo, fmt): + """ This prohibits mail transmissions across the network.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1105' + print>>fo, '=========' + + p, a, u = getMailObjectInfo() + + if not a: + if fmt: + print>>fo, '1105�4� Account MAIL$SERVER missing' + else: + print>>fo, 'Account MAIL$SERVER missing' + +@level_rule(2) +def rule1106(fo, fmt): + """ Not having this flag set allows the account unrestricted access, +which is both unnecessary and undesirable. The RESTRICTED flag should +be set on this account.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1106' + print>>fo, '=========' + + p, a, u = getMailObjectInfo() + if a and not (u.flags & uaidef.UAI_M_RESTRICTED): + if fmt: + print>>fo, '1106�2� Account MAIL$SERVER not RESTRICTED' + else: + print>>fo, 'Account MAIL$SERVER not RESTRICTED' + +@level_rule(2) +def rule1107(fo, fmt): + """ This can permit someone to exploit the privileges of this account, +and presents a risk to the systems overall security. This account should +have its UIC changed to a non-privileged value, i.e. one whose group number +is greater than that specified in the SYSGEN parameter MAXSYSGROUP.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1107' + print>>fo, '=========' + + p, a, u = getMailObjectInfo() + if not a: return + + if (u.uic_group <= lib.getsyi(syidef.SYI__MAXSYSGROUP)[1]): + if fmt: + print>>fo, '1107�2� Account MAIL$SERVER have System Group' + else: + print>>fo, "%s [%o,%o]" % ('Account MAIL$SERVER System Group', u.uic_group, u.uic_member) + +@level_rule(4) +def rule1108(fo, fmt): + """ This effectively disables this account for any use. This condition +inhibits mail transmission across the network.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1108' + print>>fo, '=========' + + p, a, u = getMailObjectInfo() + if not a: return + + if (u.flags & uaidef.UAI_M_DISACNT): + if fmt: + print>>fo, '1108�4� Account MAIL$SERVER is DISUSER' + else: + print>>fo, 'Account MAIL$SERVER is DISUSER' + +@level_rule(1) +def rule1109(fo, fmt): + """ This account should be assigned a password. Not having a password on +this account may grant access to the system via this account from outside +processes, which could exploit this vulnerability.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1109' + print>>fo, '=========' + + p, a, u = getMailObjectInfo() + if not a: return + + if (u.pwd_length < 8): + if fmt: + print>>fo, '1109�1� Account MAIL$SERVER Password Length' + else: + print>>fo, 'Account MAIL$SERVER Password Length', u.pwd_length + +@level_rule(4) +def rule1110(fo, fmt): + """ This prohibits mail transmissions across the network.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1110' + print>>fo, '=========' + + p, a, u = getMailObjectInfo() + if not a: return + + if ((u.network_access_p != '\x00\x00\x00') and + (u.network_access_s != '\x00\x00\x00')): + if fmt: + print>>fo, '1110�4� MAIL$SERVER no Netwrok Access' + else: + print>>fo, 'Account MAIL$SERVER no Netwrok Access' + +@level_rule(2) +def rule1111(fo, fmt): + """ The mail object account has 1) BATCH, 2) REMOTE, 3) DIALUP, and/or 4) +LOCAL access enabled. This permits respective logins to the system: 1) from +batch jobs submitted by other users which can specify this account as the +user; 2) by a user from a remote node; 3) utilizing a modem; 4) by a local +user. This account should have these accesses disabled.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1111' + print>>fo, '=========' + + p, a, u = getMailObjectInfo() + if not a: return + + if ((u.batch_access_p != '\xff\xff\xff') and + (u.batch_access_s != '\xff\xff\xff')): + if fmt: + print>>fo, '1111�2� MAIL$SERVER have REMOTE Access' + else: + print>>fo, 'Account MAIL$SERVER have REMOTE Access' + + if ((u.remote_access_p != '\xff\xff\xff') and + (u.remote_access_s != '\xff\xff\xff')): + if fmt: + print>>fo, '1111�2� MAIL$SERVER have REMOTE Access' + else: + print>>fo, 'Account MAIL$SERVER have REMOTE Access' + + if ((u.dialup_access_p != '\xff\xff\xff') and + (u.dialup_access_s != '\xff\xff\xff')): + if fmt: + print>>fo, '1111�2� MAIL$SERVER have DIALUP Access' + else: + print>>fo, 'Account MAIL$SERVER have DIALUP Access' + +@level_rule(4) +def rule1112(fo, fmt): + """ This account requires TMPMBX and NETMBX privileges in order to +function. Lack of these privileges can impede mail transmissions.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1112' + print>>fo, '=========' + + p, a, u = getMailObjectInfo() + if not a: return + + if not (u.priv & prvdef.PRV_M_NETMBX): + if fmt: + print>>fo, '1112�4� Account MAIL$SERVER privilege NETMBX missing' + else: + print>>fo, 'Account MAIL$SERVER privilege NETMBX missing' + if not (u.def_priv & prvdef.PRV_M_NETMBX): + if fmt: + print>>fo, '1112�4� Account MAIL$SERVER default privilege NETMBX missing' + else: + print>>fo, 'Account MAIL$SERVER default privilege NETMBX missing' + + if not (u.priv & prvdef.PRV_M_TMPMBX): + if fmt: + print>>fo, '1112�4� Account MAIL$SERVER privilege TMPMBX missing' + else: + print>>fo, 'Account MAIL$SERVER privilege TMPMBX missing' + if not (u.def_priv & prvdef.PRV_M_TMPMBX): + if fmt: + print>>fo, '1112�4� Account MAIL$SERVER default privilege TMPMBX missing' + else: + print>>fo, 'Account MAIL$SERVER default privilege TMPMBX missing' + +@level_rule(2) +def rule1113(fo, fmt): + """ If the account contains other weaknesses (such as an ability to access +the system and its resources via this account) then these extra privileges may +allow malicious use of this account to gain unauthorized access to system +objects. This account requires only TMPMBX and NETMBX privileges to function +properly.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1113' + print>>fo, '=========' + + p, a, u = getMailObjectInfo() + if not a: return + + msk_prv = prvdef.PRV_M_NETMBX | prvdef.PRV_M_TMPMBX + if (u.def_priv ^msk_prv) != 0: + if fmt: + print>>fo, '1113�2� Account MAIL$SERVER excessive default privileges' + else: + print>>fo, 'Account MAIL$SERVER excessive default privileges' + if (u.priv ^msk_prv) != 0: + if fmt: + print>>fo, '1113�2� Account MAIL$SERVER excessive privileges' + else: + print>>fo, 'Account MAIL$SERVER excessive privileges' + +@level_rule(2) +def rule1114(fo, fmt): + """ This may allow this file to be corrupted or deleted by an +unauthorized user.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1114' + print>>fo, '=========' + + it = [itemList.itemList (code = ossdef.OSS__OWNER, dtype = itemList.il_unsignedLong),] + + own = starlet.get_security (objnam='SYS$SYSTEM:VMSMAIL_PROFILE.DATA', clsnam='FILE',itmlst=it)[1][ossdef.OSS__OWNER] + g = int(own / 65536) + m = int(own - (g *65536)) + if (g != 1) or (m != 4): + if fmt: + print>>fo, '1114�2� SYS$SYSTEM:VMSMAIL_PROFILE.DATA bad owner' + else: + print>>fo, "%s [%o,%o]" % ('SYS$SYSTEM:VMSMAIL_PROFILE.DATA bad owner', g, m,) + +@level_rule(2) +def rule1115(fo, fmt): + """ This may allow this file to be corrupted or deleted by unauthorized +users.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1115' + print>>fo, '=========' + + it = [ itemList.itemList (code = ossdef.OSS__PROTECTION, dtype = itemList.il_unsignedWord)] + prot = starlet.get_security (objnam='SYS$SYSTEM:VMSMAIL_PROFILE.DATA', clsnam='FILE',itmlst=it)[1][ossdef.OSS__PROTECTION] + + if (prot != 0xFF88): + if fmt: + print>>fo, '1115�2� SYS$SYSTEM:VMSMAIL_PROFILE.DATA bad protection' + else: + print>>fo, 'SYS$SYSTEM:VMSMAIL_PROFILE.DATA', lib.format_sogw_prot (prot)[1] + +@level_rule(2) +def rule1116(fo, fmt): + """ This will prevent the mail system from functioning. It also may +indicate tampering with the operational environment.""" + + if not fmt: + print>>fo + print>>fo, 'RULE 1116' + print>>fo, '=========' + + if not file_exists('SYS$SYSTEM:MAIL_SERVER.EXE'): + if fmt: + print >>fo, '1116�2�SYS$SYSTEM:MAIL_SERVER.EXE not exists' + else: + print >>fo, 'SYS$SYSTEM:MAIL_SERVER.EXE not exists' + +if __name__ == '__main__': + import sys + fo = open(sys.argv[1], 'w') if len(sys.argv) > 1 else sys.stdout + rule1101(fo, len(sys.argv) > 2) + rule1102(fo, len(sys.argv) > 2) + rule1103(fo, len(sys.argv) > 2) + rule1104(fo, len(sys.argv) > 2) + rule1105(fo, len(sys.argv) > 2) + rule1106(fo, len(sys.argv) > 2) + rule1107(fo, len(sys.argv) > 2) + rule1108(fo, len(sys.argv) > 2) + rule1109(fo, len(sys.argv) > 2) + rule1110(fo, len(sys.argv) > 2) + rule1111(fo, len(sys.argv) > 2) + rule1112(fo, len(sys.argv) > 2) + rule1113(fo, len(sys.argv) > 2) + rule1114(fo, len(sys.argv) > 2) + rule1115(fo, len(sys.argv) > 2) + rule1116(fo, len(sys.argv) > 2)