@@ -253,6 +253,12 @@ private ServiceAccessRights GetTriggerAccess(Win32Service service, NtToken token
253253 [ Parameter ( ParameterSetName = "CheckScm" ) ]
254254 public SwitchParameter CheckScmAccess { get ; set ; }
255255
256+ /// <summary>
257+ /// <para type="description">Specify access mask for access to the SCM.</para>
258+ /// </summary>
259+ [ Parameter ( ParameterSetName = "CheckScm" ) ]
260+ public ServiceControlManagerAccessRights ScmAccess { get ; set ; }
261+
256262 /// <summary>
257263 /// <para type="description">Check mode for accessible services.</para>
258264 /// </summary>
@@ -267,7 +273,7 @@ private ServiceAccessRights GetTriggerAccess(Win32Service service, NtToken token
267273 public SwitchParameter IgnoreTrigger { get ; set ; }
268274
269275 /// <summary>
270- /// <para type="description">Generate access check results for the service files.</para>
276+ /// <para type="description">Check for writable service files and directories .</para>
271277 /// </summary>
272278 [ Parameter ( ParameterSetName = "All" ) ]
273279 [ Parameter ( ParameterSetName = "FromName" ) ]
@@ -279,11 +285,15 @@ private protected override void RunAccessCheck(IEnumerable<TokenEntry> tokens)
279285 {
280286 SecurityDescriptor sd = ServiceUtils . GetScmSecurityDescriptor ( ) ;
281287 GenericMapping scm_mapping = ServiceUtils . GetScmGenericMapping ( ) ;
288+ AccessMask access_rights = scm_mapping . MapMask ( ScmAccess ) ;
282289 foreach ( TokenEntry token in tokens )
283290 {
284291 AccessMask granted_access = NtSecurity . GetMaximumAccess ( sd , token . Token , scm_mapping ) ;
285- WriteAccessCheckResult ( "SCM" , "SCM" , granted_access , scm_mapping , sd ,
292+ if ( IsAccessGranted ( granted_access , access_rights ) )
293+ {
294+ WriteAccessCheckResult ( "SCM" , "SCM" , granted_access , scm_mapping , sd ,
286295 typeof ( ServiceControlManagerAccessRights ) , false , token . Information ) ;
296+ }
287297 }
288298 }
289299 else
@@ -295,7 +305,10 @@ private protected override void RunAccessCheck(IEnumerable<TokenEntry> tokens)
295305 {
296306 file_cmdlet = new InternalGetAccessibleFileCmdlet ( this )
297307 {
298- FormatWin32Path = true
308+ FormatWin32Path = true ,
309+ Access = FileAccessRights . WriteData | FileAccessRights . WriteDac | FileAccessRights . WriteOwner | FileAccessRights . AppendData | FileAccessRights . Delete ,
310+ DirectoryAccess = FileDirectoryAccessRights . AddFile | FileDirectoryAccessRights . WriteDac | FileDirectoryAccessRights . WriteOwner ,
311+ AllowPartialAccess = true
299312 } ;
300313 }
301314
@@ -323,13 +336,15 @@ private protected override void RunAccessCheck(IEnumerable<TokenEntry> tokens)
323336 && checked_files . Add ( service . ImagePath ) )
324337 {
325338 file_cmdlet . RunAccessCheckPathInternal ( tokens , service . ImagePath ) ;
339+ file_cmdlet . RunAccessCheckPathInternal ( tokens , Path . GetDirectoryName ( service . ImagePath ) ) ;
326340 }
327341
328342 if ( ! string . IsNullOrWhiteSpace ( service . ServiceDll )
329343 && File . Exists ( service . ServiceDll )
330344 && checked_files . Add ( service . ServiceDll ) )
331345 {
332346 file_cmdlet . RunAccessCheckPathInternal ( tokens , service . ServiceDll ) ;
347+ file_cmdlet . RunAccessCheckPathInternal ( tokens , Path . GetDirectoryName ( service . ServiceDll ) ) ;
333348 }
334349 }
335350 }
0 commit comments