Fighting Fire with Fire: Building a Windows Security Fortress with Scripts

Fighting Fire with Fire: Building a Windows Security Fortress with Scripts

"If scripts are outlawed, only outlaws will have scripts." This sentiment lies at the heart of a long-standing debate over scripting security. Whenever a new virus or cyber-attack emerges, scripts are often the first to be blamed. However, banning scripts entirely is a classic case of throwing the baby out with the bathwater. Scripts are not just potential attack vectors; they are also powerful, flexible tools for automation and security hardening in the hands of a system administrator. This article explores how to use Windows scripts (combining WMI and ADSI) to replicate and even enhance the core functions of the Microsoft Baseline Security Analyzer (MBSA), turning a potential vulnerability into a powerful defense mechanism.

Knowledge is Power: The Synergy of Scripts and MBSA

The Microsoft Baseline Security Analyzer (MBSA) is an excellent free tool that analyzes computers for potential security risks, such as missing security patches or weak password policies. However, MBSA's primary function is to "report." It tells you "what" is wrong but cannot automatically "fix" the problem. For example, MBSA can report that 2,967 computers on your network have the Guest account enabled, but you still need to go and disable them one by one manually.

This is where scripting shines. The power of scripting lies not only in its ability to "get" security information but also in its capacity to automatically "act" on that information. We can write scripts to check for and automatically remediate identified security issues. Below, we will demonstrate through a series of specific security tasks how to use scripts to perform MBSA's checks and, where possible, write further scripts to fix the issues automatically.

Note: To simplify the examples, the following scripts are all targeted at the local machine. With minor modifications, they can be easily extended to manage hundreds or thousands of computers across a network.

Scripting 14 Core Security Tasks

Task 1: Retrieve Computer Name and IP Address

When conducting a security audit, the first step is to identify the target machine. The following WMI script retrieves the computer name and its enabled IP addresses.

' Get Computer Name
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colComputers = objWMIService.ExecQuery("Select * from Win32_ComputerSystem")
For Each objComputer in colComputers
    Wscript.Echo "Computer Name: " & objComputer.Name
Next

' Get IP Address
Set IPConfigSet = objWMIService.ExecQuery("Select IPAddress from Win32_NetworkAdapterConfiguration Where IPEnabled=TRUE")
For Each IPConfig in IPConfigSet
    If Not IsNull(IPConfig.IPAddress) Then
        For Each strAddress in IPConfig.IPAddress
            WScript.Echo "IP Address: " & strAddress
        Next
    End If
Next

Task 2: Check OS Service Pack Version

Ensuring systems have the latest service pack is fundamental to defending against known vulnerabilities. This script queries the latest Service Pack version via WMI.

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colOS = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
For Each objOS in colOS
    Wscript.Echo "Service Pack: " & objOS.ServicePackMajorVersion & "." & objOS.ServicePackMinorVersion
Next

Task 3: Check Installed Security Hotfixes

Many successful attacks are due to the failure to install released security patches. This script lists all installed Quick Fix Engineering (QFE) updates on the system.

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colQuickFixes = objWMIService.ExecQuery("Select * from Win32_QuickFixEngineering")
For Each objQuickFix in colQuickFixes
    Wscript.Echo "HotFix ID: " & objQuickFix.HotFixID & " - Description: " & objQuickFix.Description
Next

Task 4: Check Number of Local Administrators

Too many administrators mean a larger attack surface. This script not only lists all members of the local Administrators group but can also automatically remove non-compliant accounts.

' List Administrators
Set objGroup = GetObject("WinNT://./Administrators,group")
For Each objUser in objGroup.Members
    Wscript.Echo objUser.Name
Next

' Automatically Remove Non-Compliant Admins (Example Policy: Allow only local Administrator and domain admin fabrikam\Administrator)
Set objGroup = GetObject("WinNT://./Administrators,group")
For Each objUser in objGroup.Members
    If LCase(objUser.Name) <> "administrator" and LCase(objUser.Name) <> "fabrikam\administrator" Then
        objGroup.Remove(objUser.ADsPath)
    End If
Next

Task 5: Check for Passwords That Don't Expire

Forcing regular password expiration is an effective security measure. The following script finds all accounts set to "Password never expires" and can automatically change that setting.

Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000

' Check and Report
Set colAccounts = GetObject("WinNT://.")
colAccounts.Filter = Array("user")
For Each objUser In colAccounts
    flag = objUser.Get("UserFlags")
    If flag AND ADS_UF_DONT_EXPIRE_PASSWD Then
        Wscript.Echo objUser.Name & ": Password does not expire."
    End If
Next

' Auto-Remediate: Force all user passwords to expire
For Each objUser In colAccounts
    flag = objUser.Get("UserFlags")
    If flag AND ADS_UF_DONT_EXPIRE_PASSWD Then
        objUser.UserFlags = flag XOR ADS_UF_DONT_EXPIRE_PASSWD
        objUser.SetInfo
    End If
Next

Task 6: Test for Weak Passwords

MBSA can detect weak passwords like blank passwords or passwords identical to the username. Scripts can simulate this check. This example detects if the password is "password".

On Error Resume Next
strPassword = "password"
Set colAccounts = GetObject("WinNT://.")
colAccounts.Filter = Array("user")
For Each objUser In colAccounts
    objUser.ChangePassword strPassword, strPassword
    If Err = 0 or Err = -2147023569 Then
        Wscript.Echo objUser.Name & " is using the weak password '" & strPassword & "'."
    End If
    Err.Clear
Next

Task 7: Check File System Type

Using the NTFS file system is essential for access control. This script checks if all local hard drive partitions are formatted with NTFS.

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = 3")
For Each objDisk in colDisks
    If UCase(objDisk.FileSystem) <> "NTFS" Then
        Wscript.Echo "Warning: Drive " & objDisk.DeviceID & " is using " & objDisk.FileSystem & ", not NTFS."
    End If
Next

Task 8: Check Auto-Logon Settings

Auto-logon is convenient but poses a serious security risk. This script checks and disables the auto-logon feature via the registry.

Const HKEY_LOCAL_MACHINE = &H80000002
strKeyPath = "Software\Microsoft\Windows NT\CurrentVersion\WinLogon"
strValueName = "AutoAdminLogon"

Set objReg = GetObject("winmgmts:\\.\root\default:StdRegProv")

' Check Status
objReg.GetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, dwValue
If dwValue = 1 Then
    Wscript.Echo "Auto-logon is enabled."
    ' Disable Auto-Logon
    dwValue = 0
    objReg.SetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, dwValue
    Wscript.Echo "Auto-logon has been disabled."
End If

Task 9: Check Guest Account Status

The Guest account should always be disabled. This script checks its status and automatically disables it if found enabled.

Set objUser = GetObject("WinNT://./Guest")
If objUser.AccountDisabled Then
    Wscript.Echo "The Guest account is disabled."
Else
    Wscript.Echo "Warning: The Guest account is currently enabled."
    objUser.AccountDisabled = True
    objUser.SetInfo
    Wscript.Echo "The Guest account has now been automatically disabled."
End If

Task 10: Check for Anonymous Logon (RestrictAnonymous)

Restricting anonymous access prevents unauthorized users from enumerating domain usernames and shares. This script checks and sets the correct registry key to restrict anonymous access.

Const HKEY_LOCAL_MACHINE = &H80000002
strKeyPath = "System\CurrentControlSet\Control\Lsa"
strValueName = "RestrictAnonymous"

Set objReg = GetObject("winmgmts:\\.\root\default:StdRegProv")

' Check and Remediate
objReg.GetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, dwValue
If dwValue = 0 Then
    Wscript.Echo "Anonymous access is enabled, posing a risk."
    dwValue = 1
    objReg.SetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, dwValue
    Wscript.Echo "Anonymous access has been restricted."
End If

Task 11: List Running Services

Knowing what services are running helps detect malware or unauthorized applications (like a private FTP server). This script can list services and also stop a specified service.

' List all services and their state
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colServices = objWMIService.ExecQuery("Select * from Win32_Service")
For Each objService in colServices
    Wscript.Echo objService.DisplayName, objService.State
Next

' Stop a specific service (e.g., UPnPHost)
Set colServices = objWMIService.ExecQuery("Select * from Win32_Service Where Name = 'upnphost'")
For Each objService in colServices
    objService.StopService()
Next

Task 12: Check File Shares and Permissions

Insecure shares are a common entry point for data breaches and lateral movement. This script can list all shares and their paths.

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colShares = objWMIService.ExecQuery("Select * from Win32_Share")
For Each objShare in colShares
    Wscript.Echo "Share Name: " & objShare.Name & ", Path: " & objShare.Path
Next

Conclusion

Far from being the villain of the security world, scripting is a powerful weapon for system administrators to achieve automated, scalable security management. By combining the checking logic of MBSA with the execution power of scripts, we can not only find problems but also solve them efficiently and consistently, thereby building a robust and intelligent security defense line across the enterprise network.

← Previous Post

Leave a Comment