Ludus: HomeLab ve CyberRange İçin Güçlü Altyapı Çözümü
Ludus Nedir? Ludus, güvenlik profesyonelleri ve sistem yöneticileri i...
Bu PowerShell script'i, Windows 11 sistemlerinde Living Off the Land Binaries (LOLBins) olarak bilinen ve saldırganlar tarafından sıkça kötüye kullanılan Windows sistem dosyalarının giden trafiğini engelleyerek güvenliği artırmayı hedeflemektedir.
LOLBin (Living Off the Land Binary), Windows işletim sisteminde varsayılan olarak bulunan ve kötü amaçlı faaliyetler için kullanılabilen meşru programlardır. Saldırganlar bu araçları kullanarak:
# Tüm profiller için varsayılan engelleme
Set-NetFirewallProfile -Profile Domain,Private,Public `
-Enabled True `
-DefaultInboundAction Block `
-DefaultOutboundAction Allow
| LOLBin | Risk Seviyesi | Kötüye Kullanım Senaryoları |
|---|---|---|
| PowerShell.exe | ⚠️ Kritik | Malware indirme, C2 iletişimi, kod çalıştırma |
| Certutil.exe | ⚠️ Yüksek | Base64 decode, dosya indirme, sertifika manipülasyonu |
| Regsvr32.exe | ⚠️ Yüksek | Proxy execution, DLL yükleme, bypass teknikleri |
| Rundll32.exe | ⚠️ Yüksek | DLL çalıştırma, process injection |
| MSBuild.exe | ⚠️ Orta | Kod derleme ve çalıştırma |
| Wmic.exe | ⚠️ Yüksek | WMI komut çalıştırma, bilgi toplama |
| Wscript/Cscript | ⚠️ Yüksek | VBS/JS malware çalıştırma |
| BitsAdmin.exe | ⚠️ Orta | Dosya transferi, persistence |
| Curl.exe | ⚠️ Orta | Veri sızdırma, dosya indirme |
| FTP.exe | ⚠️ Düşük | Dosya transferi |
# 1. Mevcut kuralları yedekle
netsh advfirewall export "C:\Backup\firewall_backup.wfw"
# 2. Script'i test ortamında dene
# Test VM'de çalıştır ve sonuçları gözlemle
# 3. İzin verilecek sunucuları tanımla
$AllowedSMBServers = @(
"192.168.1.10", # Domain Controller
"192.168.1.20" # File Server
)
# Organizasyona özel LOLBin ekleme
$CustomLOLBins = @(
@{ Name = "Block TeamViewer"; Path = "C:\Program Files\TeamViewer\TeamViewer.exe" },
@{ Name = "Block AnyDesk"; Path = "C:\Program Files\AnyDesk\AnyDesk.exe" }
)
# Script'e ekle
foreach ($item in $CustomLOLBins) {
Ensure-ProgramBlockRule -Name $item.Name -ProgramPath $item.Path
}
# Engellenen trafiği izleme
function Get-BlockedTraffic {
$logPath = "$env:windir\system32\LogFiles\Firewall\pfirewall.log"
Get-Content $logPath -Tail 100 |
Where-Object {$_ -match "DROP"} |
ConvertFrom-Csv -Delimiter " " |
Select-Object date, time, action, protocol, src-ip, dst-ip, dst-port
}
# Rapor oluşturma
Get-BlockedTraffic |
Group-Object dst-port |
Sort-Object Count -Descending |
Select-Object Count, Name |
Export-Csv "C:\Reports\blocked_traffic.csv"
# Whitelist oluşturma
$WhitelistApps = @(
"C:\Program Files\Microsoft\Exchange Server\*",
"C:\Program Files\SQL Server\*"
)
# İstisna kuralı ekleme
foreach ($app in $WhitelistApps) {
New-NetFirewallRule -DisplayName "Allow $app" `
-Direction Outbound `
-Program $app `
-Action Allow `
-Priority 1
}
# Güvenilir host'lar için izin
$TrustedHosts = @("10.0.0.5", "10.0.0.10")
foreach ($host in $TrustedHosts) {
New-NetFirewallRule -DisplayName "Allow PowerShell to $host" `
-Direction Outbound `
-Program "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe" `
-RemoteAddress $host `
-Action Allow
}
# WDAC politikası oluşturma
New-CIPolicy -Level Publisher `
-FilePath ".\WDAC-Policy.xml" `
-UserPEs `
-Deny "C:\Windows\System32\certutil.exe"
# Kural sayısını kontrol et
(Get-NetFirewallRule | Where-Object {$_.DisplayName -like "W11-HARDENING*"}).Count
# Performans metrikleri
Measure-Command {
Get-NetFirewallRule | Where-Object {$_.Enabled -eq $true}
} | Select-Object TotalMilliseconds
# Optimize edilmiş kural gruplaması
# Tek tek kural yerine grup halinde uygulama
$LOLBinPaths = @(
"$env:windir\System32\certutil.exe",
"$env:windir\System32\regsvr32.exe",
"$env:windir\System32\rundll32.exe"
)
New-NetFirewallRule -DisplayName "Block All LOLBins" `
-Direction Outbound `
-Program $LOLBinPaths `
-Action Block
# Test senaryoları
function Test-LOLBinBlocking {
$tests = @{
"Certutil" = { certutil.exe -urlcache -f http://example.com/test.txt }
"PowerShell" = { Invoke-WebRequest -Uri http://example.com }
"BitsAdmin" = { bitsadmin /transfer test http://example.com/file C:\temp\file }
}
foreach ($test in $tests.GetEnumerator()) {
try {
& $test.Value
Write-Host "❌ $($test.Key) - BLOCKED FAILED" -ForegroundColor Red
} catch {
Write-Host "✅ $($test.Key) - Successfully Blocked" -ForegroundColor Green
}
}
}
Kademeli Dağıtım
Düzenli Güncelleme
Kompansatuar Kontroller
Bu script, Defense in Depth stratejisinin önemli bir parçasıdır ve:
Kritik Not: Script'i uygulamadan önce mutlaka:
Bu yaklaşım, özellikle Zero Trust mimarisi benimseyen organizasyonlar için güçlü bir güvenlik katmanı sağlamaktadır.
<#
.SYNOPSIS
Windows 11 Pro Firewall Hardening Script
.DESCRIPTION
Implements firewall hardening recommendations:
- Secure profile defaults (Domain/Private/Public)
- Block high-risk inbound ports (SMB, RDP, WinRM, WMI/DCOM, discovery protocols)
- Restrict outbound SMB to approved servers
- Block outbound traffic from commonly abused Windows binaries (LOLBins)
- Disable local firewall rule overrides
.NOTES
Run as Administrator.
Test in a lab before broad deployment.
#>
$ErrorActionPreference = "Stop"
# ============================
# CONFIGURABLE SETTINGS
# ============================
# List of file servers allowed to receive outbound SMB (TCP 445) from this workstation.
# Use IP addresses or CIDR ranges. Leave empty to block all outbound SMB. Include Domain Controllers and File Servers here:
$AllowedSMBServers = @(
# "192.168.10.10",
# "10.0.0.5"
)
# Whether to block inbound RDP (recommended unless you explicitly use RDP to this PC)
$BlockRDPInbound = $true
# Name prefix for all rules this script manages
$RulePrefix = "W11-HARDEN - "
# ============================
# HELPER FUNCTIONS
# ============================
function Set-FirewallProfileSecure {
param(
[Parameter(Mandatory)][ValidateSet("Domain","Private","Public")]
[string]$ProfileName
)
Write-Host "Configuring firewall profile: $ProfileName"
Set-NetFirewallProfile -Profile $ProfileName `
-Enabled True `
-DefaultInboundAction Block `
-DefaultOutboundAction Allow `
-NotifyOnListen False `
-AllowLocalFirewallRules False `
-AllowLocalIPsecRules False `
-Verbose:$false
}
function Ensure-PortRule {
param(
[Parameter(Mandatory)][string]$Name,
[Parameter(Mandatory)][ValidateSet("Inbound","Outbound")][string]$Direction,
[Parameter(Mandatory)][ValidateSet("Allow","Block")][string]$Action,
[Parameter(Mandatory)][string]$Protocol,
[Parameter()][string]$LocalPort = "",
[Parameter()][string]$RemotePort = "",
[Parameter()][string]$RemoteAddress = "Any"
)
$displayName = "$RulePrefix$Name"
$existing = Get-NetFirewallRule -DisplayName $displayName -ErrorAction SilentlyContinue
$baseParams = @{
DisplayName = $displayName
Direction = $Direction
Action = $Action
Enabled = 'True'
Profile = 'Any'
}
if ($existing) {
Write-Host "Updating rule: $displayName"
Set-NetFirewallRule -DisplayName $displayName @baseParams -ErrorAction SilentlyContinue | Out-Null
# Update port filter
$filterParams = @{
Protocol = $Protocol
}
if ($LocalPort) { $filterParams.LocalPort = $LocalPort }
if ($RemotePort) { $filterParams.RemotePort = $RemotePort }
Get-NetFirewallRule -DisplayName $displayName |
Set-NetFirewallPortFilter @filterParams -ErrorAction SilentlyContinue | Out-Null
# Update remote address if applicable
if ($RemoteAddress -and $RemoteAddress -ne "Any") {
Set-NetFirewallRule -DisplayName $displayName -RemoteAddress $RemoteAddress | Out-Null
} else {
Set-NetFirewallRule -DisplayName $displayName -RemoteAddress Any | Out-Null
}
}
else {
Write-Host "Creating rule: $displayName"
$newParams = $baseParams.Clone()
$newParams["Protocol"] = $Protocol
if ($LocalPort) { $newParams["LocalPort"] = $LocalPort }
if ($RemotePort) { $newParams["RemotePort"] = $RemotePort }
if ($RemoteAddress) { $newParams["RemoteAddress"] = $RemoteAddress }
New-NetFirewallRule @newParams | Out-Null
}
}
function Ensure-ProgramBlockRule {
param(
[Parameter(Mandatory)][string]$Name,
[Parameter(Mandatory)][string]$ProgramPath
)
if (-not (Test-Path $ProgramPath)) {
Write-Host "Skipping (file not found): $ProgramPath"
return
}
$displayName = "$RulePrefix$Name"
$existing = Get-NetFirewallRule -DisplayName $displayName -ErrorAction SilentlyContinue
if ($existing) {
Write-Host "Updating program block rule: $displayName"
Set-NetFirewallRule -DisplayName $displayName `
-Direction Outbound `
-Action Block `
-Enabled True `
-Profile Any `
-Program $ProgramPath | Out-Null
}
else {
Write-Host "Creating program block rule: $displayName"
New-NetFirewallRule -DisplayName $displayName `
-Direction Outbound `
-Action Block `
-Enabled True `
-Profile Any `
-Program $ProgramPath | Out-Null
}
}
# ============================
# 1. SECURE FIREWALL PROFILES
# ============================
Set-FirewallProfileSecure -ProfileName Domain
Set-FirewallProfileSecure -ProfileName Private
Set-FirewallProfileSecure -ProfileName Public
# Enable basic logging (you can adjust paths/sizes as needed)
Write-Host "Enabling firewall logging..."
Set-NetFirewallProfile -Profile Domain,Private,Public `
-LogFileName '%systemroot%\system32\LogFiles\Firewall\pfirewall.log' `
-LogMaxSizeKilobytes 16384 `
-LogAllowed True `
-LogBlocked True | Out-Null
# ============================
# 2. INBOUND HARDENING RULES
# ============================
Write-Host "`nConfiguring inbound hardening rules..."
# SMB/CIFS inbound: block
Ensure-PortRule -Name "Inbound Block SMB TCP 445" -Direction Inbound -Action Block -Protocol TCP -LocalPort 445
Ensure-PortRule -Name "Inbound Block SMB TCP 139" -Direction Inbound -Action Block -Protocol TCP -LocalPort 139
Ensure-PortRule -Name "Inbound Block NetBIOS UDP 137" -Direction Inbound -Action Block -Protocol UDP -LocalPort 137
Ensure-PortRule -Name "Inbound Block NetBIOS UDP 138" -Direction Inbound -Action Block -Protocol UDP -LocalPort 138
# RDP inbound (TCP 3389)
if ($BlockRDPInbound) {
Ensure-PortRule -Name "Inbound Block RDP TCP 3389" -Direction Inbound -Action Block -Protocol TCP -LocalPort 3389
}
# WinRM inbound (5985/5986)
Ensure-PortRule -Name "Inbound Block WinRM TCP 5985" -Direction Inbound -Action Block -Protocol TCP -LocalPort 5985
Ensure-PortRule -Name "Inbound Block WinRM TCP 5986" -Direction Inbound -Action Block -Protocol TCP -LocalPort 5986
# WMI/DCOM RPC endpoint (TCP 135)
Ensure-PortRule -Name "Inbound Block RPC Endpoint Mapper TCP 135" -Direction Inbound -Action Block -Protocol TCP -LocalPort 135
# Discovery / legacy protocols
Ensure-PortRule -Name "Inbound Block SSDP UDP 1900" -Direction Inbound -Action Block -Protocol UDP -LocalPort 1900
Ensure-PortRule -Name "Inbound Block mDNS UDP 5353" -Direction Inbound -Action Block -Protocol UDP -LocalPort 5353
Ensure-PortRule -Name "Inbound Block LLMNR UDP 5355" -Direction Inbound -Action Block -Protocol UDP -LocalPort 5355
Ensure-PortRule -Name "Inbound Block WSD UDP 3702" -Direction Inbound -Action Block -Protocol UDP -LocalPort 3702
Ensure-PortRule -Name "Inbound Block TFTP UDP 69" -Direction Inbound -Action Block -Protocol UDP -LocalPort 69
# (Optional) ICMP echo blocking could be added here if desired.
# ============================
# 3. OUTBOUND SMB RESTRICTIONS
# ============================
Write-Host "`nConfiguring outbound SMB controls..."
# Allow outbound SMB only to approved servers
if ($AllowedSMBServers.Count -gt 0) {
foreach ($server in $AllowedSMBServers) {
Ensure-PortRule -Name "Outbound Allow SMB to $server" `
-Direction Outbound -Action Allow -Protocol TCP -RemotePort 445 -RemoteAddress $server
}
}
# Block all other outbound SMB
Ensure-PortRule -Name "Outbound Block SMB TCP 445 All" `
-Direction Outbound -Action Block -Protocol TCP -RemotePort 445 -RemoteAddress "Any"
# ============================
# 4. OUTBOUND DISCOVERY / LEGACY PROTOCOL BLOCKS
# ============================
Write-Host "`nConfiguring outbound discovery protocol blocks..."
Ensure-PortRule -Name "Outbound Block SSDP UDP 1900" -Direction Outbound -Action Block -Protocol UDP -RemotePort 1900
Ensure-PortRule -Name "Outbound Block mDNS UDP 5353" -Direction Outbound -Action Block -Protocol UDP -RemotePort 5353
Ensure-PortRule -Name "Outbound Block LLMNR UDP 5355" -Direction Outbound -Action Block -Protocol UDP -RemotePort 5355
Ensure-PortRule -Name "Outbound Block WSD UDP 3702" -Direction Outbound -Action Block -Protocol UDP -RemotePort 3702
Ensure-PortRule -Name "Outbound Block TFTP UDP 69" -Direction Outbound -Action Block -Protocol UDP -RemotePort 69
# ============================
# 5. OUTBOUND PROGRAM-LEVEL BLOCKS (LOLBINS)
# ============================
Write-Host "`nConfiguring outbound program-level blocks (LOLBins)..."
$system32 = Join-Path $env:WINDIR "System32"
$syswow64 = Join-Path $env:WINDIR "SysWOW64"
$psv1Path = Join-Path $system32 "WindowsPowerShell\v1.0"
$pswowv1 = Join-Path $syswow64 "WindowsPowerShell\v1.0"
$ProgramBlockList = @(
# PowerShell
@{ Name = "Block Outbound PowerShell (x64)"; Path = Join-Path $psv1Path "powershell.exe" },
@{ Name = "Block Outbound PowerShell ISE (x64)"; Path = Join-Path $psv1Path "powershell_ise.exe" },
@{ Name = "Block Outbound PowerShell (x86)"; Path = Join-Path $pswowv1 "powershell.exe" },
@{ Name = "Block Outbound PowerShell ISE (x86)"; Path = Join-Path $pswowv1 "powershell_ise.exe" },
# Windows scripting
@{ Name = "Block Outbound wscript"; Path = Join-Path $system32 "wscript.exe" },
@{ Name = "Block Outbound cscript"; Path = Join-Path $system32 "cscript.exe" },
@{ Name = "Block Outbound mshta"; Path = Join-Path $system32 "mshta.exe" },
# Downloaders / transfer tools
@{ Name = "Block Outbound certutil"; Path = Join-Path $system32 "certutil.exe" },
@{ Name = "Block Outbound bitsadmin"; Path = Join-Path $system32 "bitsadmin.exe" },
@{ Name = "Block Outbound curl"; Path = Join-Path $system32 "curl.exe" },
@{ Name = "Block Outbound ftp"; Path = Join-Path $system32 "ftp.exe" },
@{ Name = "Block Outbound tftp"; Path = Join-Path $system32 "tftp.exe" },
# WMI and management
@{ Name = "Block Outbound wmic"; Path = Join-Path $system32 "wbem\wmic.exe" },
# LOLBins commonly abused for code execution
@{ Name = "Block Outbound regsvr32"; Path = Join-Path $system32 "regsvr32.exe" },
@{ Name = "Block Outbound rundll32"; Path = Join-Path $system32 "rundll32.exe" },
# Dev / build tools
@{ Name = "Block Outbound MSBuild"; Path = Join-Path $system32 "MSBuild.exe" },
@{ Name = "Block Outbound msxsl"; Path = Join-Path $system32 "msxsl.exe" },
# Injection & remote tools
@{ Name = "Block Outbound mavinject"; Path = Join-Path $system32 "mavinject.exe" },
# Remote admin / post-ex tools (if present)
@{ Name = "Block Outbound PsExec"; Path = "C:\Windows\System32\psexec.exe" },
@{ Name = "Block Outbound PAExec"; Path = "C:\Windows\System32\paexec.exe" },
# Quick Assist (if present)
@{ Name = "Block Outbound Quick Assist"; Path = Join-Path $system32 "quickassist.exe" }
)
foreach ($item in $ProgramBlockList) {
Ensure-ProgramBlockRule -Name $item.Name -ProgramPath $item.Path
}
Write-Host "`nFirewall hardening complete." -ForegroundColor Green