将PyQt5 WebEngine请求转换为IP数据包,反之亦然

问题描述 投票:1回答:1

[使用PyQt5,我已经成功设置了QWebEngineUrlRequestInterceptor子类,并且可以修改Web请求的标头和数据。我正在为类似VPN的应用程序构建此应用程序,在该应用程序中,请求被转换为数据包(使用scapy的IP()对象或类似模块发送),加密并发送到另一个地址,该地址将解密并将数据包数据转换回QWebEngine请求。我的问题是如何将用PyQt5拦截的Web请求转换为IP数据包格式,反之亦然?

这里是拦截器代码:

#Custom url interceptor for modifying headers
#and the url before sending it on
class UrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
  def __init__(self,parent=None):
    super(QWebEngineUrlRequestInterceptor,self).__init__(parent)

  def interceptRequest(self,info):
    #Modify the actual request here - todo: block the
    #request here, packet simulate etc...
    info.setHttpHeader(b"Accept-Language",InterClassVariables.languageCode.encode())
python pyqt pyqt5 interceptor packet
1个回答
0
投票

问题是,当您需要IP信息(第3层)时,QWebEngineUrlRequestInterceptor与HTTP(第7层)进行交互。 QWebEngineUrlRequestInfo没有任何IP属性(同样位于第7层)。

虽然可以使用Qt的QHostInfo,但使用香草Python更简单。在这里,我们使用netifaces。尽管alternatives不在标准库中,但它更复杂,与平台有关或需要Internet连接。

import socket

from PyQt5.Qt import QUrl
from PyQt5.Qt import QWebEngineUrlRequestInterceptor
from PyQt5.Qt import QWebEngineUrlRequestInfo
import netifaces
from scapy.all import IP

#Custom url interceptor for modifying headers
#and the url before sending it on
class UrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
  def __init__(self,parent=None):
    super(QWebEngineUrlRequestInterceptor,self).__init__(parent)
    self.info = None

  def interceptRequest(self, info: QWebEngineUrlRequestInfo):
    #Modify the actual request here - todo: block the
    #request here, packet simulate etc...
    self.info = info
    self.info.setHttpHeader(b"Accept-Language",
      InterClassVariables.languageCode.encode())
    self.sendPacket()

  def getDestIp(self):
    qUrl = self.info.requestURL()
    url = qUrl.toString()
    dest_ip = socket.gethostbyname(url)
    return dest_ip

  def sendPacket()
    src_ip = netifaces.gateways()['default'][netifaces.AF_INET][0]
    dest_ip = get_dest_ip(self.info)
    ip_layer = IP(src=src_ip, dst=dest_ip)
    other_layers = OTHER_PROTOCOLS() # FIXME
    pkt = ip_layer/other_layers
    send(pkt) # Choose whichever send function is most appropriate here

如果我们打印数据包(没有其他层),我们应该得到类似的内容:

$ python project.py -show-packet # Pseudo cli
###[ IP ]###
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 1
  flags     =
  frag      = 0
  ttl       = 64
  proto     = ip
  chksum    = None
  src       = 172.31.98.1
  dst       = 151.101.65.69
  \options   \

© www.soinside.com 2019 - 2024. All rights reserved.