Wireshark 的进程/PID 过滤器

是否有使用 金线鲨基于特定进程 ID 过滤/跟踪 TCP/SSL流的方法?

194159 次浏览

我看不出来。PID 不会到达线路(一般来说) ,另外 Wireshark 允许你查看线路上的内容——可能是通过线路进行通信的 所有机器。不管怎样,进程 ID 在不同的机器上并不是唯一的。

您可以匹配 wireshark 的端口号和(比如说) Netstat的端口号,后者将告诉您监听该端口的进程的 PID。

如果您正在寻找一种替代方法,并且所使用的环境是 Windows,那么微软的 网络监视器3.3是一个不错的选择。它具有进程名称列。您可以使用上下文菜单轻松地将其添加到筛选器中并应用筛选器。.像往常一样,图形用户界面非常直观..。

在 Windows 上,有一个实验性的版本可以做到这一点,正如邮件列表 Rel = “ nofollow”> Filter by local process name 根据本地进程名过滤中所描述的那样

您可以使用 wireshark.- 上的这些命令示例检查端口号

Tcp.port = = 80

Port = = 14220

这对于监视某些进程试图连接到的位置非常重要,而在 Linux 上似乎没有任何方便的方法可以做到这一点。然而,有几种变通方法是可行的,所以我觉得值得一提。

有一个程序叫做 没有,它允许运行一个没有互联网接入的程序(我的系统上大多数程序启动器都安装了它)。它使用 setguid 在组 nonet 中运行一个进程,并设置一个 Iptables规则来拒绝来自该组的所有连接。

更新: 到目前为止,我使用的是一个更简单的系统,您可以轻松地使用 ferm 获得可读的 iptables 配置,并且只需使用程序 sg来运行具有特定组的程序。Iptables 还允许您重新路由流量,这样您甚至可以将其路由到一个单独的接口或端口上的本地代理,该代理允许您在检查流量时,如果您不想禁用所有互联网,则可以直接从 Iptables 过滤 wireshark 或 LOG 数据包。

调整它以便在一个组中运行一个程序,并在执行生命周期中使用 iptables 切断所有其他流量,这并不十分复杂,然后您只能从这个流程中捕获流量。

如果我想写的话,我会在这里发一个链接。

另一方面,您总是可以在虚拟机中运行一个进程,并嗅探正确的接口以隔离它所建立的连接,但这将是一个相当糟糕的解决方案..。

在某些情况下,您不能通过进程 ID 进行筛选。例如,在我的例子中,我需要嗅探来自一个进程的流量。但我发现在其配置目标机的 IP 地址,添加了过滤器 ip.dst==someip和瞧。它在任何情况下都不会起作用,但对某些人来说它是有用的。

使用 Microsoft Message Analyzer v1.4

从字段选择器导航到 ProcessId。

Etw
-> EtwProviderMsg
--> EventRecord
---> Header
----> ProcessId

右键单击 添加为列

使用 netstat获取端口号:

netstat -b

然后使用 Wiresharkfilter:

tcp.port == portnumber

如果你想跟踪一个仍然需要启动的应用程序,那么这当然是可能的:

  1. 安装码头(见 https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/)
  2. 打开一个终端并运行一个小容器: docker run -t -i ubuntu /bin/bash(将“ ubuntu”更改为您最喜欢的发行版,这不必与您真正的系统中的相同)
  3. 使用与在实际系统中安装应用程序相同的方法在容器中安装应用程序。
  4. 在您的实际系统中启动 wireshark,进入捕获 > 选项。在将要打开的窗口中,您将看到所有的接口。不选择 anywlan0eth0,... 而是选择新的虚拟接口 docker0
  5. 开始捕捉
  6. 在容器中启动应用程序

您可能对在容器中运行软件有一些疑问,因此下面是您可能想问的问题的答案:

  • 我的应用程序是否可以在容器中工作?几乎可以肯定是的,但是你可能需要了解一些关于 docker 的知识才能让它工作
  • 我的应用程序不会运行得很慢吗? 可忽略不计。如果你的程序需要进行一周的大量计算,那么现在可能需要一周零三秒
  • 如果我的软件或者其他什么东西在容器里坏了怎么办?这就是容器的好处。内部运行的任何东西只能破坏当前容器,不能损害系统的其他部分。

使用 strace更适合这种情况。

strace -f -e trace=network -s 10000 -p <PID>;

选项 -f也跟踪所有分叉进程,-e trace=netwrok只过滤网络系统调用和 -s显示字符串长度可达10000个字符。

您还可以只跟踪某些调用,如 send、 recv 和 read 操作。

strace -f -e trace=send,recv,read -s 10000 -p <PID>;

我有一个 PowerShell 脚本,可能会在这样的情况下有所帮助,把它放在这里会更好一些。我在 Windows 10上的 PowerShell Version 5.2和7.2测试都是成功的,但是 atm 我不能在其他操作系统上测试它。

它的作用: 它使用 IP 和网络统计中使用过的进程的端口构建 Wiresharkfilter。为了更好地理解它。

说来话长:

它获取 TCP (侦听器和连接)和 UDP 的网络统计信息 (听众)多次,直到你想继续。你会想要 等待,直到您完成测试您的过程 继续,它将显示当前进程的进程 ID 必须选择一个或多个进程。进程是第一个 过滤器,你可以应用-情况下,OP 希望有应该 只有一个进程。然后必须选择可以连接的连接/端口 想要在你的过滤器-通常选择所有这里。之后,你必须 Select 另一种类型的过滤器,它也定义了 Wireshark 过滤器将看起来像。过滤器将显示和自动 复制到剪贴板。

根据您的选择和过程,过滤器可能会 很长。

它没有的: 它不能监视您的进程和它们的网络活动。它只是多次获取数据。在 get 命令之间可能会错过一些连接。 它也不能看到任何 udp 数据包,所以它不能得到关于 udp 的远程部分的任何信息。但它将获得本地 UDP 监听端口。

其他限制是: 0.0.0.0上的本地监听将转换为您的本地 IP 地址。在127.0.0.1上监听将被跳过,因为我现在不需要本地连接监视。

因此,这里的代码:

"Attention: This script can NOT make a filter for a process, but it can build it regarding some local to remote connections (TCP) and vice versa,  and ports (UDP)."
"It works good for some cases, but not for all."
"In general it is designed to filter as less as possible."
"You may still see packets from some other processes depending on your selection"
""
"Press return to continue"
Read-Host | Out-Null


# Load Functions
function Out-WireSharkSyntax($data) {
$data = $data -replace "\)|\(| eq | or | and |==|!|{|}| not | in ",';$0;' -split ";"
foreach ($Line in $data) {
$color = switch ($Line) {
"(" {"blue"}
")" {"blue"}
"!" {"cyan"}
" eq " {"yellow"}
" or " {"cyan"}
" and " {"cyan"}
" not " {"cyan"}
" in " {"cyan"}
"==" {"yellow"}
"||" {"yellow"}
"{" {"darkred"}
"}" {"darkred"}
Default {"green"}
}
Write-Host -ForegroundColor $color -NoNewline -BackgroundColor Black $line}
}




$count=0
$sleepTimer=500 #in milliseconds to restart the query for used TCP ports and listening UDP ports
$QuitKey=81 #Character code for 'q' key.


$CurrentDateTime = Get-Date
#$LocalIPv4address = @(Get-NetIPAddress -AddressFamily IPv4 -InterfaceIndex $(Get-NetConnectionProfile | Select-Object -ExpandProperty InterfaceIndex) | Select-Object -ExpandProperty IPAddress)
$LocalIPv4address = (Get-NetIPAddress -AddressFamily IPv4 -AddressState Preferred -PrefixOrigin manual,dhcp).IPAddress
if ($LocalIPv4address.count -ne 1) {
"Could not detect exact one IPAddress. Enter the IPAddress to be used:`r`nYour local dectected addresses were:$($LocalIPv4address -join " OR ")"
$LocalIPv4address = Read-Host
}


"Retrieving network network statistics every $sleepTimer milliseconds..."
"(very short connections may not be captured with this script because of this!)"


$TcpAndUdpProperties = @{Name="NetStatEntryAsString";Expression={$_.LocalAddress + "--" + $_.LocalPort + "--" + $_.RemoteAddress + "--" + $_.RemotePort + "--" + $_.cimclass.cimclassname}},`
"LocalAddress","LocalPort","OwningProcess","RemoteAddress","RemotePort","CreationTime"
# Properties for both equal to get equal list header in all cases
$TcpAndUdpNetworkStatistic = @()


Write-Host "Press 'q' to stop collecting network statistics and to continue with the script."
Write-Host "Wireshark should now capture and you start what ever you would like to monitor now."


while($true)
{
if($host.UI.RawUI.KeyAvailable) {
$key = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyUp")
if($key.VirtualKeyCode -eq $QuitKey) {
#For Key Combination: eg., press 'LeftCtrl + q' to quit.
#Use condition: (($key.VirtualKeyCode -eq $Qkey) -and ($key.ControlKeyState -match "LeftCtrlPressed"))
Write-Host ("`r`n'q' is pressed! going on with the script now.")
break
}
}
# Temporary convertion to JSON ensures that not too much irrelevant data being bound to the new variable
$TcpAndUdpNetworkStatistic += `
(Get-NetTCPConnection | select -Property $($TcpAndUdpProperties + @{Name="Protocol";Expression={"TCP"}}) | ConvertTo-Json | ConvertFrom-Json) + `
(Get-NetUDPEndpoint   | select -Property $($TcpAndUdpProperties + @{Name="Protocol";Expression={"UDP"}}) | ConvertTo-Json | ConvertFrom-Json)
# exclude IPv6 as it is not handled in this script, remove 127.0.0.1 connections and remove duplicates
$TcpAndUdpNetworkStatistic = $TcpAndUdpNetworkStatistic | where {$_.LocalAddress -notmatch ":" -and $_.LocalAddress -notlike "127.*"} | ConvertTo-Csv -NoTypeInformation | Sort-Object -Unique -Descending |ConvertFrom-Csv | sort Protocol,LocalAddress,LocalPort
$TcpAndUdpNetworkStatistic | where {$_.localaddress -eq "0.0.0.0"} | foreach {$_.localaddress = $LocalIPv4Address}
    

$count++
Write-Host ("`rChecked network statistics {0} time{1}. Collected {2} netstat entries" -f $count,$(("s"," ")[($count -eq "1")]),$TcpAndUdpNetworkStatistic.Count) -NoNewline
    

Start-Sleep -m $sleepTimer
}
$TcpAndUdpNetworkStatistic | where {$_.localaddress -eq "0.0.0.0"} | foreach {$_.localaddress = $LocalIPv4Address}






$ProcessIDToNetworkstatistic = $TcpAndUdpNetworkStatistic | Group-Object OwningProcess -AsHashTable -AsString
"Getting processlist..."
$processselection = "Id", "Name", @{Name="MainModuleName";Expression={$_.MainModule.ModuleName}}, "Company",
"Path", "Product", "Description", "FileVersion", "ProductVersion", "SessionID", "CPU", "Threads", "StartTime"
$GetNetListedProcesses = Get-Process | Where {$ProcessIDToNetworkstatistic.GetEnumerator().name -contains $_.ID} | Select -Property $processselection


"Output processlist to gridview... Read the gridview title and make selection there..."
$ProcessIDs = ($GetNetListedProcesses |Select @{Name="Port/Session Count";Expression={$ProcessIDToNetworkstatistic["$($_.id)"].count}},* | `
Out-GridView -Title "Select process to view network statistics related to process id" -Passthru).ID


"Output related network statistics to gridview... Read the gridview title and make selection there..."
$TcpAndUdpNetworkStatisticFilteredByProcessID = $TcpAndUdpNetworkStatistic | Where {$ProcessIDs -contains $_.OwningProcess} | `
Out-Gridview -Title "Select lines that contain data you may like to have in your Wireshark filter" -Passthru




# for statistic and later processing
$UDPLocalPorts = ($TcpAndUdpNetworkStatisticFilteredByProcessID | where {$_.Protocol -eq "UDP"}).LocalPort | foreach {[int]$_} | Sort-Object -Unique
$TCPConnections = $TcpAndUdpNetworkStatisticFilteredByProcessID | where {$_.Protocol -eq "TCP"}
$TCPLocalPorts = @(foreach ($Connection in $TCPConnections) { [int]$Connection.LocalPort }) | Sort-Object -unique
$TCPRemotePorts = @(foreach ($Connection in $TCPConnections) { [int]$Connection.RemotePort })| Sort-Object -unique | where {$_ -ne 0}
$UDPLocalEndpoints = $TcpAndUdpNetworkStatisticFilteredByProcessID | where {$_.Protocol -eq "UDP"}
$UDPLocalPorts = @(foreach ($Endpoint in $UDPLocalEndpoints) { [int]$Endpoint.LocalPort }) | Sort-Object -unique




$FilterOptionsDialog = "
You can choose between the following filters
[all] for UDP + TCP filter - including remote address where possible ( filterable: $(($TcpAndUdpNetworkStatisticFilteredByProcessID).count) )
[tall] for TCP with listening ports and connections including remote ports and addresses ( filterable: $(($TcpAndUdpNetworkStatisticFilteredByProcessID | where {$_.Protocol -eq "TCP"}).count) )
[tcon] for TCP without listening ports - only connections including remote ports and addresses ( filterable: $(($TcpAndUdpNetworkStatisticFilteredByProcessID | where {$_.Protocol -eq "TCP" -and [int]$_.RemotePort -eq 0}).count) )
[u] for UDP portfilter - only local listening port - no `"connections`" ( filterable: $(($TcpAndUdpNetworkStatisticFilteredByProcessID | where {$_.Protocol -eq "UDP"}).count) )
[p] for portfilter only by ports ( filterable: $($TCPLocalPorts.count) local TCP / $($TCPRemotePorts.count) remote TCP / $($UDPLocalPorts.count) UDP )
[ptl] for portfilter only by local TCP ports (no UDP) ( filterable: $($TCPLocalPorts.count) local TCP / $($TCPRemotePorts.count) remote TCP )
[pt] for portfilter only by TCP ports (remote port ignored and no UDP) ( filterable: $($TCPLocalPorts.count) local TCP )
[pu] for portfilter only by UDP ports (only listening ports - no information about used ports) ( filterable: $($UDPLocalPorts.count) )
Type your selection and press return"
$WiresharkFilter = ""
do {
$tmp = read-host $FilterOptionsDialog
} while ("all","u","tcon","tall","p","pt","ptl","pu" -notcontains $tmp)
switch ($tmp)
{
    

"all" {
# TCP connections with local and remote IP filter - both ports included - udp only listening are included
$ConnectionFilterResolved = "("
$ConnectionFilterResolved += $(foreach ($connection in $TcpAndUdpNetworkStatisticFilteredByProcessID) {
if ([int]$connection.remoteport -eq 0) {
$ConnectionFilter = "(ip.addr eq {0} and {2}.port eq {1})"
$ConnectionFilter -f $connection.LocalAddress,$connection.LocalPort,$connection.Protocol.ToLower()
} else {
$ConnectionFilter = "(ip.addr eq {0} and ip.addr eq {1}) and (tcp.port eq {2} and tcp.port eq {3})"
$ConnectionFilter -f $connection.LocalAddress,$connection.RemoteAddress, $connection.LocalPort, $connection.RemotePort
}
}) -join ") or ("
$ConnectionFilterResolved += ")"
$WiresharkFilter += $ConnectionFilterResolved
}
    

"u" {
# udp.port only - without remote IP filter
#Building the filter variable
$FilteredPortlist = $TcpAndUdpNetworkStatisticFilteredByProcessID | where {$_.Protocol -eq "UDP"} | foreach { "udp.port eq $($_.LocalPort)"} | sort | get-unique
if ($FilteredPortlist) {
$WiresharkFilter += "(" +
($FilteredPortlist -join ") or (") +
")"
}
}
    

    

"tall" {#tall
# TCP connections with local and remote IP filter - both ports included - only listening are included without remote data)
$tcpStatsFilterResolved = "("
$tcpStatsFilterResolved += $(foreach ($connection in ($TcpAndUdpNetworkStatisticFilteredByProcessID | where {$_.Protocol -eq "TCP"} )) {
if ([int]$connection.remoteport -eq 0) {
$TcpFilter = "(ip.addr eq {0} and tcp.port eq {1})"
$TcpFilter -f $connection.LocalAddress,$connection.LocalPort
} else {
$TcpFilter = "(ip.addr eq {0} and ip.addr eq {1}) and (tcp.port eq {2} and tcp.port eq {3})"
$TcpFilter -f $connection.LocalAddress,$connection.RemoteAddress, $connection.LocalPort, $connection.RemotePort
}
}) -join ") or ("
$tcpStatsFilterResolved += ")"
$WiresharkFilter += $tcpStatsFilterResolved
}
    

"tcon" {
# TCP connections only - listening only ports are not included)
$tcpStatsFilterResolved = "("
$tcpStatsFilterResolved += $(foreach ($connection in ($TcpAndUdpNetworkStatisticFilteredByProcessID | where {$_.Protocol -eq "TCP" -and [int]$_.RemotePort -eq 0} )) {
$TcpFilter = "(ip.addr eq {0} and ip.addr eq {1}) and (tcp.port eq {2} and tcp.port eq {3})"
$TcpFilter -f $connection.LocalAddress,$connection.RemoteAddress, $connection.LocalPort, $connection.RemotePort
}) -join ") or ("
$tcpStatsFilterResolved += ")"
$WiresharkFilter = $tcpStatsFilterResolved
}
    

"p" {
# Ports only - remote and local
$TCPWiresharkFilter = "tcp.port in {" + ( ($TCPLocalPorts + $TCPRemotePorts | Sort-Object -unique ) -join ", " ) + "}"


$UDPWiresharkFilter = "udp.port in {" + ( $UDPLocalPorts -join ", " ) + "}"
$Or = ( ""," or " )[$TCPConnections.count -gt 0 -and $UDPLocalEndpoints.count -gt 0]
$WiresharkFilter = "$TCPWiresharkFilter$Or$UDPWiresharkFilter"
}
    

"ptl" {
# Local tcp ports only - remote are excluded
$WiresharkFilter = "tcp.port in {" + ( $TCPLocalPorts -join ", " ) + "}"
}
    

"pt" {
# tcp ports only - remote and local ports
$WiresharkFilter = "tcp.port in {" + ( ($TCPLocalPorts + $TCPRemotePorts | Sort-Object -unique ) -join ", " ) + "}"


}
    

"pu" {
# udp ports only - no remote anyway
$WiresharkFilter = "udp.port in {" + ( $UDPLocalPorts -join ", " ) + "}"
}
    

    

}
if ($WiresharkFilter.toString().length -gt 5) {
# Output to clipboard
$WiresharkFilter | Set-Clipboard
"The following filter should be in your clipboard already"
""
""
Out-WireSharkSyntax $WiresharkFilter
""
""
"Attention: All filtering is done on network statistic data arrount that time `"$CurrentDateTime`" and the additional $(1 - $count) checks that were done."
"`tThis filter is not perfect, but it works for some cases or is a good template to be customized afterwards."
} else {
"Everything was filtered out by your selections - I got no data to create a filter"
}
""
"Press return to end script"
Read-Host | Out-Null

这就是它看起来的样子 Main steps to go

Result

另一个可能的结果 Result_pt

您可以根据自己的需要优化代码,但对我来说,这已经足够了。 如果有人已经找到了一个更好的/内置的解决方案,请分享您的信息。