HTTP

Scapy本机支持HTTP包的发送/接收。

HTTP 1.X版

备注

增加了对http1.X的支持 2.4.3 ,而http2.X已经在 2.4.0 .

关于HTTP 1.X

HTTP 1.X是一个 文本协议 . 现在这些都很不寻常(HTTP2.X是二进制的),因此它的实现非常不同。

出于传输目的,HTTP1.X帧在连接过程中被分割成不同的片段,这些片段可能被编码,也可能没有被编码。这是解释完毕https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Transfer-Encoding

总而言之,框架可以分为三种不同的方式:

  • chunks :分割成块,称为块,前面加上它们的长度。帧的结尾由空块标记

  • 使用 Content-Length :HTTP帧的头声明帧的总长度

  • 以上都不是:当TCP流结束/当TCP推送发生时,HTTP帧结束。

此外,根据HTTP报头中指定的算法,可以对每个帧进行额外压缩:

  • compress :压缩使用 LZW

  • deflate :压缩使用 ZLIB

  • br :压缩使用 布罗特利

  • gzip

让我们看看使用Scapy执行HTTPRequest时会发生什么 TCP_client (解释如下):

../_images/http_tcp.png

一旦第一个SYN/ACK完成,就建立了连接。Scapy会把 HTTPRequest() ,主机将用HTTP片段进行应答。Scapy将对每一个进行确认,并使用 TCPSession ,就像Wireshark在显示答案框时所做的那样。

HTTP 1.X在Scapy中

让我们列出模块的内容:

>>> explore(scapy.layers.http)
Packets contained in scapy.layers.http:
Class       |Name
------------|-------------
HTTP        |HTTP 1
HTTPRequest |HTTP Request
HTTPResponse|HTTP Response

有两个可用的框架: HTTPRequestHTTPResponse . 这个 HTTP 仅在解剖过程中使用,作为在两者之间进行选择的实用程序。应支持所有公共头字段。

  • 默认HTTPRequest:

>>> HTTPRequest().show()
###[ HTTP Request ]###
  Method= 'GET'
  Path= '/'
  Http_Version= 'HTTP/1.1'
  A_IM= None
  Accept= None
  Accept_Charset= None
  Accept_Datetime= None
  Accept_Encoding= None
  [...]
  • 默认HTTPResponse:

>>> HTTPResponse().show()
###[ HTTP Response ]###
  Http_Version= 'HTTP/1.1'
  Status_Code= '200'
  Reason_Phrase= 'OK'
  Accept_Patch43= None
  Accept_Ranges= None
  [...]

使用Scapy发送/接收http1.X

为了处理这种减压,Scapy使用 Sessions classes ,更具体地说 TCPSession 班级。有几种使用方法:

sniff(session=TCPSession, [...])

TCP_client.tcplink(HTTP, host, 80)

执行解压缩/碎片整理
同时在所有TCP流上,但是
只是被动地行动。
充当TCP客户端:处理SYN/ACK,
但只创建所有
一条小溪。

例子:

  • TCP_client.tcplink

向发送HTTPRequest www.secdev.org 并将结果写入文件:

load_layer("http")
req = HTTP()/HTTPRequest(
    Accept_Encoding=b'gzip, deflate',
    Cache_Control=b'no-cache',
    Connection=b'keep-alive',
    Host=b'www.secdev.org',
    Pragma=b'no-cache'
)
a = TCP_client.tcplink(HTTP, "www.secdev.org", 80)
answer = a.sr1(req)
a.close()
with open("www.secdev.org.html", "wb") as file:
    file.write(answer.load)

TCP_client.tcplink 让它感觉好像只收到了一个包,但实际上它是在 TCPSession . 如果你表演了 sniff() ,你会看到那些包裹的。

此代码在实用程序函数中实现: http_request() ,可用作:

load_layer("http")
http_request("www.google.com", "/", display=True)

这将在您的默认浏览器中打开网页,这归功于 display=True .

  • sniff()

剖析一个pcap,其中包含使用块通过HTTP发送的JPEG图像。

备注

这个 http_chunk.pcap.gz 文件位于 scapy/test/pcaps

load_layer("http")
pkts = sniff(offline="http_chunk.pcap.gz", session=TCPSession)
# a[29] is the HTTPResponse
with open("image.jpg", "wb") as file:
    file.write(pkts[29].load)

HTTP 2.X版

The HTTP 2 documentation is available as a Jupyter notebook over here: HTTP 2 Tuto