HTTP

Scapy本地支持HTTP数据包的发送/接收.

HTTP 1.X

Note

2.4.3中添加了对HTTP 1.X的支持,而在2.4.0中已经提供了2.4.0 .

About HTTP 1.X

HTTP 1.X是文本协议 . 如今,这已经很不常见了(HTTP 2.X是二进制的),因此其实现方式大不相同.

为了传输目的,HTTP 1.X帧在连接期间分为各种片段,这些片段可能已编码也可能尚未编码. 这是通过https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Transfer-Encoding解释的

总而言之,可以用3种不同的方式拆分框架:

  • chunks :分成称为块的片段,其长度在其前面. 帧的末尾用空块标记

  • 使用Content-Length :HTTP帧的标头宣布帧的总长度

  • 以上都不是:HTTP帧在TCP流结束/ TCP推送发生时结束.

此外,取决于HTTP标头中指定的算法,可以逐帧压缩每个帧:

  • compress :使用LZW压缩

  • deflate :使用ZLIB压缩

  • br :使用Brotli压缩

  • gzip

让我们看一下使用Scapy的TCP_client执行HTTPRequest时发生的情况(如下所述):

../_images/http_tcp.png

一旦完成第一个SYN / ACK,就建立了连接. Scapy将发送HTTPRequest() ,主机将使用HTTP片段进行应答. Scapy将对其中的每一个进行确认,并使用TCPSession重新编译它们,就像Wireshark在显示答案帧时TCPSession那样.

HTTP 1.X in 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
  [...]

Use Scapy to send/receive HTTP 1.X

为了处理这种减压,Scapy使用Sessions类 ,更具体地说是TCPSession类. 您有几种使用方式:

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

TCP_client.tcplink(HTTP, host, 80)

执行解压缩/碎片整理
同时在所有TCP流上
仅被动地行动.
充当TCP客户端:处理SYN / ACK,
和所有TCP操作,但仅创建
一股流.

Examples:

  • 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)
answser = a.sr1(req)
a.close()
with open("www.secdev.org.html", "wb") as file:
    file.write(answser.load)

TCP_client.tcplink使其感觉好像只接收到一个数据包,但实际上它已在TCPSession中重新组合了. 如果执行普通的sniff() ,您将看到这些数据包.

此代码在实用程序函数中实现: http_request() ,其http_request()如下:

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

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

  • sniff():

剖析包含通过HTTP使用块发送的JPEG图像的pcap.

Note

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

HTTP 2文档可在此处作为Jupyther笔记本获得: HTTP 2 Tuto