Загрузка данных
#requires -version 2.0
<#
.SYNOPSIS
Проверка отключения LLMNR, NetBIOS и WPAD.
.DESCRIPTION
Совместим с Windows 7 / PowerShell 2.0 и Windows 10.
Проверяет:
- LLMNR
- NetBIOS over TCP/IP
- WPAD / WinINET AutoDetect
- WinHTTP DisableWpad
- PAC AutoConfigURL
- DNS resolution of wpad.<domain>
- NetBIOS ports 137/138/139
.NOTES
HKCU проверки выполняются для текущего пользователя.
Если запускать скрипт через Computer Startup GPO от SYSTEM,
HKCU будет у SYSTEM, а не у интерактивного пользователя.
#>
$ErrorActionPreference = "SilentlyContinue"
$script:FailCount = 0
$script:WarnCount = 0
function Write-Result {
param(
[string]$Name,
[string]$Status,
[string]$Details
)
switch ($Status) {
"PASS" {
Write-Host ("[PASS] {0}: {1}" -f $Name, $Details) -ForegroundColor Green
}
"FAIL" {
Write-Host ("[FAIL] {0}: {1}" -f $Name, $Details) -ForegroundColor Red
$script:FailCount++
}
"WARN" {
Write-Host ("[WARN] {0}: {1}" -f $Name, $Details) -ForegroundColor Yellow
$script:WarnCount++
}
default {
Write-Host ("[INFO] {0}: {1}" -f $Name, $Details)
}
}
}
function Get-RegistryValueSafe {
param(
[string]$Path,
[string]$Name
)
try {
return (Get-ItemProperty -Path $Path -Name $Name -ErrorAction Stop).$Name
}
catch {
return $null
}
}
Write-Host ""
Write-Host "============================================================"
Write-Host " LLMNR / NETBIOS / WPAD SECURITY CHECK"
Write-Host "============================================================"
Write-Host ""
# ------------------------------------------------------------
# SYSTEM INFORMATION
# ------------------------------------------------------------
$computer = Get-WmiObject Win32_ComputerSystem
$computerName = $env:COMPUTERNAME
$domainName = $computer.Domain
$os = Get-WmiObject Win32_OperatingSystem
Write-Host "Computer : $computerName"
Write-Host "Domain : $domainName"
Write-Host "OS : $($os.Caption)"
Write-Host "Version : $($os.Version)"
Write-Host "User : $env:USERDOMAIN\$env:USERNAME"
Write-Host ""
# ============================================================
# 1. LLMNR
# ============================================================
Write-Host "------------------------------------------------------------"
Write-Host "1. LLMNR"
Write-Host "------------------------------------------------------------"
$llmnrPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient"
$enableMulticast = Get-RegistryValueSafe `
-Path $llmnrPath `
-Name "EnableMulticast"
if ($null -eq $enableMulticast) {
Write-Result `
-Name "LLMNR policy" `
-Status "FAIL" `
-Details "EnableMulticast отсутствует. LLMNR не считается принудительно отключённым."
}
elseif ([int]$enableMulticast -eq 0) {
Write-Result `
-Name "LLMNR policy" `
-Status "PASS" `
-Details "EnableMulticast = 0"
}
else {
Write-Result `
-Name "LLMNR policy" `
-Status "FAIL" `
-Details "EnableMulticast = $enableMulticast"
}
# ============================================================
# 2. NETBIOS
# ============================================================
Write-Host ""
Write-Host "------------------------------------------------------------"
Write-Host "2. NETBIOS over TCP/IP"
Write-Host "------------------------------------------------------------"
$adapters = Get-WmiObject Win32_NetworkAdapterConfiguration `
-Filter "IPEnabled=True"
if ($null -eq $adapters) {
Write-Result `
-Name "NetBIOS adapters" `
-Status "WARN" `
-Details "IP-enabled сетевые адаптеры не найдены."
}
else {
$netbiosFail = $false
foreach ($adapter in $adapters) {
$description = $adapter.Description
$index = $adapter.Index
# TcpipNetbiosOptions:
# 0 = DHCP
# 1 = Enable NetBIOS
# 2 = Disable NetBIOS
$nbt = $adapter.TcpipNetbiosOptions
if ($nbt -eq 2) {
Write-Result `
-Name "NetBIOS adapter $index" `
-Status "PASS" `
-Details "$description -> TcpipNetbiosOptions = 2"
}
elseif ($nbt -eq 1) {
Write-Result `
-Name "NetBIOS adapter $index" `
-Status "FAIL" `
-Details "$description -> NetBIOS ENABLED (TcpipNetbiosOptions = 1)"
$netbiosFail = $true
}
elseif ($nbt -eq 0) {
Write-Result `
-Name "NetBIOS adapter $index" `
-Status "FAIL" `
-Details "$description -> DHCP-controlled (TcpipNetbiosOptions = 0)"
$netbiosFail = $true
}
else {
Write-Result `
-Name "NetBIOS adapter $index" `
-Status "WARN" `
-Details "$description -> неизвестное значение: $nbt"
}
}
if ($netbiosFail) {
Write-Result `
-Name "NetBIOS overall" `
-Status "FAIL" `
-Details "Как минимум один IP-enabled адаптер не имеет принудительного Disable NetBIOS."
}
else {
Write-Result `
-Name "NetBIOS overall" `
-Status "PASS" `
-Details "Все IP-enabled адаптеры имеют TcpipNetbiosOptions = 2."
}
}
# ============================================================
# 3. WPAD - WININET
# ============================================================
Write-Host ""
Write-Host "------------------------------------------------------------"
Write-Host "3. WPAD / WinINET"
Write-Host "------------------------------------------------------------"
$internetSettings = `
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
$autoDetect = Get-RegistryValueSafe `
-Path $internetSettings `
-Name "AutoDetect"
$autoConfigURL = Get-RegistryValueSafe `
-Path $internetSettings `
-Name "AutoConfigURL"
# AutoDetect
if ($null -eq $autoDetect) {
Write-Result `
-Name "WinINET AutoDetect" `
-Status "FAIL" `
-Details "AutoDetect отсутствует. Автоматическое обнаружение WPAD не считается отключённым."
}
elseif ([int]$autoDetect -eq 0) {
Write-Result `
-Name "WinINET AutoDetect" `
-Status "PASS" `
-Details "AutoDetect = 0"
}
else {
Write-Result `
-Name "WinINET AutoDetect" `
-Status "FAIL" `
-Details "AutoDetect = $autoDetect"
}
# PAC URL
if ([string]::IsNullOrEmpty($autoConfigURL)) {
Write-Result `
-Name "Explicit PAC URL" `
-Status "PASS" `
-Details "AutoConfigURL отсутствует."
}
else {
Write-Result `
-Name "Explicit PAC URL" `
-Status "WARN" `
-Details "Найден AutoConfigURL: $autoConfigURL"
}
# ============================================================
# 4. WPAD - WINHTTP
# ============================================================
Write-Host ""
Write-Host "------------------------------------------------------------"
Write-Host "4. WPAD / WinHTTP"
Write-Host "------------------------------------------------------------"
$winhttpPath = `
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp"
$disableWpad = Get-RegistryValueSafe `
-Path $winhttpPath `
-Name "DisableWpad"
if ($null -eq $disableWpad) {
# На Windows 7 этого параметра может вообще не быть.
Write-Result `
-Name "WinHTTP DisableWpad" `
-Status "WARN" `
-Details "DisableWpad отсутствует. Для Windows 7 это ожидаемо; для современных Windows 10 желательно наличие DisableWpad = 1."
}
elseif ([int]$disableWpad -eq 1) {
Write-Result `
-Name "WinHTTP DisableWpad" `
-Status "PASS" `
-Details "DisableWpad = 1"
}
else {
Write-Result `
-Name "WinHTTP DisableWpad" `
-Status "FAIL" `
-Details "DisableWpad = $disableWpad"
}
# ============================================================
# 5. WINHTTP CURRENT CONFIGURATION
# ============================================================
Write-Host ""
Write-Host "------------------------------------------------------------"
Write-Host "5. WinHTTP proxy configuration"
Write-Host "------------------------------------------------------------"
$winhttp = netsh winhttp show proxy 2>&1
$winhttpText = $winhttp -join " "
Write-Host $winhttpText
if ($winhttpText -match "Direct access") {
Write-Result `
-Name "WinHTTP proxy" `
-Status "PASS" `
-Details "WinHTTP настроен на Direct access."
}
else {
Write-Result `
-Name "WinHTTP proxy" `
-Status "WARN" `
-Details "WinHTTP имеет proxy configuration. Это не обязательно WPAD."
}
# ============================================================
# 6. DNS WPAD
# ============================================================
Write-Host ""
Write-Host "------------------------------------------------------------"
Write-Host "6. DNS WPAD"
Write-Host "------------------------------------------------------------"
if ([string]::IsNullOrEmpty($domainName)) {
Write-Result `
-Name "WPAD DNS" `
-Status "WARN" `
-Details "Не удалось определить домен."
}
else {
$wpadName = "wpad.$domainName"
Write-Host "Проверяем: $wpadName"
try {
$addresses = [System.Net.Dns]::GetHostAddresses($wpadName)
if ($addresses.Count -gt 0) {
$ips = @()
foreach ($address in $addresses) {
$ips += $address.IPAddressToString
}
Write-Result `
-Name "WPAD DNS" `
-Status "WARN" `
-Details "$wpadName разрешается: $($ips -join ', '). Наличие DNS-записи не доказывает использование WPAD."
}
else {
Write-Result `
-Name "WPAD DNS" `
-Status "PASS" `
-Details "$wpadName не разрешается."
}
}
catch {
Write-Result `
-Name "WPAD DNS" `
-Status "PASS" `
-Details "$wpadName не разрешается."
}
}
# ============================================================
# 7. NETBIOS PORTS
# ============================================================
Write-Host ""
Write-Host "------------------------------------------------------------"
Write-Host "7. NetBIOS ports"
Write-Host "------------------------------------------------------------"
# Проверяем LISTENING TCP ports 139
$tcp139 = netstat -ano -p tcp 2>$null |
Select-String "LISTENING" |
Select-String ":139"
if ($tcp139) {
Write-Result `
-Name "TCP/139" `
-Status "FAIL" `
-Details "Обнаружен listening TCP/139."
}
else {
Write-Result `
-Name "TCP/139" `
-Status "PASS" `
-Details "Listening TCP/139 не обнаружен."
}
# UDP 137/138
$udpNetbios = netstat -ano -p udp 2>$null |
Select-String ":(137|138)\s"
if ($udpNetbios) {
Write-Host $udpNetbios
Write-Result `
-Name "UDP/137-138" `
-Status "FAIL" `
-Details "Обнаружен UDP listener на NetBIOS ports."
}
else {
Write-Result `
-Name "UDP/137-138" `
-Status "PASS" `
-Details "UDP/137-138 listeners не обнаружены."
}
# ============================================================
# FINAL RESULT
# ============================================================
Write-Host ""
Write-Host "============================================================"
Write-Host " FINAL RESULT"
Write-Host "============================================================"
Write-Host ""
Write-Host "FAIL : $script:FailCount" -ForegroundColor Red
Write-Host "WARN : $script:WarnCount" -ForegroundColor Yellow
Write-Host ""
if ($script:FailCount -eq 0 -and $script:WarnCount -eq 0) {
Write-Host "RESULT: PASS" -ForegroundColor Green
Write-Host "LLMNR / NetBIOS / WPAD выглядят полностью отключенными."
}
elseif ($script:FailCount -eq 0) {
Write-Host "RESULT: PASS WITH WARNINGS" -ForegroundColor Yellow
Write-Host "Критических нарушений не обнаружено, но есть предупреждения."
}
else {
Write-Host "RESULT: FAIL" -ForegroundColor Red
Write-Host "Обнаружены настройки, которые необходимо исправить."
}
Write-Host ""