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