Wednesday, February 15, 2012

Windows Service Security Descriptors: Client Script

Back to Windows Service Security Descriptors Project


' Author:  Cameron L. Wilson (thepip3r)
' Date:   9/25/2011
' Description:  Track vulnerable services on Windows systems
' References:
' - Win32_ACE:    http://msdn.microsoft.com/en-us/library/aa394063.aspx
' - Win32_SecurityDescriptor: http://msdn.microsoft.com/en-us/library/aa394402.aspx
' - Win32_Service:   http://msdn.microsoft.com/en-us/library/aa394418(v=VS.85).aspx




' ****************************************************************************************************************************************
' Begin:  Create Custom WMI Namespace/Class
' ****************************************************************************************************************************************

Const wbemCimtypeSint16 = 2
Const wbemCimtypeSint32 = 3
Const wbemCimtypeReal32 = 4
Const wbemCimtypeReal64 = 5
Const wbemCimtypeString = 8
Const wbemCimtypeBoolean = 11
Const wbemCimtypeObject = 13
Const wbemCimtypeSint8 = 16
Const wbemCimtypeUint8 = 17
Const wbemCimtypeUint16 = 18
Const wbemCimtypeUint32 = 19
Const wbemCimtypeSint64 = 20
Const wbemCimtypeUint64 = 21
Const wbemCimtypeDateTime = 101
Const wbemCimtypeReference = 102
Const wbemCimtypeChar16 = 103


Set objLocator = CreateObject("WbemScripting.sWbemLocator") 
Set objSvc = objLocator.ConnectServer(".", "root") 
Set objNamespace = objSvc.Get("__namespace") 
Set objCustomNameSpace = objNamespace.SpawnInstance_ 

objCustomNamespace.name = "custom" ' Create the "Custom" namespace
objCustomNamespace.Put_() 

Set objWMI = GetObject("winmgmts:root\custom") 
Set objClass = objWMI.Get()

strClass = "ServiceVulnerabilities"

' Look for existing custom classes on this host and wipe them out if they exist
On Error Resume Next
Set objServiceVulnerabilities = objWMI.Get(strClass)

If Err.Number = 0 Then
 objServiceVulnerabilities.Delete_
End If
On Error Goto 0

' Create the custom class with all of its properties
objClass.Path_.Class = strClass 
objClass.Properties_.add "ServiceID", wbemCimtypeUint32 
objClass.Properties_("ServiceID").Qualifiers_.add "key", true 
objClass.Properties_.add "ServiceName", wbemCimtypeString 
objClass.Properties_.add "ServiceDisplayName", wbemCimtypeString 
objClass.Properties_.add "Trustee", wbemCimtypeString 
objClass.Properties_.add "AccessMask", wbemCimtypeUint32 
objClass.Properties_.add "AceType", wbemCimtypeUint32
objClass.Properties_.add "AceFlags", wbemCimtypeUint32

objClass.Put_() 

' Apply a pre-defined security string to the new namespace/class
strSD = "1,0,4,128,148,0,0,0,164,0,0,0,0,0,0,0,20,0,0,0,2,0,128,0,4,0,0,0,0,18,24,0,63,0,6,0,1,2,0,0,0,0,0,5,32,0,0,0,32,2,0,0,0,18,20,0,19,0,0,0,1,1,0,0,0,0,0,5,20,0,0,0,0,18,20,0,19,0,0,0,1,1,0,0,0,0,0,5,19,0,0,0,0,18,20,0,19,0,0,0,1,1,0,0,0,0,0,5,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,5,32,0,0,0,32,2,0,0,1,2,0,0,0,0,0,5,32,0,0,0,32,2,0,0" 
arrSD = Split(strSD,",") 

Set objSS = objWMI.Get("__SystemSecurity=@") 
objSS.SetSD(arrSD)

' ****************************************************************************************************************************************
' End:  Create Custom WMI Namespace/Class
' ****************************************************************************************************************************************




' ****************************************************************************************************************************************
' Begin:  Query Service Security Descriptors for User-Defined Criteria
' ****************************************************************************************************************************************

Const SE_DACL_PRESENT = &h4  
Const ACCESS_ALLOWED_ACE_TYPE = &h0  
Const ACCESS_DENIED_ACE_TYPE  = &h1   
 
strExclusions = "BUILTIN\Administrators, NT SERVICE\TrustedInstaller, NT AUTHORITY\SYSTEM, NT SERVICE\IPBusEnum, BUILTIN\Domain Administrators"
arrExclusions = Split(strExclusions, ",")
 
strComputer = "."  
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate, (Security)}!\\" & strComputer & "\root\cimv2")   
Set colServices =  objWMIService.ExecQuery("Select * from Win32_Service")   

Set objData = objWMI.Get(strClass) 
Set objInstance = objData.SpawnInstance_ 

y = 0
For Each objService in colServices    
 
 WScript.Echo objService.Name

 iReturn = objService.GetSecurityDescriptor( objSD )   
 
 If ( iReturn <> 0 ) Then   
  WScript.Echo "Could not get security descriptor: " & iReturn
 End If  
 
 ' Extract the security descriptor flags   
 intControlFlags = objSD.ControlFlags  
 
 If intControlFlags AND SE_DACL_PRESENT Then 
  WScript.Echo "   Control Flags:" & vbTab & intControlFlags
  ' Get the ACE entries from security descriptor    
  colACEs = objSD.DACL  

  For Each objACE in colACEs  
   strTrustee = objACE.Trustee.Domain & "\" & objACE.Trustee.Name

   If Trim(strTrustee) = "\" Then
    strTrustee = objACE.Trustee.SIDString
   End If
   
   ' Make sure the ACEType is an "allow", make sure the accessmask gives the group some kind of "write" permissions, and the trustee group isn't predefined as "good"
   If objACE.AceType = ACCESS_ALLOWED_ACE_TYPE And objACE.AccessMask >= 262144 And Not InArray(arrExclusions, strTrustee) Then 
    ' Get all the trustees and determine which have access to the service
    strTrustees = strTrustees & strTrustee & vbCrLf
    strAccessMasks = strAccessMasks & objACE.AccessMask & vbCrLf
    strAceFlags = strAceFlags & objACE.AceFlags & vbCrLf
    strAceTypes = strAceTypes & objACE.AceType & vbCrLf
    
    WScript.Echo "   Trustee:" & vbTab & strTrustee
    WScript.Echo "   Trustee SID:" & vbTab & objACE.Trustee.SIDString
    WScript.Echo "   Trustee SIDLength:" & vbTab & objACE.Trustee.SIDLength
    WScript.Echo "   Trustee SID:"
    For Each strSIDpart in objACE.Trustee.SID
     strSID = strSID & strSIDPart
    Next
    WScript.Echo "     " & vbTab & strSID
    WScript.Echo "   Access Mask:" & vbTab & objACE.AccessMask
    WScript.Echo "   Ace Flags:" & vbTab & objACE.AceFlags
    WScript.Echo "   Ace Types:" & vbTab & objACE.AceType
    
   ElseIf objACE.AceType = ACCESS_DENIED_ACE_TYPE Then     
    ' Don't care about Denies
   End If  
  Next
  
  If strTrustees <> "" Then
   WScript.Echo "   Class Index:" & vbTab & y
   
   arrTrustees = Split(strTrustees, vbCrLf)
   arrAccessMasks = Split(strAccessMasks, vbCrLf)
   arrAceFlags = Split(strAceFlags, vbCrLf)
   arrAceTypes = Split(strAceTypes, vbCrLf)
   
   ' Loop through the found ACE entries and write those to our custom class
   For x=0 to (Ubound(arrTrustees)-1)
    objInstance.ServiceID = y
    objInstance.ServiceName = objService.Name
    objInstance.ServiceDisplayName = objService.DisplayName
    objInstance.Trustee = arrTrustees(x)
    objInstance.AccessMask = arrAccessMasks(x)
    objInstance.AceType = arrAceTypes(x) 
    objInstance.AceFlags = arrAceFlags(x)
    
    objInstance.Put_() 
    y = y + 1
   Next
   
   strTrustees = ""
   strAccessMasks = ""
   strAceFlags = ""
   strAceTypes = ""
  End If

  
 Else   
  ' No DACL found; we don't care about the security descriptor.
  WScript.Echo "   Control Flags(F):" & vbTab & intControlFlags
 End If  
Next

' ****************************************************************************************************************************************
' End:  Query Service Security Descriptors for User-Defined Criteria
' ****************************************************************************************************************************************



' Checks for the existence of a string in an array
Function InArray(arrName, strValue)
 For Each strItem in arrName
  If Trim(LCase(strItem)) = Trim(LCase(CStr(strValue))) Then
   InArray = TRUE
   Exit Function
  End If
 Next
 InArray = FALSE 
End Function

   

No comments:

Post a Comment