Create Custom Mitigation QID Scripts 

The Custom Mitigation QID Script allows you to execute specific actions to reduce the risk of an active vulnerability identified in your system. This script is used to reduce the risk or impact of a vulnerability, applying temporary measures to minimize the vulnerability's potential impact.

When the script is successfully run, the associated vulnerability is mitigated, meaning the risk has been addressed for now, even though the underlying issue still exists.

You can provide the following types of scripts:

  • Mitigation: Used to reduce the risk of an vulnerability.
  • Detection: Used to detect an vulnerability.
  • Rollback: Used to revert changes made by a mitigation script.

You can only create and store Custom Mitigation QID scripts in CAR. These scripts can only be executed through the Patch Management module.

You can create a Custom Mitigation QID script using the following ways:

  • Manually enter a script
  • Upload script from local machine

To create a Custom Mitigation QID script, follow these steps:

  1. Navigate to Scripts > Scripts > CreateNew Script.

    The Create New Script page is displayed. 

  2. Enter a Name and Description for the script.

    script basic information.

  3. Click Next to view the Script Details page.
  4. Select the Type of Script as Mitigation QID.
  5. Select Platform (Windows or Linux).
  6. Complete the following Mitigation QID Details:
    Fields Description
    QID Number Provide a QID number.
    QID Severity It is a QID Severity. You can select from values 1 (minimum) to 5 (urgent).
    Implication The implication indicates whether the impact of the script on a vulnerability is permanent or temporary.

    Select the Implication value as Temporary or Permanant.

    Impact Factor Provide a value to determine the impact of the script on a vulnerability based on the Implication:
    • Temporary: The Impact Factor value should be between 1-99. This indicates that the vulnerability has been mitigated till the provided value.
    • Permanant: The Impact Factor value is pre-populated as 100.
    CVE IDs Provide CVE IDs that are associated with a specific QID.
    Mitigation Type Provide a text related to the mitigation type.

  7. Select the Scripting Language from the list in which you want to write the script.

    The list of scripting languages for Windows and Linux are different. 

    Platform Supported Scripting Language
    Windows PowerShell-Script, Python, and VBScript
    Linux Lua, Perl, Python, and Shell
  8. Select a script Category from the list.
  9. Specify the Timeout Limit in seconds, minutes, or hours.

    The Timeout Limit lets you define how long a script must be in execution.

    The Timeout Limit for all Windows and Linux assets ranges from one second to 48 hours. The default value is 300 seconds.

    Add script.

  10. Provide the following scripts by Entering the script manually.
    • Mitigation Script: This is a script designed to apply fixes or workarounds for the identified vulnerabilities.

      Example Mitigation ScriptExample Mitigation Script

      # MITIGATION SCRIPT
      # Purpose: Generic security hardening script
      # This script applies common security best practices

      function Apply-SecurityHardening {
          # Set error action preference
          $ErrorActionPreference = "SilentlyContinue"
          
          $backupFolder = "C:\ProgramData\SecurityBackups\Generic"
          $actionsPerformed = 0
          $report = @()
          
          # Create backup folder
          if (-not (Test-Path $backupFolder)) {
              New-Item -Path $backupFolder -ItemType Directory -Force | Out-Null
              $report += "Created backup directory: $backupFolder"
          }
          
          # Backup current security settings
          $timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
          $report += "Creating security settings backup..."
          
          # Backup firewall settings
          $firewallSettings = Get-NetFirewallProfile | Select-Object Name, Enabled, DefaultInboundAction, DefaultOutboundAction
          $firewallSettings | Export-Clixml -Path "$backupFolder\firewall_$timestamp.xml"
          $report += "Firewall settings backed up"
          
          # Backup services status
          $servicesStatus = Get-Service | Select-Object Name, DisplayName, Status, StartType
          $servicesStatus | Export-Clixml -Path "$backupFolder\services_$timestamp.xml"
          $report += "Services status backed up"
          
          # Enable all firewall profiles
          $report += "`nSecuring firewall settings:"
          $firewallProfiles = Get-NetFirewallProfile
          foreach ($profile in $firewallProfiles) {
              if ($profile.Enabled -eq $false) {
                  $profileName = $profile.Name
                  Set-NetFirewallProfile -Name $profileName -Enabled True
                  $report += "  - Enabled $profileName firewall profile"
                  $actionsPerformed++
              }
          }
          
          # Disable insecure services
          $report += "`nDisabling insecure services:"
          $insecureServices = @(
              "Telnet",
              "ftpsvc",
              "MSFTPSVC",
              "TlntSvr"
          )
          
          foreach ($service in $insecureServices) {
              $svc = Get-Service -Name $service -ErrorAction SilentlyContinue
              if ($svc) {
                  if ($svc.Status -eq "Running") {
                      Stop-Service -Name $service -Force
                      $report += "  - Stopped service: $service"
                      $actionsPerformed++
                  }
                  
                  if ($svc.StartType -ne "Disabled") {
                      Set-Service -Name $service -StartupType Disabled
                      $report += "  - Disabled service: $service"
                      $actionsPerformed++
                  }
              }
          }
          
          # Set secure password policy
          $report += "`nStrengthening password policy:"
          try {
              $currentLength = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SAM").MinimumPasswordLength
              if ($currentLength -lt 12) {
                  Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SAM" -Name "MinimumPasswordLength" -Value 12
                  $report += "  - Set minimum password length to 12 characters"
                  $actionsPerformed++
              }
          } catch {
              $report += "  - Failed to update password policy: $($_.Exception.Message)"
          }
          
          # Disable SMBv1
          $report += "`nDisabling outdated protocols:"
          try {
              $smbSettings = Get-SmbServerConfiguration
              if ($smbSettings.EnableSMB1Protocol) {
                  Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
                  $report += "  - Disabled SMBv1 protocol"
                  $actionsPerformed++
              }
          } catch {
              $report += "  - Failed to disable SMBv1: $($_.Exception.Message)"
          }
          
          # Enable UAC
          $report += "`nEnhancing system protections:"
          $uacRegistry = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
          $uacEnabled = (Get-ItemProperty -Path $uacRegistry).EnableLUA
          
          if ($uacEnabled -eq 0) {
              Set-ItemProperty -Path $uacRegistry -Name "EnableLUA" -Value 1
              $report += "  - Enabled User Account Control (UAC)"
              $actionsPerformed++
          }
          
          # Create a flag file to indicate hardening was applied
          "Security hardening applied on $(Get-Date)" | Out-File "$backupFolder\hardening_applied_$timestamp.txt"
          
          # Output report
          $report | ForEach-Object { Write-Output $_ }
          
          Write-Output "`nMitigation Summary: $actionsPerformed security improvements applied"
          return 0  # Return success
      }

      # Execute mitigation function
      $mitigationResult = Apply-SecurityHardening
      exit $mitigationResult
    • Detection Script: This script is used to identify a specific vulnerability in a system.

      Example Detection ScriptExample Detection Script

      # DETECTION SCRIPT
      # Purpose: Generic vulnerability detection script
      # This script checks for common security misconfigurations

      function Detect-SecurityVulnerabilities {
          # Set error action preference
          $ErrorActionPreference = "SilentlyContinue"
          
          $vulnerabilitiesFound = 0
          $report = @()
          
          # Check Windows Firewall status
          $firewallStatus = Get-NetFirewallProfile | Select-Object Name, Enabled
          $report += "Firewall Status:"
          foreach ($profile in $firewallStatus) {
              $report += "  - $($profile.Name): $($profile.Enabled)"
              if ($profile.Enabled -eq $false) {
                  $vulnerabilitiesFound++
                  $report += "    [VULNERABLE] Firewall profile disabled"
              }
          }
          
          # Check for missing Windows updates
          $report += "`nWindows Updates:"
          try {
              $updateSession = New-Object -ComObject Microsoft.Update.Session
              $updateSearcher = $updateSession.CreateUpdateSearcher()
              $searchResult = $updateSearcher.Search("IsInstalled=0 and Type='Software'")
              
              if ($searchResult.Updates.Count -gt 0) {
                  $vulnerabilitiesFound++
                  $report += "  [VULNERABLE] Missing updates: $($searchResult.Updates.Count)"
                  $criticalUpdates = $searchResult.Updates | Where-Object { $_.MsrcSeverity -eq "Critical" } | Measure-Object
                  if ($criticalUpdates.Count -gt 0) {
                      $report += "  [HIGH RISK] Missing critical updates: $($criticalUpdates.Count)"
                  }
              } else {
                  $report += "  System is up to date"
              }
          } catch {
              $report += "  Unable to check for Windows updates"
          }
          
          # Check for weak password policy
          $report += "`nPassword Policy:"
          $passwordPolicy = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters"
          $minPasswordLength = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SAM").MinimumPasswordLength
          
          if ($minPasswordLength -lt 8) {
              $vulnerabilitiesFound++
              $report += "  [VULNERABLE] Minimum password length ($minPasswordLength) is less than recommended (8)"
          } else {
              $report += "  Minimum password length: $minPasswordLength"
          }
          
          # Check for insecure services
          $report += "`nInsecure Services:"
          $insecureServices = @(
              "Telnet",
              "ftpsvc",
              "MSFTPSVC"
          )
          
          foreach ($service in $insecureServices) {
              $svc = Get-Service -Name $service -ErrorAction SilentlyContinue
              if ($svc -and $svc.Status -eq "Running") {
                  $vulnerabilitiesFound++
                  $report += "  [VULNERABLE] Insecure service running: $service"
              }
          }
          
          # Output report
          $report | ForEach-Object { Write-Output $_ }
          
          Write-Output "`nScan Summary: $vulnerabilitiesFound vulnerabilities detected"
          return $vulnerabilitiesFound
      }

      # Execute detection function
      $detectionResult = Detect-SecurityVulnerabilities
      exit $detectionResult
    • Rollback Script: This script is used to revert any changes made by the mitigation script if needed. It provides a safety mechanism to restore systems to their previous state if the mitigation causes unexpected issues.

      Example Rollback ScriptExample Rollback Script

      # ROLLBACK SCRIPT
      # Purpose: Revert security hardening changes
      # This script restores original settings if mitigation needs to be undone

      function Rollback-SecurityHardening {
          # Set error action preference
          $ErrorActionPreference = "SilentlyContinue"
          
          $backupFolder = "C:\ProgramData\SecurityBackups\Generic"
          $actionsPerformed = 0
          $report = @()
          
          # Check if backup folder exists
          if (-not (Test-Path $backupFolder)) {
              $report += "No backup folder found at $backupFolder. Cannot perform rollback."
              $report | ForEach-Object { Write-Output $_ }
              return 1  # Return error
          }
          
          # Find most recent hardening flag file
          $latestFlag = Get-ChildItem -Path $backupFolder -Filter "hardening_applied_*.txt" | 
                       Sort-Object LastWriteTime -Descending | 
                       Select-Object -First 1
          
          if (-not $latestFlag) {
              $report += "No hardening flag found. Cannot determine which settings to roll back."
              $report | ForEach-Object { Write-Output $_ }
              return 1  # Return error
          }
          
          # Extract timestamp from flag filename
          $timestamp = $latestFlag.Name -replace "hardening_applied_", "" -replace ".txt", ""
          $report += "Rolling back security hardening applied on $timestamp"
          
          # Restore firewall settings
          $firewallBackup = "$backupFolder\firewall_$timestamp.xml"
          if (Test-Path $firewallBackup) {
              $report += "`nRestoring firewall settings:"
              $firewallSettings = Import-Clixml -Path $firewallBackup
              
              foreach ($profile in $firewallSettings) {
                  Set-NetFirewallProfile -Name $profile.Name -Enabled $profile.Enabled
                  $report += "  - Restored $($profile.Name) firewall profile: Enabled=$($profile.Enabled)"
                  $actionsPerformed++
              }
          } else {
              $report += "`nNo firewall backup found for timestamp $timestamp"
          }
          
          # Restore services
          $servicesBackup = "$backupFolder\services_$timestamp.xml"
          if (Test-Path $servicesBackup) {
              $report += "`nRestoring service settings:"
              $serviceSettings = Import-Clixml -Path $servicesBackup
              
              # Focus on previously modified services
              $targetServices = @("Telnet", "ftpsvc", "MSFTPSVC", "TlntSvr")
              
              foreach ($service in $targetServices) {
                  $originalService = $serviceSettings | Where-Object { $_.Name -eq $service }
                  if ($originalService) {
                      # Restore startup type
                      Set-Service -Name $service -StartupType $originalService.StartType
                      $report += "  - Restored service $service startup type to $($originalService.StartType)"
                      
                      # Restore running state if it was running
                      if ($originalService.Status -eq "Running") {
                          Start-Service -Name $service
                          $report += "  - Started service $service"
                      }
                      
                      $actionsPerformed++
                  }
              }
          } else {
              $report += "`nNo services backup found for timestamp $timestamp"
          }
          
          # Reset UAC to previous state
          # Note: We don't have a specific backup of this value, but including this for completeness
          # In a real script, you'd want to backup these specific values too
          $report += "`nRestoring system protections to default values:"
          $uacRegistry = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
          Set-ItemProperty -Path $uacRegistry -Name "EnableLUA" -Value 1
          $report += "  - Reset User Account Control (UAC) to default enabled state"
          $actionsPerformed++
          
          # Move the flag file to indicate it's been rolled back
          $rolledBackPath = $latestFlag.FullName -replace ".txt", "_ROLLED_BACK.txt"
          Move-Item -Path $latestFlag.FullName -Destination $rolledBackPath -Force
          $report += "`nMarked hardening as rolled back"
          
          # Output report
          $report | ForEach-Object { Write-Output $_ }
          
          Write-Output "`nRollback Summary: $actionsPerformed settings restored to original values"
          return 0  # Return success
      }

      # Execute rollback function
      $rollbackResult = Rollback-SecurityHardening
      exit $rollbackResult

    You can also upload the script. For more details, refer to Upload Script.

  11. Select the Create Script in the approved state checkbox to create the script in approved state.

    This option is available only for the manager role.

    The user with any other user role must get the script approved by an authorized user.
    For more details, refer to Qualys CAR RBAC

    Approved script.

  12. Click Next to view the Review and Confirm page.
  13. Review the details and click Confirm & Save.

The Mitigation QID script is created and displayed on the Scripts tab.

As CAR is used as a repository for storing the Mitigation QID script, you can only View Details, Edit, Clone, Export Script, and Deprecate.

Upload Script

You can upload a script from your local drive. The script size limit for any asset on both Windows and Linux platforms is 500 KB.

To upload a script, follow these steps:

  1. Select the Upload Script option.

  2. Click Browse to navigate and upload the required script.

    Once you upload all scripts, the script content is displayed in the Script text box. You can make changes to the script if required.

    If you are using a signed script, always use the browse mechanism to select it. This ensures that the signed script remains intact and can be executed on assets if the execution policy is set to AllSigned.

  3. Click Next.

    The Review and Confirm page displays the selections you have made for the script. It also highlights if the script you have entered contains any commands that may potentially impact the system's behavior and performance.

Edit the Mitigation QID Script

To modify the approved script, follow these steps:

  1. Navigate to the Scripts tab.
  2. To edit a script, select an approved QID script and click Edit on the Quick Actions menu.

    The Basic Information page is displayed.

  3. Modify the details as required and click Next to view the Scripts Details page.

  4. Modify the editable content as required.

  5. Provide the Reason for Edit.

  6. Click Next to view the Review and Confirm page.
  7. Review the script and click Update to save the changes to the script.

Related Topics

Cloning Scripts

Exporting Scripts

Deprecating Scripts