微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将Python2脚本移植到Python3-struct Libary

如何解决将Python2脚本移植到Python3-struct Libary

我正在socks5代理服务器上工作,现在正在实现一种ICMP隧道方法,以通过ICMP协议来隧道SSH流量,从而绕过防火墙限制。

那是我使用的开放源代码https://github.com/sanecz/pingtunnel

    def create(self):
        pack_str = "!BBHHH4sH"
        pack_args = [self.type,self.code,self.id,self.sequence,socket.inet_aton(self.dest[0]),self.dest[1]]

        if self.length:
            pack_str += "{}s".format(self.length)
            pack_args.append(self.data)

        self.checksum = self._checksum(struct.pack(pack_str,*pack_args)) 
        pack_args[2] = self.checksum
        return struct.pack(pack_str,*pack_args)

显然,这部分代码给我带来了麻烦,我必须在python3中运行此代码才能匹配我的Socks5代理和反向端口转发。

self.checksum = self._checksum(struct.pack(pack_str,*pack_args))

此行给我一个错误提示“期望值不是整数”。

在这里

        while count < countTo:
            thisVal = ord(packet[count+1]) * 256 + ord(packet[count])
            csum = csum + thisVal
            csum = csum & 0xffffffff
            count = count + 2

        if countTo < len(packet):
            csum = csum + ord(packet[len(packet) - 1])
            csum = csum & 0xffffffff

删除了以csum = csum & 0xffffffff行结尾的L。

有人可以帮助我移植此ICMP.py脚本并进行解释吗?

解决方法

嘿,我努力尝试了几次,以解决自己的问题!

这是修改后的代码:

#!/usr/bin/python3

import socket
import struct

ICMP_ECHO = 0
ICMP_ECHO_REQUEST = 8

class ICMPPacket(object):
    def __init__(self,type,code,checksum,id,sequence,data,source_ip,dest=(None,None)):
        self.type,self.code,self.checksum = type,checksum
        self.id,self.sequence,self.data = id,data
        self.dest = dest
        self.source_ip = source_ip
        self.length = len(self.data)

    def __repr__(self):
        return "<ICMP packet: type = {s.type},code = {s.code}," \
            "data length = {length}".format(s=self,length=len(self.data))

    def __str__(self):
        return "Type of message: {s.type},Code {s.code},"\
            "Checksum: {s.checksum},ID: {s.id},Sequence: {s.sequence}," \
            "Data: {s.data},Data length: {length}".format(s=self,length=len(self.data))

    def create(self):
        #print("\nEntering CREATE!!\n\n")
        pack_str = "!BBHHH4sH"
        pack_args = [self.type,self.id,socket.inet_aton(self.dest[0]),self.dest[1]]

        if self.length:
            pack_str += "{}s".format(self.length)
            #print("PACK STR: " + pack_str)
            pack_args.append(self.data)

        #print("Pack ARGS: \n",pack_args,"\n")
        self.checksum = self._checksum(struct.pack(pack_str,*pack_args)) 
        #print("CHECKSUM: ",self.checksum)
        pack_args[2] = self.checksum
        return struct.pack(pack_str,*pack_args)

    @classmethod
    def parse(cls,packet):
        ip_pack_str = "BBHHHBBH4s4s"
        icmp_pack_str = "!BBHHH4sH"
        data = ""

        ip_packet,icmp_packet = packet[:20],packet[20:] # split ip header

        ip_packet = struct.unpack(ip_pack_str,ip_packet)

        source_ip = ip_packet[8]
        icmp_pack_len = struct.calcsize(icmp_pack_str)
        packet_len = len(icmp_packet) - icmp_pack_len

        if packet_len > 0:
            icmp_data_str = "{}s".format(packet_len)
            data = struct.unpack(icmp_data_str,icmp_packet[icmp_pack_len:])[0]

        type,dest_ip,\
            dest_port = struct.unpack(icmp_pack_str,icmp_packet[:icmp_pack_len])

        return cls(type,socket.inet_ntoa(source_ip),(socket.inet_ntoa(dest_ip),dest_port))


    @staticmethod
    def _checksum(packet):
        #print("Argument for checksum: !!\n",packet)
        packet = packet.decode('ISO-8859-1') # edited to match python3 
        csum = 0
        countTo = (len(packet) / 2) * 2
        count = 0

        while count < countTo:
            thisVal = ord(packet[count+1]) * 256 + ord(packet[count])
            #print("THISVAL: ",thisVal)
            csum = csum + thisVal
            csum = csum & 0xffffffff
            count = count + 2

        if countTo < len(packet):
            csum = csum + ord(packet[len(packet) - 1])
            csum = csum & 0xffffffff

        csum = (csum >> 16) + (csum & 0xffff)
        csum = csum + (csum >> 16)
        checksum = ~csum
        checksum = checksum & 0xffff
        checksum = checksum >> 8 | (checksum << 8 & 0xff00)
        return checksum

我使用packet = packet.decode('ISO-8859-1')重新编码了数据包以使其与字节匹配

以匹配此行thisVal = ord(packet[count+1]) * 256 + ord(packet[count])

因为它需要一个字符串,而是接收一个INT。

因此将其解码为字符串可以解决此问题!

编辑:如果您对处理数据包二进制数据的更好编码有任何建议,请告诉我。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。