Hướng dẫn tự động chặn brute force RDP bằng PowerShell

Tác giả: Trần Thảo 11 tháng 07, 2026

Đang nửa đêm, hệ thống monitoring gửi cảnh báo báo CPU máy chủ Windows Server chạm mốc 100%. Bạn truy cập remote vào server, các thao tác bắt đầu có độ trễ lớn. Mở Task Manager lên, không có ứng dụng nào đang chạy nặng, nhưng tài nguyên đã cạn kiệt. Cố gắng mở Event Viewer, ứng dụng lập tức treo cứng (Not Responding) vì file Security Log đã phình to lên đến hàng Gigabyte. Nguyên nhân chính là mạng lưới botnet bên ngoài đang liên tục dội hàng trăm request mỗi giây vào cổng 3389 để dò quét mật khẩu.

Nhiều sysadmin vội vàng tìm tải các phần mềm chống brute force của bên thứ ba. Tuy nhiên, cài thêm phần mềm đôi khi lại rước thêm rủi ro xung đột hệ thống, hoặc công cụ lại tiêu tốn RAM không kém gì chính botnet. Thay vì phụ thuộc vào ứng dụng ngoài, chúng ta hoàn toàn có thể tận dụng sức mạnh nội tại của hệ điều hành. Làm thế nào để xây dựng một kịch bản chặn brute force RDP bằng PowerShell chạy ngầm 24/7, tối ưu tài nguyên mà không làm tê liệt máy chủ? Thuật toán nào giúp phân biệt chính xác botnet và người dùng hợp lệ?

Cùng phân tích sâu kỹ thuật này tới tận nhân hệ thống (kernel) ngay trong bài viết dưới đây.

Nỗi ám ảnh mang tên CPU spike khi server bị botnet càn quét RDP

Nhiều quản trị viên hệ thống thường thắc mắc: Chỉ là gửi vài request sai mật khẩu, sao VPS lại bị vắt kiệt CPU đến mức ngừng hoạt động các dịch vụ đang chạy?

Vấn đề này không nằm ở lượng băng thông mạng, mà xuất phát từ cơ chế khởi tạo giao diện đồ họa của hệ điều hành.

Cụ thể, đối với các máy chủ chưa được bật tính năng NLA (Network Level Authentication) hoặc bị cấu hình bypass NLA, với mỗi một yêu cầu kết nối RDP chạm vào cổng 3389, máy chủ sẽ phải khởi chạy tiến trình LogonUI.exe và render toàn bộ giao diện màn hình đăng nhập truyền về cho phía client. Việc này diễn ra trước cả khi quá trình nhập mật khẩu thực sự bắt đầu.

Việc liên tục khởi tạo các session đồ họa mới là một tiến trình tiêu tốn rất nhiều tài nguyên. Trong thực tế vận hành, chỉ cần một mạng lưới botnet cơ bản gửi 1 request mỗi 4 giây, nó đã đủ sức tiêu tốn 50% CPU của một VPS cấu hình tiêu chuẩn. Khi kết hợp hàng trăm IP tấn công cùng lúc, cuộc rà quét mật khẩu (brute-force) bỗng chốc biến thành một cuộc tấn công từ chối dịch vụ (DoS), làm tê liệt hoàn toàn máy chủ.

Đồ thị minh họa CPU Server quá tải do tiến trình LogonUI.exe khi bị botnet tấn công brute force RDP và vai trò của NLA.

Minh họa sự khác biệt về tiêu hao tài nguyên CPU trên máy chủ khi tắt và bật tính năng NLA (Network Level Authentication).

Nếu bạn muốn tìm hiểu cách thiết lập chuẩn ngay từ đầu, hãy tham khảo hướng dẫn cấu hình VPS Windows làm máy trạm (Remote Desktop) với hiệu suất cao và chuẩn bảo mật.

Bóc tách Event ID 4625: Giải oan cho Logon Type 10

Để chặn chính xác IP độc hại bằng script, chúng ta cần phải hiểu rõ cấu trúc nhật ký của Windows. Khi một kết nối nhập sai mật khẩu, hệ thống sẽ ghi nhận một sự kiện bảo mật mang mã Event ID 4625 (An account failed to log on).

Tuy nhiên, điểm hạn chế của 90% các đoạn script chia sẻ trên mạng là chúng chỉ tập trung lọc Logon Type 10.

Bản chất kỹ thuật:

  • Logon Type 10 (RemoteInteractive): Chỉ xuất hiện khi NLA (Network Level Authentication) bị tắt hoặc trên các máy chủ Windows phiên bản cũ (2008 trở xuống). Kẻ tấn công chạm được vào giao diện đồ họa và nhập sai mật khẩu.
  • Logon Type 3 (Network): Đây mới là nguyên nhân chính trong môi trường hiện đại. Trên Windows Server 2012, 2016, 2019, 2022 và 2025, NLA được bật mặc định. Quá trình xác thực diễn ra ở cấp độ mạng (Network Level) trước khi tải giao diện. Do đó, khi botnet tấn công một server có NLA, hệ thống sẽ ghi nhận đây là thất bại mạng (Type 3) thay vì Type 10.

Nếu kịch bản của bạn chỉ lọc Logon Type 10, hệ thống sẽ bỏ lọt 90% lượng traffic tấn công mạng hiện đại.

Tất nhiên, Event 4625 còn chứa nhiều Type khác do lỗi cấu hình nội bộ mà ta cần loại trừ:

  • Type 2 (Interactive): Đăng nhập vật lý trực tiếp tại bàn phím Server.
  • Type 4 & 5 (Batch & Service): Lỗi từ Scheduled Tasks hoặc các Windows Services nội bộ chạy sai thông tin xác thực.

Kết luận: Script chuẩn phải bao gồm cả Logon Type 3 và 10, đồng thời loại trừ các IP nội bộ (localhost).

Phân biệt Logon Type 3 và Logon Type 10 trong Event ID 4625 khi máy chủ bị dò quét mật khẩu RDP.

Bản chất sự khác biệt giữa Logon Type 3 và Logon Type 10 dựa trên cơ chế xác thực NLA của Windows Server.

4 sai lầm ngốn RAM khi tự viết script đọc Security Log

Thay vì sử dụng trực tiếp các mã nguồn chưa được kiểm chứng, một quản trị viên hệ thống cần tránh ngay 4 vấn đề tiêu hao tài nguyên sau đây:

Dùng lệnh Get-EventLog (công nghệ legacy)

Lệnh này sử dụng các API cũ của Windows. Nó hoạt động chậm và không được Microsoft khuyến nghị cho các file log có dung lượng lớn. Thay vào đó, quản trị viên cần sử dụng Get-WinEvent.

Dùng ống dẫn (pipeline) Where-Object

Viết script theo cú pháp Get-WinEvent -LogName Security | Where-Object {$_.ID -eq 4625} là một phương pháp thiếu tối ưu. PowerShell sẽ phải nạp toàn bộ hàng chục GB dữ liệu log vào bộ nhớ RAM trước khi tiến hành lọc. Hậu quả là VPS có thể bị treo ngay lập tức.

Parse XML trong vòng lặp (lỗi chí mạng nhất)

Nhập môn PowerShell thường chỉ cách lấy địa chỉ IP bằng cách ép kiểu XML: [xml]$xml = $event.ToXml() rồi dò tìm thẻ IpAddress. Việc khởi tạo cây DOM (Document Object Model) cho định dạng XML trên hàng ngàn dòng log là một tác vụ tiêu tốn rất nhiều chu kỳ CPU.

Giải pháp tối ưu: Trong môi trường PowerShell hiện đại, Event Log trả về thuộc tính .Properties dưới dạng mảng (Array). Theo cấu trúc của Event 4625, địa chỉ IP (Source Network Address) luôn nằm ở vị trí thứ 20, tức là index [19]. Lấy trực tiếp $event.Properties[19].Value sẽ cho tốc độ truy xuất nhanh hơn đáng kể so với việc parse XML.

Mỗi IP tạo 1 Firewall Rule (làm rác tường lửa)

Kẻ tấn công thường sử dụng hàng nghìn IP khác nhau. Nếu script cứ gặp 1 IP xấu lại chạy lệnh New-NetFirewallRule, sau một thời gian, Windows Firewall của hệ thống sẽ chứa hàng chục nghìn rule đơn lẻ. Điều này khiến việc mở giao diện Advanced Security bị chậm trễ nghiêm trọng.

Để quản lý tường lửa một cách tối ưu, bạn nên tham khảo bài viết về cách cấu hình Windows Firewall bằng PowerShell hàng loạt để dễ dàng mở port và chặn đứng các IP độc hại.

Từng bước xây dựng kịch bản chặn brute force RDP bằng PowerShell

Sau khi đã nắm vững cơ chế kỹ thuật, chúng ta sẽ bắt tay vào xây dựng kịch bản tự động hóa với 4 bước cốt lõi.

Bước 1: Lọc log siêu tốc bằng -FilterXPath

Nguyên tắc quan trọng nhất là Filter Left (Lọc dữ liệu từ nguồn). Ta sẽ đẩy bộ truy vấn XPath xuống thẳng nhân Windows Event Log Service. Hệ thống sẽ tự xử lý bằng C++ ở tầng thấp và chỉ trả về cho PowerShell những dòng log thỏa mãn điều kiện: Sự kiện 4625 + Xảy ra trong 15 phút qua + Logon Type là 3 hoặc 10.

Bước 2: Bóc tách IP và đếm số lượng (Threshold)

Duyệt qua các log trả về, sử dụng kỹ thuật .Properties[19].Value để lấy IP. Đưa chúng vào một Hashtable ($IpCounts) để cộng dồn số lần đăng nhập thất bại. Nếu IP nào nhập sai mật khẩu vượt ngưỡng 5 hoặc 10 lần, hệ thống sẽ đưa vào danh sách chặn.

Bước 3: Lập whitelist chống tự hủy

Luôn cần thiết lập một danh sách an toàn để bảo vệ quyền truy cập của quản trị viên:

  • IP 127.0.0.1::1 (Localhost).
  • IP rỗng hoặc -.
  • IP VPN của hệ thống nội bộ hoặc dải mạng LAN (ví dụ: 192.168.0.0/16).
  • IP 255.255.255.254 (IP giữ chỗ, thành phần quan trọng cho thuật toán ở bước 4).

Bước 4: Thuật toán gom IP (Chunking) vào chung Firewall Rule

Bản chất Windows Firewall cho phép nạp một mảng (Array) hàng trăm địa chỉ IP vào chung một Rule thông qua tham số -RemoteAddress. Tuy nhiên, giới hạn cứng của Microsoft là 1.000 IP cho một Rule.

Thuật toán phân nhóm (Chunking) hoạt động như sau:

  • Gọi Rule số 1 (RDP-Blocker_1). Trích xuất mảng IP đang bị chặn hiện tại.
  • Nếu số lượng IP trong Rule 1 < 1000: Nối thêm IP độc hại mới vào mảng và ghi đè lại Rule bằng Set-NetFirewallRule.
  • Nếu số lượng IP trong Rule 1 >= 1000: Script tự động tăng biến index, tạo Rule số 2 (RDP-Blocker_2), đưa IP giữ chỗ (255.255.255.254) vào để khởi tạo, sau đó nạp IP độc hại vào Rule 2.

Với phương pháp này, việc chặn 10.000 IP độc hại chỉ yêu cầu khoảng 10 Firewall Rule gọn gàng trong hệ thống.

Thuật toán Chunking gom tối đa 1000 địa chỉ IP độc hại vào chung một Rule trên Windows Firewall bằng PowerShell.

Thuật toán phân trang (Chunking) giúp gom hàng ngàn IP độc hại vào số lượng Firewall Rule ít nhất, chống suy giảm hiệu suất hệ thống.

Toàn bộ source code chống brute force (bản chuẩn production)

Dưới đây là mã nguồn PowerShell đã được tối ưu hóa hiệu năng, sử dụng XPath (bắt Type 3 & 10) và xử lý mảng IP tốc độ cao. Bạn hãy sao chép và lưu file này thành C:\Scripts\AutoBlock-RDP.ps1.

<#
.SYNOPSIS
    Kịch bản chặn brute force RDP bằng PowerShell - Phiên bản chuẩn Production (Tối ưu RAM/CPU).
.DESCRIPTION
    - Bắt cả Logon Type 3 (NLA) và Type 10.
    - Truy xuất IP tốc độ cao qua mảng Properties[19] thay vì ép kiểu XML.
    - Dùng thuật toán Array Append để gom tối đa 1000 IP vào 1 Firewall Rule.
#>

# ================= CẤU HÌNH =================
$Threshold = 10              # Khóa IP sau 10 lần sai
$WindowMinutes = 15          # Quét lùi lại 15 phút (Chạy task tương ứng 15p/lần)
$RulePrefix = "RDP-Blocker"
$LogPath = "C:\Scripts\BlockRDP_Log.txt"

# Khởi tạo Whitelist (Cập nhật theo dải IP quản trị của hệ thống)
$Whitelist = @("127.0.0.1", "::1", "255.255.255.254", "10.0.0.0/8", "192.168.0.0/16")

# Thư mục chứa script
$ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
if (!(Test-Path $ScriptDir)) { New-Item -ItemType Directory -Force -Path $ScriptDir | Out-Null }

Function Write-Log ($Message) {
    $time = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    "$time - $Message" | Out-File -FilePath $LogPath -Append -Encoding UTF8
    Write-Host "$time - $Message" -ForegroundColor Yellow
}

Write-Log "Bắt đầu rà soát Security Log ($WindowMinutes phút qua)..."

# ================= 1. TRUY VẤN XPATH =================
# Bắt Event 4625, giới hạn thời gian, và lấy cả Logon Type 10 VÀ Logon Type 3
$xpath = "*[System[(EventID=4625) and TimeCreated[timediff(@SystemTime) <= $($WindowMinutes * 60000)]]] and *[EventData[Data[@Name='LogonType']='10' or Data[@Name='LogonType']='3']]"

$events = Get-WinEvent -LogName Security -FilterXPath $xpath -ErrorAction SilentlyContinue

if (-not $events) { 
    Write-Log "Hệ thống an toàn. Không phát hiện rà quét RDP."
    exit 0 
}

# ================= 2. ĐẾM SỐ LẦN SAI & TRÍCH XUẤT IP =================
$IpCounts = @{}

foreach ($event in $events) {
    # Truy xuất qua mảng thay vì Parse XML
    # Cấu trúc Event 4625: Source Network Address thường nằm ở Index 19
    if ($event.Properties.Count -ge 20) {
        $ip = $event.Properties[19].Value
        
        if (-not [string]::IsNullOrWhiteSpace($ip) -and $ip -ne "-" -and $ip -ne "::1") {
            $IpCounts[$ip]++
        }
    }
}

# ================= 3. LỌC WHITELIST & TÌM IP VƯỢT NGƯỠNG =================
$IPsToBlock = @()

foreach ($ip in $IpCounts.Keys) {
    if ($IpCounts[$ip] -ge $Threshold) {
        $isWhite = $false
        foreach ($w in $Whitelist) { 
            if ($ip -like $w) { $isWhite = $true; break } 
        }
        if (-not $isWhite) { $IPsToBlock += $ip }
    }
}

if ($IPsToBlock.Count -eq 0) { 
    Write-Log "Có IP dò mật khẩu nhưng nằm trong Whitelist hoặc chưa vượt ngưỡng ($Threshold)."
    exit 0 
}

# ================= 4. THUẬT TOÁN GOM RULE FIREWALL (CHUNKING) =================
$MaxIpsPerRule = 1000
$RuleIndex = 1
$BlockedCount = 0

foreach ($badIp in $IPsToBlock) {
    $RuleName = "${RulePrefix}_${RuleIndex}"
    $Rule = Get-NetFirewallRule -DisplayName $RuleName -ErrorAction SilentlyContinue

    if (-not $Rule) {
        # Tạo rule mới với IP giữ chỗ 255.255.255.254
        New-NetFirewallRule -DisplayName $RuleName -Direction Inbound -Action Block -Protocol TCP -LocalPort 3389 -RemoteAddress "255.255.255.254" -Description "Auto RDP Blocker by PowerShell" | Out-Null
        $CurrentIPs = @("255.255.255.254")
    } else {
        # Lấy danh sách IP hiện tại trong Rule
        $CurrentIPs = @((Get-NetFirewallAddressFilter -AssociatedNetFirewallRule $Rule).RemoteAddress)
    }

    if ($CurrentIPs -notcontains $badIp) {
        if ($CurrentIPs.Count -ge $MaxIpsPerRule) {
            # Rule đã đạt giới hạn 1000 IP -> Tăng index để sang vòng lặp sau tạo Rule mới
            $RuleIndex++
            continue 
        }
        $CurrentIPs += $badIp
        # Ghi đè mảng IP mới vào Firewall Rule
        Set-NetFirewallRule -DisplayName $RuleName -RemoteAddress $CurrentIPs | Out-Null
        Write-Log "Đã chặn IP: $badIp (Số lần thử: $($IpCounts[$badIp])) -> Đưa vào $RuleName"
        $BlockedCount++
    }
}

Write-Log "Hoàn tất xử lý. Đã thêm $BlockedCount IP mới vào danh sách chặn."

Bonus: Cơ chế ân xá (unban) xóa IP khỏi Firewall sau 7 ngày

Kẻ tấn công thường sử dụng mạng botnet với IP động (Dynamic IP) hoặc proxy thay đổi liên tục. Nếu script của bạn chạy 24/7 trong 1 năm, danh sách IP bị chặn có thể lên tới hàng trăm ngàn. Việc giữ các rule này vĩnh viễn không mang lại lợi ích bảo mật mà chỉ làm phình to bảng định tuyến mạng của Windows Server, làm chậm quá trình xử lý packet hợp lệ.

Do đó, một hệ thống đạt chuẩn luôn cần cơ chế Gỡ chặn (Amnesty) tương tự như Fail2Ban trên Linux.

Bạn có thể lưu đoạn code dưới đây thành C:\Scripts\Unban-RDP.ps1 và thiết lập một Task Scheduler chạy 1 lần mỗi tuần (vào Chủ Nhật). Kịch bản này sẽ tìm các Firewall Rule do script chống brute force tạo ra, kiểm tra tuổi đời của rule, nếu quá 7 ngày thì xóa bỏ để giải phóng Firewall.

# Số ngày duy trì trạng thái Block (Sau 7 ngày sẽ gỡ chặn)
$DaysToUnban = 7
$Prefix = "RDP-Blocker_*"

Write-Host "Đang rà soát các Rule cũ..."

# Tìm các Rule có tên chứa RDP-Blocker_ và có thời gian tạo cũ hơn 7 ngày
$OldRules = Get-NetFirewallRule -DisplayName $Prefix | Where-Object {
    $_.CreationTime -lt (Get-Date).AddDays(-$DaysToUnban) 
}

if ($OldRules) {
    # Xóa toàn bộ Rule cũ
    $OldRules | Remove-NetFirewallRule -ErrorAction SilentlyContinue
    Write-Host "Đã gỡ chặn và xóa bỏ $($OldRules.Count) Rule Firewall quá hạn để giải phóng hệ thống." -ForegroundColor Green
} else {
    Write-Host "Không có Rule nào vượt quá $DaysToUnban ngày cần xóa." -ForegroundColor Yellow
}

Triển khai Task Scheduler: Chạy ngầm và bền bỉ 24/7

Để tự động hóa hoàn toàn, chúng ta sẽ thiết lập Task Scheduler. Tuy nhiên, trên Windows Server 2019 hoặc 2022, có một lỗi hệ thống (bug) cần lưu ý: Nếu bạn cấu hình Trigger dạng “Daily” (Hằng ngày) và lặp lại “Indefinitely” (Vô thời hạn), task sẽ chỉ cập nhật thời gian “Next Run” mà không thực thi script.

Dưới đây là cách cấu hình Task Scheduler chuẩn kỹ thuật để tránh lỗi này và giúp tiến trình PowerShell chạy hoàn toàn ẩn ở Session 0:

1. Thẻ General (Quyền thực thi):

  • Chọn Run whether user is logged on or not.
  • Đánh dấu Run with highest privileges.
  • Tại mục User Account, thay đổi thành SYSTEM. Việc chạy dưới quyền SYSTEM giúp tác vụ không bị gián đoạn hay mất quyền ngay cả khi Administrator thay đổi mật khẩu đăng nhập.

2. Thẻ Triggers (Lập lịch chuẩn xác):

  • Begin the task: Chọn On a schedule -> One time (Không chọn Daily).
  • Advanced settings: Tích chọn Repeat task every 15 minutes.
  • For a duration of: Chọn Indefinitely (Vô thời hạn).

3. Thẻ Actions (Gọi trình thông dịch):

  • Action: Start a program
  • Program/script: powershell.exe
  • Add arguments: Nhập chuỗi tham số sau: -NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File "C:\Scripts\AutoBlock-RDP.ps1" (Tham số -NoProfile giúp script khởi động nhanh hơn, -NonInteractive ngăn chặn việc treo tiến trình nếu script yêu cầu nhập liệu).

4. Thẻ Settings (Kiểm soát tiến trình):

  • Bỏ chọn mục Start the task only if the computer is on AC power (trong thẻ Conditions).
  • Tại mục If the task is already running…, bắt buộc chọn Do not start a new instance. Nếu vì lý do nào đó server chịu tải cao khiến script chạy quá 15 phút chưa hoàn thành, Task Scheduler sẽ không khởi tạo thêm các instance đè lên nhau gây cạn kiệt RAM.
Hướng dẫn cấu hình Task Scheduler chạy ngầm định kỳ kịch bản PowerShell bảo mật để né bug của Windows Server.

Thiết lập vòng lặp One time + Indefinitely là giải pháp kỹ thuật để tránh lỗi treo Task Scheduler trên Windows Server 2019/2022.

Nếu bạn muốn áp dụng thêm các công cụ tự động hóa khác để bảo vệ máy chủ, hãy tham khảo Cẩm nang 10 scripts PowerShell quản trị VPS Windows Server 2025.

Câu hỏi thường gặp (FAQ)

1. Logon Type 3 và Logon Type 10 trong Event ID 4625 khác nhau thế nào?

Logon Type 10 là kẻ tấn công đã chạm được vào giao diện đồ họa Logon UI (khi server tắt NLA). Logon Type 3 là bị chặn ngay từ lớp mạng (khi NLA được kích hoạt). Các đoạn script phổ biến thường chỉ lọc Type 10 nên bỏ lọt 90% botnet hiện đại. Script trong bài viết này bao quát cả hai.

2. Tại sao không dùng phần mềm chống brute force của bên thứ 3?

Phần mềm bên thứ 3 thường tiêu tốn RAM, có thể yêu cầu trả phí và tiềm ẩn nguy cơ xung đột hệ thống. Tận dụng PowerShell kết hợp Windows Firewall là phương pháp sử dụng công cụ tích hợp sẵn, bảo mật từ tầng Kernel, chạy ngầm ổn định và tối ưu hoàn toàn tài nguyên phần cứng.

3. Tại sao không đổi port 3389 mà phải dùng script chặn IP?

Đổi port (ví dụ: 43389) chỉ né tránh được các công cụ rà soát ngẫu nhiên (mass scan). Với đối tượng tấn công có chủ đích, họ có thể rà soát toàn bộ port bằng Nmap để tìm ra cổng mới. Đổi port là giải pháp ẩn mình thụ động, còn cấu hình PowerShell là phương án phòng thủ chủ động. Quản trị viên nên kết hợp đồng thời cả hai.

4. Kịch bản này có chặn chính IP của tôi nếu vô tình nhập sai mật khẩu không?

Có khả năng, nếu bạn nhập sai vượt ngưỡng (ví dụ: 10 lần). Tuy nhiên, kịch bản đã tích hợp sẵn cơ chế Whitelist. Quản trị viên chỉ cần khai báo IP tĩnh cá nhân, IP nội bộ công ty hoặc dải VPN vào danh sách an toàn, hệ thống sẽ tự động bỏ qua việc kiểm tra các IP này.

5. VPS của tôi RAM chỉ 1GB, chạy task kiểm tra log mỗi 15 phút có làm quá tải server không?

Hoàn toàn không. Script này không sử dụng Pipeline hay thao tác Parse XML tiêu tốn bộ nhớ. Nó ứng dụng tham số -FilterXPath để trích xuất log từ nhân hệ thống và bóc tách IP bằng Array Properties với tốc độ cao. Giải pháp này đặc biệt tối ưu cho các máy chủ có cấu hình hạn chế.

6. Làm sao để kiểm tra script đang hoạt động và xem danh sách IP bị chặn?

Bạn có thể mở file nhật ký được hệ thống tự động xuất ra tại C:\Scripts\BlockRDP_Log.txt để xem chi tiết lịch sử thực thi. Hoặc dùng PowerShell với lệnh Get-NetFirewallAddressFilter để kiểm tra trực tiếp danh sách các IP đang bị chặn bởi Firewall.

7. Kịch bản này có thể áp dụng cho máy cá nhân chạy Windows 10/11 không?

Hoàn toàn khả thi với các phiên bản Windows Pro/Enterprise có hỗ trợ Remote Desktop. Tuy nhiên, đối với thiết bị cá nhân hoặc văn phòng, phương án bảo mật an toàn nhất là không Public port RDP ra Internet qua router (NAT Port), mà nên sử dụng các mô hình mạng riêng ảo (như Tailscale, ZeroTier) để thực hiện remote an toàn.

Kết luận

Việc cấu hình và triển khai thành công kịch bản chặn brute force RDP bằng PowerShell giúp quản trị viên chủ động bảo vệ hệ thống. Giải pháp này xử lý triệt để tình trạng CPU Spike, rà soát nhật ký sự kiện chính xác và tối ưu cấu trúc của Windows Firewall ở mức cao nhất thông qua thuật toán nhóm rule (chunking).

Dù vậy, trong an toàn thông tin hệ thống, quản trị viên cần thiết lập bảo mật nhiều lớp. Sau khi cấu hình thành công script này, bạn nên triển khai thêm 3 tiêu chuẩn bảo vệ sau để ngăn chặn triệt để các rủi ro từ botnet RDP:

  1. Bảo đảm NLA luôn kích hoạt: NLA (Network Level Authentication) là lớp bảo vệ đầu tiên cần thiết lập để ngắt các kết nối mạng trái phép trước khi yêu cầu tiếp cận được giao diện đăng nhập.
  2. Thay đổi port RDP mặc định: Chuyển cổng 3389 sang một số port ngẫu nhiên ở dải cao (Ví dụ: 43389). Các công cụ rà soát diện rộng thường tập trung vào cổng 3389, việc thay đổi port sẽ giúp hệ thống giảm bớt lượng truy cập không mong muốn.
  3. Ứng dụng Mô hình VPN/Zero Trust: Đây là phương pháp tối ưu nhất. Tắt hoàn toàn RDP ở các network interface kết nối trực tiếp Internet (Public). Kỹ sư hệ thống cần kết nối vào mạng riêng ảo (như OpenVPN, WireGuard, hoặc IPsec) trước, sau đó mới tiến hành remote vào IP Local của máy chủ.

Tài liệu tham khảo