如果你跟我一樣,看完資安鬼故事開始神經兮兮兼被害妄想,三不五時懷疑「該不會有人從網路偷連我的個人電腦還渾然不知?」,這篇文章分享的小工具應該能幫助你減輕憂慮。

確認有沒有人從網路登入 Windows 的簡單方法是查詢事件檢視器的安全性事件,事件識別碼 4624 是登入成功記錄、4625 是登入失敗,事件詳細資料會包含登入帳號、來源 IP 等資訊,若發現可疑再深入追查:
(提醒:這種檢查方式只能揭露用 Windows 驗證試圖登入主機的行為,像是遠端登入、連上網路磁碟機... 等,但不包含透過木馬、後門程式建立的網路連線)

不過呢,身為大內攻城獅,這種例行檢查還一筆一筆點開來看成何體統?當然要土砲小工具自用才帥氣。

早年我曾寫過 WPF 版,不過 EXE 檔分享轉發較困難,這些年學會新兵器,就來翻寫成 PowerShell 版吧! 使用時只需複製貼上存成 ListLogonEvent.ps1 檔,程式碼直接攤在陽光下(也順便請大家 Code Review),沒有夾帶木馬或病毒的風險。在電腦上開個 【Windows PowerShell (系統管理員)】(如下圖) 或 Cmder (推薦!) 即可執行,想到就健檢一下,有機會提早抓出潛伏的歹咪呀,希望對提升全人類資安能有丁點貢獻。

PowerShell 有個 Get-WinEvent 指令可以查詢 Windows 事件,依實務經驗,將所有事件記錄抓回來用 PowerShell 篩選的效率很差,用 -FilterHashtable-FilterXPath 查詢,FilterHashtable 只支援簡單的比對,XPath 語法較難懂但能實現複雜一點的查詢條件,會是較好的選擇。

Windows Event Log 支援的 XPath 版本只到 1.0,能用的函式少得可憐,別期望它像 SQL WHERE。如果不知從何開始,可以用事件檢視器的篩選工具設好條件,再參考它產生的 XML。參考

我設了幾項條件:

  • EventID = 4624 (登入成功) 或 4625 (登入失敗)
  • 只顯示特定日期之後的記錄,要用 TimeCreated[timediff(@SystemTime) ⇐ 距現在的毫秒數] 這種特殊寫法
  • 由於我要鎖定來自網路的存取,故要排除 EventData 中的 IpAddress 為 -、::1、127.0.0.1 的事件

程式碼很簡單,大約五十行搞定,最後將結果輸出成以 Tab 分隔的 CSV:

Param (
    # 查詢區間之起始時間(預設最近30天)
    [DateTime]$start = (Get-Date).AddDays(-30)
)
# 登入類別對照表
$LogonTypeTexts = @(
    'NA','NA',
    'Interactive', #2
    'Network','Batch','Service','Unlock','NetworkClearText',
    'NewCredentials','RemoteInteractive','CachedInteractive'
)
# 計算起始時間距今的毫秒數
$timeDiff = (New-TimeSpan -Start $start -End (Get-Date)).TotalMilliseconds
# 限定 4624(登入成功)、4625(登入失敗)
$xpath = @"
*[  
    System[
        (EventID=4624 or EventID=4625) and
        TimeCreated[timediff(`@SystemTime) <= $timeDiff]
    ] and 
    EventData[
        Data[@Name='IpAddress'] != '-' and
        Data[@Name='IpAddress'] != '::1' and
        Data[@Name='IpAddress'] != '127.0.0.1'
    ]
]
"@
# 加上 SilentlyContinue 防止查無資料時噴錯 No events were found that match the specified selection criteria.
Get-WinEvent -LogName 'Security' -FilterXPath $xpath -ErrorAction SilentlyContinue | ForEach-Object {
    $xml = [xml]$_.ToXml() # 將事件記錄轉成 XML
    $d = @{} # 建立 Hashtable 放 EventData.Data 中的客製屬性
    @($xml.Event.EventData.Data) | ForEach-Object {
        $d[$_.name] = $_.'#text'
    }
    if ($_.ID -eq 4624) { $action = '登入成功'  }
    elseif ($_.ID -eq 4625) { $action = '登入失敗' }
    $logonType = ''
    if ($d.LogonType -gt 1) {
        $logonType = $LogonTypeTexts[$d.LogonType]
    }
    [PSCustomObject]@{
        Action = $action;
        Time = $_.TimeCreated.ToString("yyyy/MM/dd HH:mm:ss");
        Id = $_.ID;
        TargetAccount = "$($d.TargetDomainName)\$($d.TargetUserName)"; # 登入帳號
        Socket = "$($d['IpAddress']):$($d['IpPort'])"; # IP 來源
        LogonType = $logonType; # 登入類別
        LogonProcess = $d.LogonProcessName; # 程序名稱
        AuthPkgName = $d.AuthenticationPackageName; # 驗證模組
    }
} | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation

我模擬了從另一台機器 192.168.50.93 登入整合式驗證 ASP.NET 網站 登入成功、失敗及網路磁碟機失敗的狀況,查詢結果如下:

純文字不好閱讀,建議用 .\ListLoginEvents.ps1 > D:\Check.csv 存成 CSV 檔再用 Excel 開啟。

22 列紅字是登入 IIS 失敗,21 列綠字是登入 IIS 成功;藍字是試圖連上 \\My-PC\d$ 時 Windows 用當下登入帳號 tony 試圖自動登入失敗的記錄,兩筆紫色是故意打錯帳密產生的失敗記錄。

大家可以用它檢查自己的 Windows,看看是否有人曾試圖登入你的電腦、連上你的網路分享資料夾。

PowerShell example to list logon events on Windows.


Comments

# by Taiyu

版主您好 我有查微軟網頁,可是都是微軟的廣告,遇到沒有數字簽章的時候,要怎麼處理,還請賜教,感謝。 PS V:\__01-00__Task\ListLoginEvents> .\ListLoginEvents.ps1 > Check.csv .\ListLoginEvents.ps1 : File V:\__01-00__Task\ListLoginEvents\ListLoginEvents.ps1 cannot be loaded. The file V:\__01-00 __Task\ListLoginEvents\ListLoginEvents.ps1 is not digitally signed. You cannot run this script on the current system. F or more information about running scripts and setting execution policy, see about_Execution_Policies at https:/go.micro soft.com/fwlink/?LinkID=135170. At line:1 char:1 + .\ListLoginEvents.ps1 > Check.csv + ~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : SecurityError: (:) [], PSSecurityException + FullyQualifiedErrorId : UnauthorizedAccess

# by CMH

回樓上 遇到執行ps1時數位簽章錯誤時可以用以下指令更改Excecution Policy Set-ExecutionPolicy Unrestricted 或是用 powershell.exe 執行時指定 Execution Policy powershell.exe -executionpolicy bypass -file .\Script.ps1

# by

版主你好, 有没有办法使用检查一下公司发的笔记本被IT部门安装了什么样的监控软件吗?

# by Jeffrey

to 翔,假設公司安裝的是名門正派的監控軟體(沒用後門、木馬的技巧讓自己隱形,若是如此已屬駭客層次的議題了),最基本的檢查方式是看Windows的應用程式的安裝清單(控制台用來移除軟體的那個介面),但有些軟體因部署方式不同不一定會出現在清單中,因此更徹底的檢查方式是開工作管理員逐一盤點執行中的程序,看有沒有可疑項目。

# by 小陳

這妄想症我有時也有,不過我是假設是否不小心裝到一些間諜程式來偷資料。 我是用 ProcessTCPSummary by nirsoft 來看的。 主要是觀察是否有哪個process偷連上網。 ProcessTCPSummary - Show the number of TCP connections for every Windows process

# by IG

WFH的現在看到這篇真棒,想請問黑暗大及各位先進,IT管理方面,是否可以用這方式透過AD來查詢每台電腦遠端登入紀錄呢,因為上司要求稽核查員工是否有在上班時間正常登入事件... 在思考該怎麼運用比較好 ><

# by Jeffrey

to IG, 只要具備權限,Get-WinEvent 加 -ComputerName 即可查詢遠端主機,剩下就是從事件中挑選合適的項目以判斷打卡時間。

# by IG

謝謝 Jeffrey 的教學,我來嘗試看看,感謝~

# by BEN

感謝分享! 是否可以加入以下兩個EVENT ID,這兩個通常也是常常需要關心的事件。 4720 已建立使用者帳戶 1102 稽核記錄已清除

# by Jeffrey

to BEN, 視需求調整 $xpath 中的 (EventID=4624 or EventID=4625) 條件即可。

Post a comment


99 - 97 =