From f3fedbc61c062ec50d340ff6fe16629e37bac5eb Mon Sep 17 00:00:00 2001 From: Ttt Date: Mon, 2 Mar 2026 15:58:07 +0800 Subject: [PATCH] first commit --- rdp_login_script.ps1 | 106 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 rdp_login_script.ps1 diff --git a/rdp_login_script.ps1 b/rdp_login_script.ps1 new file mode 100644 index 0000000..51cfcfe --- /dev/null +++ b/rdp_login_script.ps1 @@ -0,0 +1,106 @@ +# ====== 配置区 ====== +$accessToken = "d28bd09159097d9cc5793a183990927ce637bd8addafb5e4586e2687ca317039" +$secret = "SECd4bf3fb7703bd2826896deefa68d579e9945a67058ee9047ac5f8757ae800729" + +$threshold = 3 # 尝试失败次数阈值 +$failCache = @{} # 失败计数缓存 + +# ====== 钉钉发送函数 ====== +function Get-Signature { + $timestamp = [DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds() + $stringToSign = "$timestamp`n$secret" + $hmac = New-Object System.Security.Cryptography.HMACSHA256 + $hmac.Key = [Text.Encoding]::UTF8.GetBytes($secret) + $hash = $hmac.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign)) + $sign = [Convert]::ToBase64String($hash) + $sign = [System.Net.WebUtility]::UrlEncode($sign) + return @{ timestamp=$timestamp; sign=$sign } +} + +function Send-DingTalk($msg) { + $signData = Get-Signature + $url = "https://oapi.dingtalk.com/robot/send?access_token=$accessToken×tamp=$($signData.timestamp)&sign=$($signData.sign)" + $body = @{ msgtype="text"; text=@{ content=$msg } } | ConvertTo-Json -Depth 5 + Invoke-RestMethod -Uri $url -Method Post -ContentType "application/json" -Body $body +} + +# ====== 封禁函数(可选) ====== +function Ban-IP($ip) { + if (-not (Get-NetFirewallRule -DisplayName "RDP_Block_$ip" -ErrorAction SilentlyContinue)) { + New-NetFirewallRule -DisplayName "RDP_Block_$ip" -Direction Inbound -RemoteAddress $ip -Action Block -Protocol TCP + } +} + +# ====== 查询日志 ====== +$query = @" + + + + + +"@ + +$events = Get-WinEvent -FilterXml $query -MaxEvents 50 + +foreach ($event in $events) { + + # 处理 LogonType + $logonTypeRaw = $event.Properties[8].Value + $logonType = 0 + + if ($logonTypeRaw -match '%%(\d+)') { + $logonType = [int]$matches[1] + } else { + $logonType = [int]$logonTypeRaw + } + + # 只处理远程登录类型(10、134、2304,2313) + if ($logonType -notin @(10, 134, 2304, 2313)) { continue } + + $user = $event.Properties[5].Value + + # 尝试多个索引获取 IP + $ip = $event.Properties[18].Value + if (-not $ip -or $ip -eq '-' -or $ip -match 'C:\\') { $ip = $event.Properties[19].Value } + if (-not $ip -or $ip -eq '-' -or $ip -match 'C:\\') { $ip = $event.Properties[20].Value } + + if (-not $ip -or $ip -eq '-') { $ip = "UNKNOWN" } + + # 输出日志 + Write-Host "RDP Failed login: $user from $ip at $($event.TimeCreated) LogonType=$logonType" + + # 累加失败次数 + # 格式化时间 + $time = $event.TimeCreated.ToString("yyyy-MM-dd HH:mm:ss") + + Write-Host "RDP Failed login: $user from $ip at $time LogonType=$logonType" + + # 累加失败次数 + if ($ip -ne "UNKNOWN") { + if (-not $failCache.ContainsKey($ip)) { + $failCache[$ip] = 1 + } else { + $failCache[$ip]++ + } + + $count = $failCache[$ip] + + if ($count -ge $threshold) { + Ban-IP $ip + # 推送钉钉(加入时间) + $msg = @" +!!!RDP Broke!!! + + IP: $ip + username: $user + failcounts: $count + time: $time + LogonType: $logonType +"@ + + Send-DingTalk $msg + + $failCache.Remove($ip) + } + } +} \ No newline at end of file