Web Server Security Toolkit

<#
.SYNOPSIS
Web Server Security Toolkit

.DESCRIPTION
This script provides a comprehensive set of tools for analyzing and enhancing the security of web servers,
with a focus on IIS (Internet Information Services).

.NOTES
File Name      : WebServerSecurityToolkit.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, administrator rights, IIS installed
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\WebServerSecurityToolkit.ps1
#>

# Import required modules
Import-Module WebAdministration
Import-Module IISAdministration

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\Web_Server_Security_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"

function Show-Menu {
    Clear-Host
    Write-Host "=== Web Server Security Toolkit ===" -ForegroundColor Cyan
    Write-Host "1.  Analyze IIS Configuration"
    Write-Host "2.  Check SSL/TLS Configuration"
    Write-Host "3.  Review Web Application Firewall (WAF) Settings"
    Write-Host "4.  Analyze HTTP Response Headers"
    Write-Host "5.  Check File and Folder Permissions"
    Write-Host "6.  Review Application Pool Settings"
    Write-Host "7.  Analyze Logging and Auditing Configuration"
    Write-Host "8.  Check for Unnecessary Services and Features"
    Write-Host "9.  Review Authentication Methods"
    Write-Host "10. Analyze Network Security Settings"
    Write-Host "11. Check for Common Vulnerabilities"
    Write-Host "12. Generate Comprehensive HTML Report"
    Write-Host "13. Exit"
}

function Analyze-IISConfiguration {
    Write-Host "`nAnalyzing IIS Configuration..." -ForegroundColor Yellow
    try {
        $iisVersion = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\InetStp"
        $websites = Get-Website
        $appPools = Get-IISAppPool

        $result = [PSCustomObject]@{
            IISVersion = "$($iisVersion.MajorVersion).$($iisVersion.MinorVersion)"
            WebsitesCount = $websites.Count
            AppPoolsCount = $appPools.Count
            DefaultWebsiteEnabled = (Get-Website "Default Web Site").State -eq "Started"
        }

        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error analyzing IIS configuration: $_" -ForegroundColor Red
        return $null
    }
}

function Check-SSLTLSConfiguration {
    Write-Host "`nChecking SSL/TLS Configuration..." -ForegroundColor Yellow
    try {
        $sslProtocols = @("SSL 2.0", "SSL 3.0", "TLS 1.0", "TLS 1.1", "TLS 1.2")
        $results = @()

        foreach ($protocol in $sslProtocols) {
            $clientPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$protocol\Client"
            $serverPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$protocol\Server"
            
            $clientEnabled = (Get-ItemProperty -Path $clientPath -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
            $serverEnabled = (Get-ItemProperty -Path $serverPath -Name "Enabled" -ErrorAction SilentlyContinue).Enabled

            $results += [PSCustomObject]@{
                Protocol = $protocol
                ClientEnabled = if ($clientEnabled -eq 0) { "Disabled" } elseif ($clientEnabled -eq 1) { "Enabled" } else { "Not Configured" }
                ServerEnabled = if ($serverEnabled -eq 0) { "Disabled" } elseif ($serverEnabled -eq 1) { "Enabled" } else { "Not Configured" }
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error checking SSL/TLS configuration: $_" -ForegroundColor Red
        return $null
    }
}

function Review-WAFSettings {
    Write-Host "`nReviewing Web Application Firewall (WAF) Settings..." -ForegroundColor Yellow
    Write-Host "Note: This function checks for common WAF solutions. Actual WAF may vary." -ForegroundColor Yellow
    
    try {
        $wafPresent = $false
        $wafInfo = [PSCustomObject]@{
            WAFDetected = $false
            WAFType = "Unknown"
            Status = "Not Installed"
        }

        # Check for common WAF solutions (this is a simplified check and may need to be adapted)
        if (Get-Service "MicrosoftAzureApplicationGateway" -ErrorAction SilentlyContinue) {
            $wafPresent = $true
            $wafInfo.WAFDetected = $true
            $wafInfo.WAFType = "Azure Application Gateway"
            $wafInfo.Status = "Installed"
        }
        elseif (Get-Website "ARR_*" -ErrorAction SilentlyContinue) {
            $wafPresent = $true
            $wafInfo.WAFDetected = $true
            $wafInfo.WAFType = "Application Request Routing (Potential WAF)"
            $wafInfo.Status = "Installed"
        }

        if (-not $wafPresent) {
            Write-Host "No common WAF solution detected. Manual verification recommended." -ForegroundColor Yellow
        }

        $wafInfo | Format-List
        return $wafInfo
    }
    catch {
        Write-Host "Error reviewing WAF settings: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-HTTPResponseHeaders {
    Write-Host "`nAnalyzing HTTP Response Headers..." -ForegroundColor Yellow
    try {
        $websites = Get-Website
        $results = @()

        foreach ($site in $websites) {
            $headers = Get-WebConfiguration "/system.webServer/httpProtocol/customHeaders" -PSPath "IIS:\Sites\$($site.Name)"
            $securityHeaders = @(
                "X-Frame-Options",
                "X-XSS-Protection",
                "X-Content-Type-Options",
                "Strict-Transport-Security",
                "Content-Security-Policy",
                "Referrer-Policy"
            )

            $presentHeaders = $headers.Collection | Where-Object { $securityHeaders -contains $_.Name } | Select-Object Name, Value

            $results += [PSCustomObject]@{
                Website = $site.Name
                PresentSecurityHeaders = ($presentHeaders | ForEach-Object { "$($_.Name): $($_.Value)" }) -join ", "
                MissingSecurityHeaders = ($securityHeaders | Where-Object { $_ -notin $presentHeaders.Name }) -join ", "
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error analyzing HTTP response headers: $_" -ForegroundColor Red
        return $null
    }
}

function Check-FileAndFolderPermissions {
    Write-Host "`nChecking File and Folder Permissions..." -ForegroundColor Yellow
    try {
        $websites = Get-Website
        $results = @()

        foreach ($site in $websites) {
            $physicalPath = $site.PhysicalPath -replace "%SystemDrive%", $env:SystemDrive
            $acl = Get-Acl $physicalPath
            $permissions = $acl.Access | Select-Object IdentityReference, FileSystemRights

            $results += [PSCustomObject]@{
                Website = $site.Name
                PhysicalPath = $physicalPath
                Permissions = ($permissions | ForEach-Object { "$($_.IdentityReference): $($_.FileSystemRights)" }) -join "; "
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error checking file and folder permissions: $_" -ForegroundColor Red
        return $null
    }
}

function Review-ApplicationPoolSettings {
    Write-Host "`nReviewing Application Pool Settings..." -ForegroundColor Yellow
    try {
        $appPools = Get-IISAppPool
        $results = @()

        foreach ($pool in $appPools) {
            $results += [PSCustomObject]@{
                Name = $pool.Name
                ManagedRuntimeVersion = $pool.ManagedRuntimeVersion
                IdentityType = $pool.ProcessModel.IdentityType
                IdleTimeout = $pool.ProcessModel.IdleTimeout
                LoadUserProfile = $pool.ProcessModel.LoadUserProfile
                MaxProcesses = $pool.ProcessModel.MaxProcesses
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error reviewing application pool settings: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-LoggingAndAuditingConfiguration {
    Write-Host "`nAnalyzing Logging and Auditing Configuration..." -ForegroundColor Yellow
    try {
        $websites = Get-Website
        $results = @()

        foreach ($site in $websites) {
            $logFile = Get-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST/$($site.Name)"  -filter "system.applicationHost/sites/site[@name='$($site.Name)']/logFile" -name *
            
            $results += [PSCustomObject]@{
                Website = $site.Name
                LoggingEnabled = $logFile.enabled
                LogFormat = $logFile.logFormat
                Directory = $logFile.directory
                Period = $logFile.period
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error analyzing logging and auditing configuration: $_" -ForegroundColor Red
        return $null
    }
}

function Check-UnnecessaryServicesAndFeatures {
    Write-Host "`nChecking for Unnecessary Services and Features..." -ForegroundColor Yellow
    try {
        $unnecessaryFeatures = @(
            "IIS-WebDAV",
            "IIS-ASPNET45",
            "IIS-ASP",
            "IIS-CGI",
            "IIS-ServerSideIncludes"
        )

        $installedFeatures = Get-WindowsOptionalFeature -Online | Where-Object { $_.State -eq "Enabled" }
        $results = @()

        foreach ($feature in $unnecessaryFeatures) {
            $installed = $installedFeatures | Where-Object { $_.FeatureName -eq $feature }
            $results += [PSCustomObject]@{
                Feature = $feature
                Installed = if ($installed) { $true } else { $false }
                Recommendation = if ($installed) { "Consider removing if not needed" } else { "Not installed (Good)" }
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error checking unnecessary services and features: $_" -ForegroundColor Red
        return $null
    }
}

function Review-AuthenticationMethods {
    Write-Host "`nReviewing Authentication Methods..." -ForegroundColor Yellow
    try {
        $websites = Get-Website
        $results = @()

        foreach ($site in $websites) {
            $authMethods = @(
                "anonymousAuthentication",
                "basicAuthentication",
                "windowsAuthentication",
                "digestAuthentication"
            )

            $enabledMethods = @()

            foreach ($method in $authMethods) {
                $config = Get-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST/$($site.Name)"  -filter "system.webServer/security/authentication/$method" -name "enabled"
                if ($config.Value) {
                    $enabledMethods += $method
                }
            }

            $results += [PSCustomObject]@{
                Website = $site.Name
                EnabledAuthMethods = $enabledMethods -join ", "
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error reviewing authentication methods: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-NetworkSecuritySettings {
    Write-Host "`nAnalyzing Network Security Settings..." -ForegroundColor Yellow
    try {
        $firewallRules = Get-NetFirewallRule | Where-Object { $_.Enabled -and ($_.Direction -eq "Inbound") }
        $openPorts = Get-NetTCPConnection | Where-Object { $_.State -eq "Listen" } | Select-Object LocalPort -Unique

        $results = [PSCustomObject]@{
            FirewallRulesCount = $firewallRules.Count
            OpenPorts = ($openPorts.LocalPort | Sort-Object) -join ", "
        }

        $results | Format-List
        return $results
    }
    catch {
        Write-Host "Error analyzing network security settings: $_" -ForegroundColor Red
        return $null
    }
}

function Check-CommonVulnerabilities {
    Write-Host "`nChecking for Common Vulnerabilities..." -ForegroundColor Yellow
    try {
        $vulnerabilities = @()

        # Check for directory browsing
        $dirBrowsing = Get-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/directoryBrowse" -name "enabled"
        if ($dirBrowsing.Value) {
            $vulnerabilities += "Directory browsing is enabled"
        }

        # Check for potentially dangerous HTTP methods
        $webDAV = Get-WindowsOptionalFeature -Online -FeatureName IIS-WebDAV
        if ($webDAV.State -eq "Enabled") {
            $vulnerabilities += "WebDAV is enabled, which allows potentially dangerous HTTP methods"
        }

        # Check for default documents
        $defaultDocs = Get-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/defaultDocument/files/add" -name "value"
        if ($defaultDocs.Value -contains "iisstart.htm") {
            $vulnerabilities += "Default IIS start page is present"
        }

        if ($vulnerabilities.Count -eq 0) {
            Write-Host "No common vulnerabilities detected." -ForegroundColor Green
        } else {
            Write-Host "Vulnerabilities detected:" -ForegroundColor Red
            $vulnerabilities | ForEach-Object { Write-Host "- $_" -ForegroundColor Yellow }
        }

        return $vulnerabilities
    }
    catch {
        Write-Host "Error checking for common vulnerabilities: $_" -ForegroundColor Red
        return $null
    }
}

function Generate-HTMLReport {
    param([hashtable]$AllResults)

    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Web Server Security Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .warning { color: orange; }
        .critical { color: red; }
    </style>
</head>
<body>
    <h1>Web Server Security Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>IIS Configuration</h2>
    $($AllResults.IISConfig | ConvertTo-Html -Fragment)

    <h2>SSL/TLS Configuration</h2>
    $($AllResults.SSLTLSConfig | ConvertTo-Html -Fragment)

    <h2>WAF Settings</h2>
    $($AllResults.WAFSettings | ConvertTo-Html -Fragment)

    <h2>HTTP Response Headers</h2>
    $($AllResults.HTTPHeaders | ConvertTo-Html -Fragment)

    <h2>File and Folder Permissions</h2>
    $($AllResults.Permissions | ConvertTo-Html -Fragment)

    <h2>Application Pool Settings</h2>
    $($AllResults.AppPoolSettings | ConvertTo-Html -Fragment)

    <h2>Logging and Auditing Configuration</h2>
    $($AllResults.LoggingConfig | ConvertTo-Html -Fragment)

    <h2>Unnecessary Services and Features</h2>
    $($AllResults.UnnecessaryFeatures | ConvertTo-Html -Fragment)

    <h2>Authentication Methods</h2>
    $($AllResults.AuthMethods | ConvertTo-Html -Fragment)

    <h2>Network Security Settings</h2>
    $($AllResults.NetworkSecurity | ConvertTo-Html -Fragment)

    <h2>Common Vulnerabilities</h2>
    $($AllResults.Vulnerabilities | ConvertTo-Html -Fragment)
</body>
</html>
"@

    $reportContent | Out-File -FilePath $global:reportPath
    Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green
}

# Main program loop
$allResults = @{}

do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-13)"

    switch ($choice) {
        "1"  { $allResults.IISConfig = Analyze-IISConfiguration }
        "2"  { $allResults.SSLTLSConfig = Check-SSLTLSConfiguration }
        "3"  { $allResults.WAFSettings = Review-WAFSettings }
        "4"  { $allResults.HTTPHeaders = Analyze-HTTPResponseHeaders }
        "5"  { $allResults.Permissions = Check-FileAndFolderPermissions }
        "6"  { $allResults.AppPoolSettings = Review-ApplicationPoolSettings }
        "7"  { $allResults.LoggingConfig = Analyze-LoggingAndAuditingConfiguration }
        "8"  { $allResults.UnnecessaryFeatures = Check-UnnecessaryServicesAndFeatures }
        "9"  { $allResults.AuthMethods = Review-AuthenticationMethods }
        "10" { $allResults.NetworkSecurity = Analyze-NetworkSecuritySettings }
        "11" { $allResults.Vulnerabilities = Check-CommonVulnerabilities }
        "12" { Generate-HTMLReport -AllResults $allResults }
        "13" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "13") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "13")

This Web Server Security Toolkit includes:

  1. A comprehensive menu-driven interface.
  2. Functions to analyze various aspects of web server security:
    • IIS Configuration Analysis
    • SSL/TLS Configuration Check
    • Web Application Firewall (WAF) Settings Review
    • HTTP Response Headers Analysis
    • File and Folder Permissions Check
    • Application Pool Settings Review
    • Logging and Auditing Configuration Analysis
    • Check for Unnecessary Services and Features
    • Authentication Methods Review
    • Network Security Settings Analysis
    • Common Vulnerabilities Check
  3. Comprehensive HTML report generation.

Key features:

  • Detailed analysis of IIS configuration and settings
  • SSL/TLS protocol and cipher suite checks
  • WAF detection and configuration review
  • Security-related HTTP header analysis
  • File system permissions audit for web directories
  • Application pool security configuration review
  • Logging and auditing settings analysis
  • Identification of potentially unnecessary or risky IIS features
  • Authentication method review across websites
  • Network security analysis including firewall rules and open ports
  • Common web server vulnerability checks
  • Comprehensive HTML report for all analyses

This tool is particularly useful for:

  • Web server administrators
  • Security professionals auditing web server configurations
  • IT professionals setting up or maintaining IIS servers
  • Anyone needing to assess the security posture of a web server

To use this script effectively:

  1. Run PowerShell as an administrator on the web server
  2. Ensure you have the necessary permissions to query IIS and system configurations
  3. Have the IIS PowerShell modules installed (WebAdministration and IISAdministration)
  4. Review the generated HTML report for a comprehensive overview of the web server’s security configuration

This script provides a thorough analysis of web server security settings, helping to identify potential vulnerabilities, misconfigurations, or areas for improvement in the server’s security posture. It’s designed to give administrators a comprehensive view of their web server’s security configuration and highlight areas that may need attention.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *