Как извлечь изображения из HTTP-сессии, используя netfilter, Scapy и Python 3? - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь создать код, который извлекает изображения из HTTP-трафика, используя nfqueue и scapy. Я реализовал код, который захватывает сетевой трафик в очередь Python nfqueueu. Код в Scapy находит заголовки HTTP. Однако у меня есть проблема с "сбором" всех частей ответа HTTP, чтобы я мог извлечь изображения. И мой вопрос, как это сделать правильно?

Я последовал примеру извлечения изображений из файла pcap.

    def preprocesing_packets(self, packet):
        # packet in nfqueue
        pkt: IP = IP(packet.get_payload())

        # setup variable for image
        image = b''

        if pkt.haslayer(TCP): #and (pkt[TCP].sport == 80 or pkt[TCP].dport == 80):
            payload: http.HTTP = pkt[TCP].payload
            self.http_header_exists = False

            try:
                if hasattr(payload, 'Headers'):
                    http_header = getattr(payload, 'Headers')

                    print("[*] Heeader exists \n:", pkt.src, ":", pkt.sport, pkt.dst, ":", pkt.dport, http_header)
                    if http_header:
                        self.http_header_exists = True

            except Exception as err:
                print(err)
                pass

            if not self.http_header_exists and self.http_payload:
                self.http_payload += payload
                print("add payload")
                print(len(self.http_payload))

            elif self.http_header_exists and self.http_payload:

                http_header_raw = self.http_payload[:self.http_payload.index(b"\r\n\r\n") + 2]
                http_header_parsed = dict(re.findall(r"(?P<name>.*?): (?P<value>.*?)\r\n", http_header_raw.decode("utf8")))
                if "Content-Type" in http_header_parsed.keys():
                    if "image" in http_header_parsed["Content-Type"]:
                        image_payload = self.http_payload[self.http_payload.index(b"\r\n\r\n") + 4:]
                        if image_payload:

                            self.extract_payload(http_header_parsed, image_payload, 'images')
                            self.http_payload = payload

                elif self.http_header_exists and not self.http_payload:
                    self.http_payload = payload


        packet.set_payload(bytes(pkt))
        packet.accept()


    def extract_payload(self, http_headers, payload, output_path):
        print('extract')
        payload_type = http_headers["Content-Type"].split("/")[1].split(";")[0]
        try:
            if "Content-Encoding" in http_headers.keys():
                if http_headers["Content-Encoding"] == "gzip":
                    file = zlib.decompress(payload, 16 + zlib.MAX_WBITS)
                elif http_headers["Content-Encoding"] == "deflate":
                    file = zlib.decompress(payload)
                else:
                    file = payload
            else:
                file = payload
        except:
            pass

        filename = uuid.uuid4().hex + "." + payload_type
        file_path = output_path + "/" + filename
        fd = open(file_path, "wb")
        fd.write(file)
        fd.close()

Редактировать: 1

Я изменил свой код, чтобы изменить запрос GET и точно изменить URL-адрес изображения. Сценарий работает, обнаруживает запросы и изменяет URL, но страницы загружаются нормально, с оригинальными изображениями. Я проверил в Wireshark и после каждого несанкционированного запроса я получаю ошибку HTTP Bad Request.

Как это исправить?

    def preprocesing_packets(self, packet):
        pkt: IP = IP(packet.get_payload())
        self.counter += 1
        #print(self.counter, packet)

        if pkt.haslayer(TCP) and (pkt[TCP].dport == 8080 or pkt[TCP].dport == 80 or pkt[TCP].dport == 8000) and pkt[TCP].payload:

            http_request: http.HTTPRequest = pkt[TCP].payload
            http_request.show()
            payload_before = len(pkt[TCP].payload)

            if hasattr(http_request, "Method") and getattr(http_request, "Method") == b"GET":
                #print("MAMY GET")
                #print(http_request)

                if hasattr(http_request, "Accept-Encoding") and getattr(http_request, "Accept-Encoding") and (
                    hasattr(http_request, "Path") and hasattr(http_request, 'Host')) and hasattr(http_request, 'Referer'):

                    if b"gzip" in getattr(http_request, "Accept-Encoding"):
                        host = getattr(http_request, "Host")
                        path = getattr(http_request, "Path")
                        url = host + path

                        if (b'.jpg' or b'.bmp' or b'.gif') in url:
                            myurl = self.myhost + self.mypath
                            print(url, '->', myurl)
                            setattr(http_request, "Host", self.myhost)
                            setattr(http_request, "Path", self.mypath)
                            # setattr(http_request, "Referer", self.myreferer)
                            payload_after = len(pkt[TCP].payload)
                            payload_dif = payload_after - payload_before
                            del pkt[IP].len
                            #pkt[IP].len = pkt[IP].len + payload_dif
                            del pkt[IP].chksum
                            del pkt[TCP].chksum
                            pkt.show(dump=True)
                            packet.set_payload(bytes(pkt))
        packet.accept()

enter image description here

Есть ли способ это исправить?

...