将 Python2 脚本移植到 Python3 - 结构库
Porting Python2 script to Python3 - struct library
我在 socks5 代理服务器上工作,现在我正在实施 ICMP 隧道方法,通过 ICMP 协议通过隧道传输 SSH 流量以绕过防火墙限制。
这是我用的开源:https://github.com/sanecz/pingtunnel
def create(self):
pack_str = "!BBHHH4sH"
pack_args = [self.type, self.code, 0, 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, code, checksum
self.id, self.sequence, self.data = id, sequence, 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.code, 0, self.id, self.sequence,
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, code, checksum, id, sequence, dest_ip, \
dest_port = struct.unpack(icmp_pack_str, icmp_packet[:icmp_pack_len])
return cls(type, code, checksum, id, sequence, data,
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。
因此将其解码为字符串解决了这个问题!
编辑:如果您对处理数据包二进制数据的更好编码有任何建议,请告诉我。
我在 socks5 代理服务器上工作,现在我正在实施 ICMP 隧道方法,通过 ICMP 协议通过隧道传输 SSH 流量以绕过防火墙限制。
这是我用的开源:https://github.com/sanecz/pingtunnel
def create(self):
pack_str = "!BBHHH4sH"
pack_args = [self.type, self.code, 0, 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, code, checksum
self.id, self.sequence, self.data = id, sequence, 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.code, 0, self.id, self.sequence,
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, code, checksum, id, sequence, dest_ip, \
dest_port = struct.unpack(icmp_pack_str, icmp_packet[:icmp_pack_len])
return cls(type, code, checksum, id, sequence, data,
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。
因此将其解码为字符串解决了这个问题!
编辑:如果您对处理数据包二进制数据的更好编码有任何建议,请告诉我。