【问题标题】:How to hijack all local http request and extract the url using c?如何劫持所有本地http请求并使用c提取url?
【发布时间】:2010-05-07 02:32:37
【问题描述】:

我应该往哪个方向发展(librariesdocuments)?

更新

有人可以说明如何使用 winpcap 来完成这项工作吗?

更新 2

如何验证数据包是否为 HTTP 数据包?

【问题讨论】:

  • 您不需要编写任何软件来执行此操作。使用具有loggingproxy
  • 请注意,给出的答案允许您记录或监控 URL,但肯定不会劫持:“在用户不知情的情况下更改软件设置,以迫使该用户访问某个网站”(维基词典)。您可能误用了该术语或使用了其他术语。
  • 很抱歉对马特提出异议,但鱿鱼确实“劫持”了。我的意思是它允许你用不同的 url 替换用户输入的那个(如果这是你作为程序员想要做的)。主要功能是缓存东西,但它可以做的比你想要的更多。

标签: c http winpcap


【解决方案1】:

如果你所说的“劫持”是指嗅探数据包,那么你应该用 WinPcap 做什么:

  1. 找到您要使用的设备 - See WinPcap tutorial

  2. 使用pcap_open打开设备

    // Open the device
    char errorBuffer[PCAP_ERRBUF_SIZE];
    pcap_t *pcapDescriptor = pcap_open(source,                // name of the device
                                       snapshotLength,        // portion of the packet to capture
                                                              // 65536 guarantees that the whole packet will be captured on all the link layers
                                       attributes,            // 0 for no flags, 1 for promiscuous
                                       readTimeout,           // read timeout
                                       NULL,                  // authentication on the remote machine
                                       errorBuffer);          // error buffer
    
  3. 使用从描述符中读取数据包的函数,例如pcap_loop

    int result = pcap_loop(pcapDescriptor, count, functionPointer, NULL);
    

    这将循环直到发生错误或使用特殊方法调用中断循环。它会为每个数据包调用functionPointer。

  4. 在函数指向的实现解析数据包的东西,它应该看起来像pcap_handler

    typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
             const u_char *);
    
  5. 现在剩下的就是解析缓冲区位于const u_char* 中且长度位于pcap_pkthdr 结构caplen 字段中的数据包。

    假设您有基于 TCP 的 HTTP GET over IPv4 over Ethernet 数据包,您可以:

    • 跳过以太网标头的 14 个字节。
    • 跳过 IPv4 标头的 20 个字节(假设没有 IPv4 选项,如果您怀疑 IPv4 选项是可能的,您可以读取 IPv4 标头的 5-8 位,将其乘以 4,这将是数字IPv4 标头占用的字节数)。
    • 跳过 TCP 标头的 20 个字节(假设没有 TCP 选项,如果您怀疑 TCP 选项是可能的,您可以读取 TCP 标头的 96-99 位,将其乘以 4,这将是数字TCP 标头占用的字节数)。
    • 数据包的其余部分应该是 HTTP 文本。第一个和第二个空格之间的文本应该是 URI。如果太长,您可能需要进行一些 TCP 重建,但大多数 URI 都足够小,可以放入一个数据包中。

      更新:在代码中看起来是这样的(我没有测试就写了):

      int tcp_len, url_length;
      uchar *url, *end_url, *final_url, *tcp_payload;
      
      ... /* code in http://www.winpcap.org/docs/docs_40_2/html/group__wpcap__tut6.html */
      
      /* retireve the position of the tcp header */
      ip_len = (ih->ver_ihl & 0xf) * 4;
      
      /* retireve the position of the tcp payload */
      tcp_len = (((uchar*)ih)[ip_len + 12] >> 4) * 4;
      tcpPayload = (uchar*)ih + ip_len + tcp_len;
      
      /* start of url - skip "GET " */
      url = tcpPayload + 4;
      
      /* length of url - lookfor space */
      end_url = strchr((char*)url, ' ');
      url_length = end_url - url;
      
      /* copy the url to a null terminated c string */
      final_url = (uchar*)malloc(url_length + 1);
      strncpy((char*)final_url, (char*)url, url_length);
      final_url[url_length] = '\0';
      

您还可以通过创建和设置 BPF 仅过滤 HTTP 流量。 See WinPcap tutorial。您可能应该使用过滤器"tcp and dst port 80",它只会为您提供计算机发送到服务器的请求。

如果您不介意使用 C#,您可以尝试使用 Pcap.Net,它会更轻松地为您完成所有这些工作,包括解析数据包的以太网、IPv4 和 TCP 部分。

【讨论】:

  • 是否可以自动执行第 1 步?看来教程需要手动指定一个设备。
  • 当然,您仍然必须选择一种或简单地为所有设备选择。很多时候你只有一个设备,所以你可以简单地选择第一个。您还可以通过使用它们的属性(如它们的 IP)来自动选择。参见 WinPcap 教程的另一部分:winpcap.org/docs/docs_411/html/group__wpcap__tut2.html
  • @brickner,你能否详细说明如何验证一个数据包是否是pcap_handler内的HTTP数据包?
  • 最好的办法是先验证端口。为了过滤请求(如 HTTP GET),您应该确保目标端口为 80。这可以使用我之前提到的过滤器 (BPF) 轻松完成,它还验证它是 TCP over IPv4 数据包。如果您不使用 BPF,则可以通过查看 TCP 标头来验证目标端口。 TCP 标头的第 3 和第 4 字节代表端口号。为了确保 HTTP 请求是 GET,您可以确保 HTTP 部分(TCP 有效负载)中第一个空格之前的字节是 ASCII 编码中表示“GET”的字节。
  • 这里是提取地址部分的demo,你能详细说明如何根据这个提取url吗? winpcap.org/docs/docs_40_2/html/group__wpcap__tut6.html
【解决方案2】:

这听起来可能有点矫枉过正,但 Web 代理/缓存服务器 Squid 正是这样做的。几年前,我的公司使用它,我不得不在本地调整代码以在访问某些 URL 时提供一些特殊警告,这样我就知道它可以做你想做的事。您只需要找到您想要的代码并将其用于您的项目。我使用了 2.X 版本,我看到它们现在已经达到 3.X,但我怀疑代码的这方面在内部没有太大变化。

您没有说 Windows 是“要求”还是“偏好”,但根据该网站: http://www.squid-cache.org/ 两者都可以。

【讨论】:

  • 不,我想自己实现。
  • 不想引发一场激烈的战争,但你只是在 winpcap 评论中问别人如何为你做这件事的事实让我想知道......
【解决方案3】:

【讨论】:

  • 你能说明如何使用它来实现我的目标吗?
【解决方案4】:

您可能想查看tcpdump 的源代码以了解它是如何工作的。 tcpdump 是一个 Linux 命令行实用程序,用于监视和打印网络活动。不过,您需要对机器具有 root 访问权限才能使用它。

【讨论】:

  • @Runner:如果您对纯 Windows 解决方案感兴趣,可以添加 [windows] 标签。
  • 不仅是windows,还有windows和linux。
猜你喜欢
  • 2013-11-10
  • 2011-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-25
  • 2017-10-29
  • 1970-01-01
相关资源
最近更新 更多