【问题标题】:Is it possible to create a HTTP response via scapy是否可以通过 scapy 创建 HTTP 响应
【发布时间】:2016-10-13 15:23:07
【问题描述】:

我想通过 scapy 向目标系统发送 HTTP 响应。我知道 scapy 使用分层实现来创建像 IP/TCP/ETHER 这样的数据包。要发送一个简单的 TCP 数据包,我们可以使用以下 scapy 脚本。

#!/usr/bin/python
from scapy.all import *

ip=IP(src="10.10.1.207", dst="10.10.1.60")

payload="Hello World"
PUSH=TCP(sport=80, dport=3389, flags="F")
send(ip/PUSH/payload)

有什么方法可以附加一个 HTTP 层吗? 我尝试了很多方法,但是每次我在目标机器上收到 TCP 数据包而不是 HTTP 响应数据包。

【问题讨论】:

  • 响应包我的意思是当我们尝试访问任何 url 的基本信息时,我们发送一个 get 请求(HTTP),作为响应,我们收到一个响应包,其标头如“HTTP 1.1 200 OK...等”我想通过 scapy(或任何其他工具)创建此响应数据包并将其发送到目标系统。

标签: python http tcp scapy


【解决方案1】:

编辑:这已经过时了。从 Scapy 2.4.3 开始,您可以使用 the http layer

Scapy 没有原生 HTTP 层解析器,但是,您可以轻松发送 HTTP 请求/响应,因为它是文本协议:

RESP  = "HTTP/1.1 200 OK\r\n"
RESP += "Server: exampleServer\r\n"
RESP += "Content-Length: 6\r\n"
RESP += "\r\n"
RESP += "A body"

IP(src="10.10.1.207", dst="10.10.1.60")/TCP(sport=80, dport=3389, flags="A", seq=ACK.ack, ack=ACK.seq)/RESP

ACK 是先前进行的 3 次握手(SYN、SYN-ACK、ACK)的第三段,因为这是通过 TCP 发送数据之前所必需的。

【讨论】:

  • 感谢 Jeff,当我将正文保持在 1460 字节内(即标头+正文)时,这可以正常工作。您还可以建议我发送大小超过 1460 字节的数据(在多个数据包中用于同一响应)吗?如果大小超过 MTU,则帧将被丢弃,这很好。但是有没有办法通过超过 1460 字节的 scapy 向目标系统发送 HTTP 响应?
  • 是的,使用多个 TCP 段。如果我是你,我会先计算我的 HTTP 响应的长度,将它除以我的 MTU,它会给我必要的段数(segments_nb = len(HTTP_resp) / MTU,小心除法的其余部分),然后执行循环将它们与权限序列号一起发送。使用 Scapy 会强制您手动分割数据。
【解决方案2】:

虽然,Scapy 没有对 HTTP 层的原生支持,但是有一个 python 模块可用于扩展 Scapy 的功能以支持 HTTP 层。模块名称为“scapy-http”,可以在 github 上的 invernizzi/scapy-http 找到。

您可以使用 pip 安装它:

 sudo pip install scapy-http

这是来自 github 存储库的示例代码:

#!/usr/bin/env python 尝试: 将 scapy.all 导入为 scapy 导入错误除外: 进口scapy 尝试: # 此导入从项目目录工作 导入 scapy_http.http 导入错误除外: # 如果你通过 pip 安装了这个包,你只需要执行这个 从 scapy.layers 导入 http 数据包 = scapy.rdpcap('example_network_traffic.pcap') 对于数据包中的 p: 打印'=' * 78 p.show()

使用此模块,您可以在不发送自己的文本数据的情况下生成 HTTP 数据包。

【讨论】:

    【解决方案3】:

    正如 Jeff Bencteux 的回答所提到的,http 层现在可以在 scapy 上使用。这可以很容易地做到这一点,这里有一个例子:

    >>>import scapy.all as S
    
    >>>S.load_layer("http") # without this, http might not be loaded as default
    >>> pkg = S.IP() / S.TCP() / HTTP() / HTTPResponse(Server="exampleServer") / "<html></html>"
    

    最后一行末尾的字符串是原始数据。回显pkg 你会得到:

    >>> pkg
    <IP  frag=0 proto=tcp |<TCP  sport=http dport=http |<HTTP  |<HTTPResponse  Server='exampleServer' |<Raw  load='<html></html>' |>>>>>
    

    您应该 read the doc 并且可能会嗅探一些 http 响应以了解您需要修改哪些字段

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-17
      相关资源
      最近更新 更多