如何使用 SharpPcap 捕获 HTTP 数据包

Posted

技术标签:

【中文标题】如何使用 SharpPcap 捕获 HTTP 数据包【英文标题】:How to capture HTTP packet with SharpPcap 【发布时间】:2010-12-24 05:29:44 【问题描述】:

我想捕获我机器的所有传入 HTTP 数据包。为此,我使用了 SharpPcap,它是一个 WinPcap 包装器。

SharpPcap 工作得很好,但它捕获 TCP 数据包,这太低级了,无法满足我的要求。有谁知道我怎样才能从所有这些 TCP 数据包中轻松获得完整的 HTTP 请求/响应?

谢谢

【问题讨论】:

【参考方案1】:

SharpPcap 已经能够以与 wireshark 相同的方式捕获数据包(只是在代码中而不是在 GUI 中)。您可以直接解析它们,也可以将它们以常见的 .pcap 文件格式转储到驱动器中。

解析捕获的步骤是:

选择一个接口 以混杂模式打开连接 使用 while 循环或事件回调开始捕获 将原始数据包解析为您想要的类型

如果您正在读取 .pcap 转储文件,则过程几乎相同,只是您调用了离线捕获读取器,不需要选择接口,也不需要设置混杂模式。 SharpPcap 支持wireshark、tcpdump 和大多数其他Pcap 框架使用的所有标准过滤器。有关这些的参考,请查看 tcpdump 手册。

目前不支持直接解析HTTP,但是解析TCP包真的很简单。

当您收到原始数据包(未解析)时,请执行以下操作:

TCPPacket packet = TCPPacket.GetEncapsulated(rawPacket);

Packet.Net(SharpPcap 的一个独立和包含的组件)解析器能够直接提取 TCP 部分,即使通信是由 ***、PPoE 或 PPP 封装的。

一旦你解析了 TCPPacket,只需抓取 packet.PayloadBytes 以获取字节数组中的有效负载,该字节数组应包含原始字节中的 HTTP 标头,可以转换为正确的文本格式(我不确定 HTTP 标头是否使用该级别的 UTF-8 或 ASCII 编码)。应该有大量免费可用的工具/库来解析 HTTP 标头。


从 TCP 中提取 HTTP 数据包:

您需要在连接的 tcp 数据包进入时收集它们,如果数据是碎片化的(大于 1500 字节),您需要在内存中重新组装这些部分。要发现哪些部分按什么顺序排列,您需要仔细跟踪序列/确认号。

使用 SharpPcap 完成这项工作并非易事,因为您正在处理堆栈的较低部分并手动重新组装连接。

Wireshark 有一篇关于如何在 C 中完成此任务的有趣文章。

截至目前,SharpPcap 不支持 TCP 负载解析。


如果您正在寻找有关如何使用 SharpPcap 的易于理解的示例,请下载源代码树并查看包含的示例项目。还有一个tutorial for SharpPcap on codeproject。

如果您有更多问题和/或想对项目提出任何功能请求,请随时在 SourceForge 项目上发帖。它远未消亡,仍在积极开发中。

注意:Chris Morgan 是项目负责人,我是 SharpPcap/Packet.Net 的开发人员之一。

更新:关于代码项目的教程项目现已更新以匹配当前 API。

【讨论】:

GetEncapsulated 等于 Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data); 对吧?【参考方案2】:

将 TCP 流解码为 HTTP 请求/响应对并非易事。 WireShark 等工具为此付出了相当大的努力。

我为 Ruby 编写了一个 WireShark 包装器(这对你没有帮助),但在我编写它之前,我尝试使用 tshark(WireShark 的命令行版本)。这并没有解决我的问题,但它可能对你有用。方法如下:

您捕获数据包并将它们写入 pcap 文件(SharpPcap 可能有办法做到这一点)。在某个时候关闭 cap 文件并启动另一个文件,然后在旧文件上运行 tshark 并使用 HTTP 流量过滤器和一个指示您希望以 PDML 格式输出的标志。您会发现这是一种 XML 格式,可以使用 System.Xml 工具轻松解析,其中包含各种格式的每个 HTTP 字段的值。您可以编写 C# 代码来生成 tshark,并将其 StdOut 流通过管道传输到 XML 阅读器中,以便在数据包出现时将其从 tshark 中取出。我不建议使用 DOM 解析器,因为大型捕获文件的 PDML 输出会很快变得疯狂。

除非您的要求很复杂(就像我的一样),否则这可能就是您所需要的。

【讨论】:

有趣的是,PDML 是一种众所周知的标准格式还是一种特定于应用程序的一次性。 SharpPcap 中的上限可以通过两种方式完成:对于低/中等流量,可以实时捕获/解析数据包;对于高流量捕获(如 ftp 传输),最好的选择是将原始上限转储到 .pcap 文件并在之后进行后处理。 SharpPcap 基本上只是一个跨平台框架,用于将类似wireshark 的捕获构建到C# 应用程序中。现在 SharpPcap 是 pcap 包装器,Packet.Net 是解析器库。 您是否将代码发布在某个地方(例如 GitHub)。如果是这样,我想在某个时候看看它。我想看看管理 TCP 重新组装步骤需要多少代码/工作量。 我不知道PDML是标准还是wireshark特有的东西;无论如何,它很容易处理。 我的 Ruby 扩展的代码在 github.com/anelson/rcapdissector。请注意,这是针对几年前的 WireShark 版本构建的。如果不使用最新的 WireShark 源代码进行修改,它可能无法编译。 谢谢。我不需要它来编译。出于个人的好奇心,我只是想看看它是如何工作的。我花了很多时间阅读 RFC 和实现解析器,所以我很欣赏从(模棱两可的)规范到可用代码的工作。【参考方案3】:

我认为您已接近解决方案:如果您有来自 HTTP 流量的 TCP 数据包,则只需提取 TCP 有效负载即可重建 HTTP 请求/响应。请参阅此SO entry 了解可能的方法。

【讨论】:

以上是关于如何使用 SharpPcap 捕获 HTTP 数据包的主要内容,如果未能解决你的问题,请参考以下文章

.net 数据包捕获:pcap.net 与 Sharppcap

如何通过Sharppcap获得连续数据包?

SharpPcap 中的离线数据包过滤

SharpPcap - 从标准输出捕获

如何编写 http 隧道

Pcap.net vs Sharppcap