diff --git a/secrules/rules14.py b/secrules/rules14.py
index c3f0d2b86c4333de60ed3ddc43ae8f88b4427415_c2VjcnVsZXMvcnVsZXMxNC5weQ==..24e85e972d75ab092fcdd5075fac19f8c32fc13d_c2VjcnVsZXMvcnVsZXMxNC5weQ== 100644
--- a/secrules/rules14.py
+++ b/secrules/rules14.py
@@ -1,5 +1,6 @@
 # -*- coding: iso-8859-1 -*-
 
+from typing import Tuple
 from .common import level_rule
 import os
 from ovms.rtl.lib import FindFile
@@ -3,8 +4,9 @@
 from .common import level_rule
 import os
 from ovms.rtl.lib import FindFile
-
+from ovms import rms
+from ovms import rmsdef
 __version__ = '1.0'
 
 
 @level_rule(2)
@@ -7,8 +9,8 @@
 __version__ = '1.0'
 
 
 @level_rule(2)
-def rule1401(fo, fmt):
-    """
+def rule1402(fo, fmt):
+    """Verify installed images
     """
     if not fmt:
@@ -13,5 +15,5 @@
     """
     if not fmt:
-        print('RULE 1401', file=fo)
+        print('RULE 1402', file=fo)
         print('=========', file=fo)
 
@@ -16,5 +18,67 @@
         print('=========', file=fo)
 
+    def vmstxtopener(fn, mode):
+        return os.open(fn, os.O_RDONLY)
+
+    vmsimg_files = {}
+
+    def add_file(fn: bytes, priv: Tuple[str,...], auth: Tuple[str,...] = tuple()) -> None:
+        nonlocal vmsimg_files
+        try:
+            fn = b''.join(rms.search(fn, True)[:-2])
+            fn = fn.replace(b'][', b'')
+            vmsimg_files[fn] = (priv, auth)
+        except OSError as e:
+            if e.errno != rmsdef.RMS__FNF:
+                raise
+
+    add_file(b'SYS$SYSTEM:USB$UCM_CLIENT.EXE', tuple(), ('SYSPRV', 'SYSLCK'))
+    add_file(b'SYS$SYSTEM:TCPIP$UCP.EXE', ('CMKRNL', 'PHY_IO'))
+    add_file(b'SYS$SYSTEM:TCPIP$TELNET.EXE', ('OPER',))
+    add_file(b'SYS$SYSTEM:TCPIP$RLOGIN.EXE', ('OPER',))
+    add_file(b'SYS$SYSTEM:TCPIP$PING.EXE', ('OPER',))
+    add_file(b'SYS$SYSTEM:TCPIP$OS_MIBS.EXE', ('BYPASS',))
+    add_file(b'SYS$SYSTEM:TCPIP$NTP.EXE', ('CMKRNL', 'LOG_IO', 'SETPRV', 'OPER', 'SYSPRV'))
+    add_file(b'SYS$SYSTEM:TCPIP$MOUNTD.EXE', ('OPER', 'SYSPRV'))
+    add_file(b'SYS$SYSTEM:TCPIP$LPD_RCV.EXE', ('BYPASS',))
+    add_file(b'SYS$SYSTEM:TCPIP$HR_MIB.EXE', ('WORLD', 'PHY_IO', 'BYPASS',))
+    add_file(b'SYS$SYSTEM:TCPIP$FAILSAFE.EXE', ('CMKRNL', 'OPER', 'SYSPRV', 'SYSLCK'))
+    add_file(b'SYS$SYSTEM:RMUEXEC72.EXE', ('CMKRNL', 'GROUP', 'WORLD', 'SYSPRV'))
+    add_file(b'SYS$SYSTEM:RMUEXEC73.EXE', ('CMKRNL', 'GROUP', 'WORLD', 'SYSPRV'))
+    add_file(b'SYS$SYSTEM:RMUEXEC74.EXE', ('CMKRNL', 'GROUP', 'WORLD', 'SYSPRV'))
+    add_file(b'SYS$SYSTEM:RMU72.EXE', ('CMKRNL', 'SYSPRV'))
+    add_file(b'SYS$SYSTEM:RMU73.EXE', ('CMKRNL', 'SYSPRV'))
+    add_file(b'SYS$SYSTEM:RMU74.EXE', ('CMKRNL', 'SYSPRV'))
+    add_file(b'SYS$SYSTEM:PPPD$UTIL.EXE', ('CMKRNL', 'PRMMBX', 'PSWAPM', 'SYSPRV'))
+    add_file(b'SYS$SYSTEM:LD$UTILITY.EXE', ('PHY_IO', 'SYSLCK', 'SHARE'))
+    add_file(b'SYS$SYSTEM:LM$UTILITY.EXE', ('PHY_IO', 'SYSLCK', 'SHARE'))
+    add_file(b'SYS$SYSTEM:ENCRYPT$FAC.EXE', ('SYSNAM',))
+    add_file(b'SYS$SYSTEM:DECW$WINMGR.EXE', ('SETPRV',))
+    add_file(b'SYS$SYSTEM:DECW$SETSHODIS.EXE', ('CMEXEC',), ('SYSPRV', 'AUDIT'))
+    add_file(b'SYS$SYSTEM:CTF$SERVER.EXE', ('SYSNAM', 'TMPMBX', 'SYSGBL', 'SYSLCK'))
+    add_file(b'SYS$SYSTEM:CTF$DCP.EXE', ('CMKRNL', '', 'PRMMBX', 'PSWAPM', 'TMPMBX', 'WORLD', 'NETMBX', 'PRMGBL'))
+    add_file(b'SYS$COMMON:[CDE$DEFAULTS.SYSTEM.BIN]DTGREET.EXE', ('NETMBX',))
+
+    with open('/SYS$MANAGER/VMSIMAGES.DAT', opener=vmstxtopener) as fi:
+        for line in fi:
+            if '/PRIV' in line:
+                lst = line.split('/')
+                fn = lst[0].rstrip()
+                if fn[-4:] != '.EXE':
+                    fn += '.EXE'
+                fn = rms.search(fn, True)[:-2]
+                fn = b''.join(fn).replace(b'][', b'')
+                priv = ''
+                auth = None
+                for v in lst:
+                    if v.startswith('PRIV'):
+                        priv = v
+                    if v.startswith('AUTH'):
+                        auth = v
+                lstpriv = priv[priv.index('(') + 1 : priv.index(')')].split(',')
+                lstauth = tuple() if auth is None else auth[auth.index('(') + 1 : auth.index(')')].split(',')
+                vmsimg_files[fn] = (lstpriv, lstauth)
+
     with os.popen('install list/full') as p:
         r = [x[:-1].rstrip() for x in p]
     dspec = ''
@@ -53,5 +117,8 @@
             ) as fi:   # type: ignore
                 for f in fi:   # type: ignore
                     f: bytes
-                    if hasPriv:
+                    f = f.replace(b'<', b'[').replace(b'>', b']')
+                    f = b''.join(rms.search(f, True)[:-2])
+                    f = f.replace(b'][', b'')
+                    if hasPriv and f not in vmsimg_files:
                         if fmt:
@@ -57,5 +124,5 @@
                         if fmt:
-                            print('1401"2"', f.decode(), file=fo)
+                            print('1402"2"', f.decode(), file=fo)
                         else:
                             print(f.decode(), file=fo)
                             if priv:
@@ -68,4 +135,4 @@
     import sys
 
     fo = open(sys.argv[1], 'w') if len(sys.argv) > 1 else sys.stdout
-    rule1401(fo, len(sys.argv) > 2)
+    rule1402(fo, len(sys.argv) > 2)