##Windowsでのパケットキャプチャは netsh や Wireshark が鉄板だけど...
Windows環境におけるパケットキャプチャは、netsh コマンドやパケットキャプチャツールの Wireshark が有名ですが、netsh は2/17に20周年を迎えましたし、Wireshark はインフラの環境によってはインストールが制限されることが多いです。
PowerShell 5.0 には NetEventPacketCapture と呼ばれるコマンドレット群があり、これらを用いてパケットをキャプチャすることができます。
このドキュメントでは、NetEventPacketCapture を使ったTCPIPパケットのキャプチャと、生成されるETLファイルの簡単な解析までを行います。
##環境
> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.18362.145
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.18362.145
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
##ネットワークイベントセッションを作成する
ネットワークパケットを取得するためにはまず、セッションというものを作る必要があります。
PowerShellを管理者権限で開き、以下のコマンドを入力します。
New-NetEventSession -Name "Session1" -LocalFilePath "$HOME\Desktop\Session1.etl"
-Name
でセッション名を Session1 に、-LocalFilePath
でキャプチャしたログファイルをカレントユーザーをデスクトップに作成するよう指定します。
実行すると、以下の出力が得られます。
> New-NetEventSession -Name "Session1" -LocalFilePath "$HOME\Desktop\Session1.etl"
Name : Session1
CaptureMode : SaveToFile
LocalFilePath : C:\Users\Goggle555\Desktop\Session1.etl
MaxFileSize : 250 MB
TraceBufferSize : 0 KB
MaxNumberOfBuffers : 0
SessionStatus : NotRunning
##キャプチャするプロバイダーをTCPIPに指定する
キャプチャするTCPIPプロバイダーの名前を、以下のコマンドで探します。
> (Get-NetEventProvider -ShowInstalled).Name | Select-String "TCP"
TCPIP Service Trace
Microsoft-Windows-TCPIP
Add-NetEventProvider
を使い、Session1のプロバイダーをMicrosoft-Windows-TCPIP
に指定します。
> Add-NetEventProvider -Name "Microsoft-Windows-TCPIP" -SessionName "Session1"
Name : Microsoft-Windows-TCPIP
SessionName : Session1
Level : 4
MatchAnyKeyword : 0xFFFFFFFFFFFFFFFF
MatchAllKeyword : 0x0
##パケットキャプチャを開始する
Start-NetEventSession
でセッションがパケットキャプチャを開始します。
このコマンドを実行しても出力が表示されないため、Get-NetEventSession
でセッションが実行されていることを確認します。
> Start-NetEventSession -Name "Session1"
> Get-NetEventSession
Name : Session1
CaptureMode : SaveToFile
LocalFilePath : C:\Users\Goggle555\Desktop\Session1.etl
MaxFileSize : 250 MB
TraceBufferSize : 64 KB
MaxNumberOfBuffers : 38
SessionStatus : Running
SessionStatus
の値がRunning
と表示されていれば、キャプチャが開始されています。
またこのときに、New-NetEventSession -LocalFilePath
で指定した場所にETLファイルが生成されています。
> ls "$HOME\Desktop" -filter "*.etl"
ディレクトリ: C:\Users\Goggle555\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
------ 2020/02/29 12:06 0 Session1.etl
##キャプチャを停止する
Stop-NetEventSession
でパケットキャプチャを停止します。
このコマンドでも出力が表示されないため、Get-NetEventSession
でセッションが停止していることを確認します。
> Stop-NetEventSession -Name "Session1"
> Get-NetEventSession
Name : Session1
CaptureMode : SaveToFile
LocalFilePath : C:\Users\Goggle555\Desktop\Session1.etl
MaxFileSize : 250 MB
TraceBufferSize : 64 KB
MaxNumberOfBuffers : 38
SessionStatus : NotRunning
SessionStatus
の値がNotRunning
と表示されていれば、キャプチャは停止しています。
ETLファイルの状態を見てみると、キャプチャしていた時間にもよりますが容量が増えていることがわかります。
> ls "$HOME\Desktop" -filter "*.etl"
ディレクトリ: C:\Users\Goggle555\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2020/02/29 12:27 6488064 Session1.etl
##ネットワークイベントセッションを削除する
セッションを停止したあとは、Remove-NetEventSession
でセッションを削除しましょう。
セッションは1つしか作れず、前のセッションを放置してるとNew-NetEventSession
をした際にエラーになってしまうためです。
> Remove-NetEventSession
> Get-NetEventSession
>
##ETLファイルを読み込む
ETL(Event Trace Log)ファイルとは、netshやlogmanなどでも取得できるバイナリ形式のログファイルです。
Get-WinEvent
コマンドレットで配列オブジェクトとして読み込むことができます。
> (Get-WinEvent -Path "$HOME\Desktop\Session1.etl").GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
ログの先頭10個を見てみましょう。
毎回ETLファイルを直接読み込むと時間がかかるので、$Session1
変数に格納します。
> $Session1 = Get-WinEvent -Path $HOME\Desktop\Session1.etl -Oldest
> $Session1[1..10]
ProviderName: Microsoft-Windows-TCPIP
TimeCreated Id LevelDisplayName Message
----------- -- ---------------- -------
2020/02/29 12:06:32 1300 情報 TCP: connection 0xffffa98c94b54b90 (local=[240d:1a:593:2400:4c89:1e12:405d:7347]:58656 remote=[2404:6800:4004:80b::200a]:443) exists. State = EstablishedS...
2020/02/29 12:06:32 1300 情報 TCP: connection 0xffffa98c8d26ab80 (local=192.168.1.2:57657 remote=168.61.148.205:9354) exists. State = EstablishedState. PID = 14188.
2020/02/29 12:06:32 1300 情報 TCP: connection 0xffffa98c8dab5010 (local=192.168.1.2:58666 remote=54.240.252.52:443) exists. State = EstablishedState. PID = 144.
2020/02/29 12:06:32 1300 情報 TCP: connection 0xffffa98ca3a6dba0 (local=192.168.1.2:58493 remote=103.2.48.247:443) exists. State = CloseWaitState. PID = 6492.
2020/02/29 12:06:32 1300 情報 TCP: connection 0xffffa98c94e708c0 (local=[240d:1a:593:2400:4c89:1e12:405d:7347]:58655 remote=[2404:6800:4004:80b::200a]:443) exists. State = EstablishedS...
2020/02/29 12:06:32 1300 情報 TCP: connection 0xffffa98c908e0a10 (local=127.0.0.1:65001 remote=127.0.0.1:49717) exists. State = EstablishedState. PID = 4832.
2020/02/29 12:06:32 1300 情報 TCP: connection 0xffffa98c87f49b80 (local=[240d:1a:593:2400:4c89:1e12:405d:7347]:58601 remote=[2404:6800:4004:81d::200a]:443) exists. State = EstablishedS...
2020/02/29 12:06:32 1300 情報 TCP: connection 0xffffa98c9c576050 (local=[240d:1a:593:2400:4c89:1e12:405d:7347]:58659 remote=[2406:da14:add:900:f2cf:9253:2438:7cf6]:443) exists. State =...
2020/02/29 12:06:32 1300 情報 TCP: connection 0xffffa98c896e6ba0 (local=192.168.1.2:51329 remote=40.90.189.152:443) exists. State = EstablishedState. PID = 5156.
2020/02/29 12:06:32 1300 情報 TCP: connection 0xffffa98c8ca804b0 (local=127.0.0.1:9100 remote=127.0.0.1:49875) exists. State = EstablishedState. PID = 9932.
ID 別にどれくらいパケットが記録されているか見ることもできます。
> $Session1 | group id -NoElement | sort count -Descending
Count Name
----- ----
13799 1454
5848 1170
5278 1169
4272 1074
3228 1332
2159 1157
1821 1167
1752 1330
1562 1159
(...)
一番カウントの多いId 1454
の中身を見てみましょう。
> $Session1.Where({$_.id -eq 1454})[0..4]
ProviderName: Microsoft-Windows-TCPIP
TimeCreated Id LevelDisplayName Message
----------- -- ---------------- -------
2020/02/29 12:06:32 1454 情報 INETINSPECT: Owner = 0xffffa98c93f962a0, InspectHandle = 0xffffa98c93f962e0, InspectType = CreateEndpoint, Action = Allow, Status = STATUS_SUCCESS
2020/02/29 12:06:32 1454 情報 INETINSPECT: Owner = 0xffffa98c93f962a0, InspectHandle = 0xffffa98c8e5c6a20, InspectType = BindEndpointRequest, Action = Allow, Status = STATUS_SUCCESS
2020/02/29 12:06:32 1454 情報 INETINSPECT: Owner = 0xffffa98c93f962a0, InspectHandle = 0xffffa98c8e5c6a20, InspectType = BindEndpoint, Action = Allow, Status = STATUS_SUCCESS
2020/02/29 12:06:32 1454 情報 INETINSPECT: Owner = 0xffffa98c93f962a0, InspectHandle = 0xffffa98c8e5c6a20, InspectType = ConnectRequest, Action = Allow, Status = STATUS_SUCCESS
2020/02/29 12:06:32 1454 情報 INETINSPECT: Owner = 0xffffa98c967a7560, InspectHandle = 0xffffa98c9c8717d0, InspectType = ReceiveDatagram, Action = Allow, Status = STATUS_SUCCESS
Message
にsuccess
が含まれているパケットをカウントしてみたり。
> $Session1.message | Select-String -SimpleMatch "success" | measure
Count : 16741
Average :
Sum :
Maximum :
Minimum :
Property :
##参考
Packet Sniffing with PowerShell: Getting Started
NetEventPacketCapture
windows-powershell-docs/NetEventPacketCapture.md at master · MicrosoftDocs/windows-powershell-docs