这是什么?

这经常发生在我身上……有些事情很奇怪或没有按预期工作,心中不禁会问:“发生了什么?为什么客户端或服务器会这样表现?”通常,这些都是与网络相关的问题。

一位安全研究人员曾告诉我:“如果你想了解一个系统是如何工作的,你必须理解网络流量。几乎所有问题都可以在网络层面上进行诊断。” 根据我的经验,这确实是事实。 🥳

不幸的是,我的经验也表明,许多人不知道如何在Windows中捕获网络流量,而唯一的解决方案就是***“让我们安装Wireshark”***。

好吧,即使Wireshark是一个很棒的工具,但它并不是唯一的解决方案,也可能不是快速和一次性捕获的最佳解决方案。尤其是当涉及到你那些安全性极高的服务器时,肯定有更好、更快的解决方案。



关于这种情况的考虑

再说一次,Wireshark是一个强大的工具,或多或少是事实上的网络协议分析标准。你肯定会用它来分析捕获到的内容。但Wireshark的缺点是:

  • 它无法在不安装额外组件的情况下捕获:一个网络驱动程序(WinPcap或Npcap)。
  • 它是一个活跃且复杂的工具,包含许多二进制文件和潜在的漏洞。
  • 在服务器上的每次安装都是一个潜在的攻击向量,并会导致你的服务器变得独特。

这可能不是你想在生产服务器上使用的工具,尤其是当你只想捕获一些流量进行快速分析时。 无论如何,把它放在你的工作站上分析捕获到的内容。你甚至不需要管理员权限就可以使用Wireshark进行分析! Wireshark可以作为便携式安装正常运行,而无需进行任何系统范围的安装。

那么,有什么替代方案?

在Windows中有几种替代方案可以完成这项工作。最棒的是,你不需要在机器上安装任何东西。Windows中有内置工具可以完成这项工作……而且它们非常强大。结合一些PowerShell和PSRemoting功能,这很容易扩展。

1. netsh trace - 老而弥坚

netsh trace 命令是Windows中的一个内置工具,允许你在不需要额外软件的情况下捕获网络流量。它使用Windows事件跟踪(ETW)框架来捕获和记录网络事件。 基本上,它是netsh trace startnetsh trace stop来开始和停止捕获,但还有netsh trace show来显示当前状态,以及netsh trace convert来将捕获的数据转换为更易读的格式。

以下是netsh trace中可用命令的快速概述:

以下命令可用:

在此上下文中的命令:
?              - 显示命令列表。
convert        - 将跟踪文件转换为HTML报告。
correlate      - 将跟踪文件标准化或过滤到新输出文件。
diagnose       - 启动诊断会话。
dump           - 显示配置脚本。
export         - 将场景导出到WPR配置文件。
help           - 显示命令列表。
merge          - 合并跟踪文件并添加符号元数据。
postreset      -
show           - 列出接口、提供程序和跟踪状态。
start          - 开始跟踪。
stop           - 停止跟踪。

要查看命令的帮助,请输入命令,后跟空格,然后输入?。

现在,让我们关注startstop命令,这些是你将用来捕获网络流量的命令。命名是相当自解释的,我想。要开始网络捕获,你需要指定一些额外的参数。基本上,你只需要指定你想捕获流量。这就是参数capture=yes。 即使这就是你所需的绝对最小值,还有一个推荐的参数以提高效率。如果你只关心捕获网络流量,可以通过report=disabled禁用netsh的报告生成行为。这将加快捕获过程并减少捕获文件的大小,因为它不会包含额外的报告数据。 其余参数可以根据你的需要自定义捕获过程。当然,你可以指定保存跟踪的位置和捕获内容,但这不是强制性的。

由于捕获网络流量是一个系统范围的操作,会影响系统上的所有进程(和所有用户),因此你需要以管理员权限运行netsh trace命令。 以下是使用netsh trace开始捕获网络流量的基本命令:

# 在“以太网”接口上捕获网络流量并将其保存到文件中
netsh trace start capture=yes report=disabled

一旦你获得所需内容,可以使用以下命令停止捕获:

# 停止网络流量捕获
netsh trace stop


捕获的流量保存在一个.etl文件中,可以稍后进行分析。如果你想为捕获的数据指定自定义文件名和位置,可以使用tracefile参数进行指定。

# 捕获网络流量并将其保存到特定文件
netsh trace start capture=yes report=disabled tracefile=C:\Administration\Logs\MyTraceFile.etl

现在我们已经捕获了流量,需要对其进行分析……

在Wireshark中打开etl-file不幸的是需要额外的步骤。但是,请继续关注我,这并不难,而且仍然不需要安装: 只需使用etl2pcapng,这是微软提供的一个非常小的工具,你就可以开始了。它将etl-file转换为pcapng-file,可以在Wireshark中轻松打开进行分析。

# 将.etl文件转换为.pcapng格式
etl2pcapng nettrace.etl nettrace.pcapng

当然,命令中的文件名可以是完全限定的路径,包括驱动器字母和目录。这只是一个快速示例。


转换后可以删除创建的etl-file,如果你不再需要它的话。pcapng-file是你将在Wireshark中进行分析的文件。 除了使用这种方法不需要在系统上安装任何东西外,你还拥有更详细的捕获的优势,因为netsh trace捕获的不仅仅是网络流量。它还捕获有关系统和进程的额外信息,这对于故障排除和分析非常有用:


这个过程在每个Windows系统上都能很好地工作,从Windows 7和Windows Server 2008 R2开始。考虑到这一点,这对于内置解决方案来说相当不错,可以满足你的需求。 再说一次,所有这些都无需在系统上安装任何东西,这在生产服务器上是一个巨大的优势。你可以直接运行命令,捕获流量,并在你的工作站上使用Wireshark进行分析,而无需在服务器本身上进行任何安装。

netsh trace还有许多其他参数和选项,可以根据你的需要自定义捕获过程。例如,你可以指定

  • 协议过滤器
  • 以太网类型过滤器
  • IP地址过滤器
  • 要捕获的特定接口
  • 以及更多

你可以通过运行netsh trace show CaptureFilterHelp查看所有可用选项。这将为你提供一个详细的可用过滤器和选项列表,以便你自定义捕获。 我个人最喜欢的选项是:

# 仅捕获IPv4流量:
Ethernet.Type=IPv4

# 仅捕获TCP/UDP或两者:
Protocol=TCP
Protocol=UDP
Protocol=(TCP,UDP)

# 将捕获限制为特定IP地址:
IPv4.SourceAddress=<IPv4 address>
IPv4.DestinationAddress=<IPv4 address>
IPv4.Address=(<IPv4 Address>,<IPv4 Address>)

使用这些选项,你应该能够有效捕获与你的分析和故障排除最相关的流量。你可以组合过滤器,仅捕获与你特定用例相关的流量,这可以帮助你专注于重要数据并减少捕获中的噪音。

你可以在实用示例部分找到一些示例。

2. pktmon - 新来的小子

Pktmon是Windows 10 / Windows Server 2019及更高版本中的较新内置工具,提供了更方便的数据包监控功能。

它也是一个命令行工具,允许你捕获流量,但它更专注于数据包监控,而不是netsh trace,并提供了更用户友好的界面来管理数据包过滤器和捕获流量。语法略有不同,但基本上是相同的。如果你熟悉netsh trace,你应该会觉得使用它很舒服。以下是pktmon中可用命令的快速概述:

pktmon <command> [OPTIONS | help]
    高级数据包捕获和事件收集。

命令
    filter     管理数据包过滤器。
    list       列出数据包处理组件。

    start      开始 数据包捕获、计数器和事件收集。
    stop       停止数据收集。
    status     查询当前状态。
    unload     卸载 PktMon 驱动程序。

    counters   显示当前数据包计数器。
    reset      将数据包计数器重置为零。

    etl2txt    将日志文件转换为文本格式。
    etl2pcap   将日志文件转换为 pcapng 格式。
    hex2pkt    解码十六进制格式的数据包。

    help       显示特定命令的帮助文本。
               示例:pktmon start help

因为它还利用了 Windows 事件跟踪 (ETW) 框架来捕获网络事件,所以它还会生成 etl-files。以下是如何使用的快速示例:

# 开始捕获数据包并将输出保存到文件
pktmon start --capture pktmon.etl

# 停止捕获
pktmon stop

正如你所看到的,即使语法与 netsh trace 有些不同,但也非常接近。你可以跳过报告参数,这在旧版本中是需要的。这使得调用变得更简洁。


这里是 pktmon 的一个 真正优势:与经典的 netsh trace 不同,捕获的数据可以直接转换为 .pcapng 文件,利用 pktmon 的内置功能。这意味着,在当前操作系统中,你甚至不需要使用额外的工具 etl2pcapng 进行转换。

你可以直接将捕获的数据转换为 .pcapng 文件,以便使用 Wireshark 进行分析:

# 将 .etl 文件转换为 .pcapng 格式
pktmon etl2pcap pktmon.etl

转换后,如果你不再需要,可以删除创建的 etl-filepcapng-file 是你将在 Wireshark 中使用的文件。因为 pcapng 文件仅包含流量数据,而不是关于系统和进程的额外信息,所以它比 etl 文件更轻量。但在长时间捕获或高流量的情况下,它仍然可能相当大。


正如 netsh trace 所述,pktmon 也提供了许多过滤选项。同样,你可以指定协议过滤器、IP 地址等,以减少捕获的数据量。 你可以通过运行 pktmon filter add help 查看所有可用选项。这将为你提供一个详细的可用过滤器和选项列表,以便你自定义捕获。主要的区别在于,你需要在开始捕获之前添加过滤器,这与 netsh trace 不同,后者可以直接在启动命令中指定过滤器。但当你通过脚本执行此操作时,这可能并不是一个大问题。在我看来,这提高了命令的可读性,因为启动命令中没有太多参数,而是更分离和结构化。

以下是一些可以与 pktmon 一起使用的过滤器示例:

# 仅捕获 IPv4 流量:
pktmon filter add -p IPv4


# 仅捕获 TCP/UDP 或两者:
pktmon filter add -p TCP
pktmon filter add -p UDP

# 将捕获限制为特定 IP 地址:
pktmon filter add -a IPv4.SourceAddress <IPv4 地址>
pktmon filter add -a IPv4.DestinationAddress <IPv4 地址> 
pktmon filter add -a IPv4.Address <IPv4 地址>

你可以多次执行过滤器添加命令以添加多个过滤器,这一点非常有用,因为它允许你逐步构建过滤器配置并保持更有序。你还可以使用 pktmon filter list 列出当前配置的过滤器,以查看在开始捕获之前当前活动的过滤器。

3. Get-NetEventSession - PowerShell 原生方式

如果你是 PowerShell 爱好者,这里有另一种使用 Get-NetEventSession cmdlet 捕获网络流量的方法,它是 NetEventPacketCapture 模块的一部分。此 cmdlet 允许你创建和管理网络事件会话,可用于捕获网络流量。尽管这需要更多的文本,但 PowerShell 提供了一些相当有趣的功能:

  • 内置参数的选项卡补全
  • 通过内置 -CimSession 参数进行 PowerShell 远程操作
# 创建一个新的网络事件会话
$session = New-NetEventSession -Name "MySession" -LocalFilePath "C:\path\to\capture.etl"

# 添加提供程序以捕获网络流量(例如,Microsoft-Windows-Kernel-Network)
Add-NetEventProvider -SessionName $session.Name -Name "Microsoft-Windows-Kernel-Network"

# 检查创建的会话
$session


# 启动会话以开始捕获流量
$session | Start-NetEventSession

# 停止会话以结束捕获
$session | Stop-NetEventSession

与命令行工具一样,捕获的流量保存在 .etl 文件中,可以在使用 etl2pcapngpktmon 转换为 .pcapng 格式后进行分析。我不会再次详细说明,因为这是与上述描述相同的过程。


我必须诚实地承认,这 不是我最喜欢的捕获网络流量的方法,因为处理各种命令和网络事件会话及提供程序的基本概念有点复杂。但如果你想完全在 PowerShell 的世界中,它仍然是一个内置且强大的捕获流量的方法。

在下面的 实际示例部分,你会找到一个示例,我使用 PowerShell 远程功能结合上述命令行工具捕获远程系统的网络流量。这是一个相当强大的组合,在我个人看来,结合使用命令行工具和 PowerShell 并没有什么不妥。正如常常所说… 使用最适合你和你的用例的工具。没有一种适合所有人的解决方案。

当然,❤️ PowerShell ❤️ 非常接近一种适合所有人的解决方案。😁

4. 图形用户界面方式:性能监视器

如果你更喜欢在 Windows 中使用经典的基于 MMC 的图形用户界面,你也可以使用内置的性能监视器(PerfMon)。PerfMon 允许你创建数据收集集,可以捕获各种性能指标,包括网络流量。


实际上,以上提到的所有工具都基于相同的底层技术,即 Windows 事件跟踪 (ETW) 框架,它们仅提供不同的接口和不同的功能来捕获事件。性能监视器只是 ETW 的基于 GUI 的接口。

要使用性能监视器捕获网络流量,可以按照以下步骤操作:

  1. 通过在开始菜单中输入 perfmon 并按 Enter 打开性能监视器。
  2. 在左侧窗格中,展开 “数据收集集",右键单击 “用户定义"。选择 “新建” > “数据收集集"。
  3. 给你的数据收集集命名(例如,"NetworkTrafficCapture"),并选择 “手动创建(高级)"。点击 “下一步"。
  4. 在 “创建数据收集器” 步骤中,选择 “性能计数器” 并点击 “下一步"。
  5. 点击 “添加” 以添加性能计数器。在 “添加计数器” 对话框中,展开 “网络接口” 并选择你想要捕获的计数器(例如,"Bytes Total/sec"、"Packets/sec")。点击 “添加” 然后 “确定"。
  6. 点击 “下一步” 并指定你想要保存捕获数据的位置。点击 “下一步” 然后 “完成” 创建数据收集集。
  7. 要开始捕获网络流量,右键单击你新创建的数据收集集(例如,"NetworkTrafficCapture")并选择 “开始"。性能计数器将开始捕获数据。
  8. 要停止捕获,再次右键单击数据收集集并选择 “停止"。捕获的数据将保存在指定位置。


如果你想通过不同的时间表和较长时间捕获与网络流量相关的性能指标,这是一种特别有用的方法。这不是快速捕获和分析的最佳方法,但在监控和分析网络性能方面非常有用。

除了调度之外,这种定义的数据收集集可以轻松导出并导入到其他系统,这对于在多个服务器或工作站之间标准化捕获过程非常有用。如果你将各种指标与网络流量捕获结合在一起,例如 CPU 使用率、内存使用率、磁盘 I/O 等,以便更全面地了解系统的性能和行为与网络流量的关系,这尤其有用。

我不打算详细说明,因为这篇博客文章的主要目的是展示如何快速捕获和在控制台中进行操作。

实际示例

仅捕获 HTTP 或 HTTPS 流量

这可能是一个常见的用例。 不幸的是,据我所知,netsh trace start 没有内置功能来捕获特定端口。😣 过滤器不允许你如此具体。但使用 pktmon 你可以轻松做到这一点。值得一提的是,这仅在 Windows Server 2019 和 Windows 10+ 版本 1809 及更高版本中可行。

你可以使用以下命令仅捕获 HTTP 和 HTTPS 流量:

pktmon filter add "http + https" -d IPv4 -t TCP -p 80 443
pktmon start --capture --file-name https_traffic.etl

pktmon stop
pktmon filter remove

仅捕获 DNS 流量

如果您只对捕获 DNS 流量感兴趣,可以使用以下命令仅捕获 DNS 流量:

pktmon filter add "UDP DNS" -d IPv4 -t UDP -p 53
pktmon filter add "TCP DNS" -d IPv4 -t TCP -p 53
pktmon start --capture --file-name dns_traffic.etl

pktmon stop
pktmon filter remove

仅捕获 SMTP 流量

如果您想仅捕获 SMTP 流量,可以使用以下命令仅捕获 SMTP 流量:

pktmon filter add "SMTP" -d IPv4 -t TCP -p 25
pktmon start --capture --file-name smtp_traffic.etl

pktmon stop
pktmon filter remove

这只是另一个快速示例,展示了如何使用 `pktmon` 的过滤功能仅捕获特定类型的流量。

通过特定 IP 使用 netsh trace 捕获

如果您被迫使用 netsh trace,因为旧操作系统或更喜欢使用它,我建议您指定系统的 IP 过滤器。这样可以切断广播和其他可能与您的系统无关的流量。

首先准备您的 IP 过滤器和捕获的文件路径:

$localIpList = (Get-NetIPAddress -AddressState Preferred -PrefixOrigin Dhcp, Manual -AddressFamily IPv4).ipaddress
$ipFilter = "($($localIpList -join ","))"
$filePath = "traffic.etl"

然后使用 IP 过滤器开始捕获:

netsh trace start capture=yes report=disabled overwrite=yes fileMode=circular Protocol="(UDP,TCP)" tracefile="$($filePath)" IPv4.Address=$ipFilter

检查捕获状态:

netsh trace show status

完成您的操作,当您完成时,停止捕获:

netsh trace stop

通过这种方法,您可以轻松捕获与您的系统相关的流量,这可以帮助您专注于重要数据并减少捕获中的噪音。这在网络流量较大的环境中特别有用,因为捕获所有内容会导致非常大且难以处理的捕获文件。

通过 PowerShell 远程捕获流量

我想概述另一个我在现实生活中多次使用的实用案例。当涉及到多个服务器的大型环境时,逐一登录每个服务器并执行捕获命令并不是很高效。

这正是 PowerShell 远程的优势所在。🎉

您可以将 PowerShell 远程功能与上述命令行工具结合起来,轻松在任意数量的系统上捕获流量。我认为这是一个相当强大的组合!

以下是如何做到这一点的快速示例:
(显而易见,您可以根据特定用例的需要自定义脚本块以包含其他过滤器或参数)

# 定义您想要捕获流量的远程服务器列表
$remoteServers = @("Server1", "Server2", "Server3")

# 定义远程服务器上的基本路径和文件名
$remoteBasePath = "C:\Administration\Logs"
$remoteCaptureFileName = "traffic_http"

# 创建到远程服务器的会话
$sessions = New-PSSession -ComputerName $remoteServers

# 定义使用 pktmon 开始捕获网络流量的脚本块
$scriptStart = {
    $filePath = "$($using:remoteBasePath)\$($using:remoteCaptureFileName)_$($env:COMPUTERNAME)_$(Get-Date -Format 'yyyy-MM-dd-HH-mm-ss').etl"
    
    PktMon.exe filter add "HTTP" -d IPv4 -t TCP -p 80
    PktMon.exe start --capture --file-name "$($filePath)"
}

# 使用 PowerShell 远程在每个远程服务器上执行脚本块
Invoke-Command -Session $sessions -ScriptBlock $scriptStart

现在,您可以进行操作以获取所需内容…

您可以使用以下命令检查每个远程服务器上的捕获状态:

Invoke-Command -Session $sessions -ScriptBlock { PktMon.exe status }

当您准备好时,可以停止捕获并在每个远程服务器上将捕获的数据转换为 .pcapng 格式,使用以下命令:

$scriptStop = {
    # 停止捕获
    PktMon.exe stop | Out-Null
    
    # 移除过滤器(为下次捕获保持干净)
    PktMon.exe filter remove | Out-Null
    
    # 将 .etl 文件转换为 .pcapng 格式
    PktMon.exe etl2pcap $filePath
    
    # 转换后清除原始 .etl 文件
    Remove-Item -Path $filePath -Force
}
Invoke-Command -Session $sessions -ScriptBlock $scriptStop

现在,您已经在每个远程服务器上捕获了流量,但同样,您在每个服务器上都有一个捕获文件。幸运的是,PowerShell 在这种情况下也能帮助您。您可以使用相同的远程功能将捕获的文件复制到本地工作站,以便使用 Wireshark 进行分析。您可以使用 Copy-Item cmdlet 和 -ToSession 参数将文件从远程服务器复制到本地计算机。

# 定义您想要保存捕获文件的本地路径
$localPath = Join-Path -Path $home -ChildPath "LocalData"

# 将捕获的文件从每个远程服务器复制到本地计算机
foreach ($session in $sessions) {
    $remoteFilePath = "$($remoteBasePath)\$($remoteCaptureFileName)_*.pcapng"
    Copy-Item -Path $remoteFilePath -Destination $localPath -FromSession $session
}

# 在复制后从远程服务器清除 pcapng 文件
Invoke-Command -Session $sessions -ScriptBlock {
    Remove-Item -Path ($filePath -replace ".etl", ".pcapng") -Force
}

完成后,删除与服务器的会话:

# 删除与远程服务器的会话
Remove-PSSession -Session $sessions

正如这个例子所示,您可以轻松地在多个系统上捕获网络流量,通过 **结合 `PowerShell` 和 `pktmon`**。这种方法使您能够高效地管理和分析整个环境中的网络流量,而无需手动干预或在远程服务器上安装任何东西。 这个例子假设您有 - 多或少 - 当前版本的 Windows。如果您的系统上没有 `pktmon`,只需将 `pktmon` 命令替换为相应的 `netsh trace` 命令。

请参阅上面的 netsh 示例,获取如何使用它的想法。脚本块的整体结构将保持不变。

结论

在 Windows 中捕获网络流量可以 轻松 使用各种内置工具完成,每种工具都有其自身的优点和使用案例。无论您更喜欢像 netsh tracepktmon 这样的命令行工具,还是像性能监视器这样的图形界面,都有适合不同需求和偏好的选项可供选择。

对于快速捕获和分析,pktmon 是一个很好的选择,因为它易于使用并具有直接转换功能。(如果您使用的是 Windows Server 2019 或 Windows 10+ 版本在 1809 之后)在旧系统上,netsh trace 可以是一个强大的工具,能够完成任务。

而对于那些更喜欢 GUI 的用户,性能监视器提供了一种全面的方式来捕获和分析网络性能指标。最终,在 Windows 中捕获网络流量的最佳工具取决于您的具体需求和您分析所需的详细程度。