Уже пару дней бьюсь…
Это исходник скрипта.
Интересующий фрагмент:
logger.info("start")
src_ip = get_local_ip()
src_port = random.randint(30000, 50000)
logger.debug("local ip address : %s", src_ip)
logger.debug("local port : %d", src_port)
dst_ip = socket.gethostbyname(args.address)
dst_port = args.port
logger.debug("remote ip address : %s", dst_ip)
logger.debug("remote port : %d", dst_port)
ip_header = IPHeader(
src_ip,
dst_ip,
total_len=60,
# ident=secrets.randbits(16),
flags=IPHeader.Flags.MF,
)
# чексумму подставит роутер,если ее не указать
ip_header.check = checksum(ip_header.pack())
options = [
(TCPOption.Kind.MSS, bytes.fromhex("05b4")), # 1460
(TCPOption.Kind.SACK_PERMIT,),
# Не знаю что в TSVal поставить
(TCPOption.Kind.TS, secrets.randbits(32).to_bytes(4) + b"\0\0\0\0"),
(TCPOption.Kind.NOP,),
# (TCPOption.Kind.WIN_SCALE, 7),
(TCPOption.Kind.WIN_SCALE, 0),
]
tcp_header = TCPHeader(
src_port,
dst_port,
seq_num=secrets.randbits(32),
flags=TCPHeader.Flags.SYN,
data_off=10, # 40 bytes,
options=options,
)
tcp_header.check = checksum(tcp_header.pack())
syn_packet = ip_header + tcp_header
logger.debug(syn_packet)
data = syn_packet.pack()
logger.debug("packet data : %s", data.hex(" "))
logger.debug("packet size : %d", len(data))
assert len(data) == ip_header.total_len
try:
# socket.IPPROTO_TCP чтобы сниффить
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
except PermissionError as ex:
raise RuntimeError("root priveleges are required")
# просим не добавлять ip заголовки при отправке (для socket.IPPROTO_RAW не нужно)
# s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# ip.dst == 178.248.233.6 and tcp.flags.syn == 1 (www.linux.org)
# ip.dst == 85.119.149.3 ?
# ip.dst == 93.184.216.34 (example.com)
if 0 == (n_bytes := s.sendto(data, (ip_header.dst_ip, 0))):
raise RuntimeError("packet was not sent")
logger.debug("bytes sent: %d", n_bytes)
response, addr = s.recvfrom(65535)
logger.debug("response : %s", response.hex(" "))
WireShark’ом я вижу, что запрос отправляется на сервер, НО ОТВЕТА не приходит.
Я проверял чексуммы рассчитываются вроде правильно, добавил всякие таймстемпы:
INFO:__main__:start
DEBUG:__main__:local ip address : 192.168.0.104
DEBUG:__main__:local port : 46986
DEBUG:__main__:remote ip address : 178.248.233.6
DEBUG:__main__:remote port : 443
DEBUG:__main__:Compound(items=[IPHeader(src_ip='192.168.0.104', dst_ip='178.248.233.6', version=4, ihl=5, tos=0, total_len=60, ident=0, flags=<Flags.MF: 2>, frag_off=0, ttl=64, protocol=6, check=56748), TCPHeader(src_port=46986, dst_port=443, seq_num=3635193239, ack_num=0, data_off=10, reserved=0, flags=<Flags.SYN: 2>, window=32120, check=5903, urg_ptr=0, options=[(<Kind.MSS: 2>, b'\x05\xb4'), (<Kind.SACK_PERMIT: 4>,), (<Kind.TS: 8>, b'r2\t\xf2\x00\x00\x00\x00'), (<Kind.NOP: 1>,), (<Kind.WIN_SCALE: 3>, 0)])])
DEBUG:__main__:packet data : 45 00 00 3c 00 00 40 00 40 06 dd ac c0 a8 00 68 b2 f8 e9 06 b7 8a 01 bb d8 ac a5 97 00 00 00 00 a0 02 7d 78 17 0f 00 00 02 04 05 b4 04 02 08 0a 72 32 09 f2 00 00 00 00 01 03 03 00
DEBUG:__main__:packet size : 60
DEBUG:__main__:bytes sent: 60
Вроде пакет правильно собирает. Но куда ответ приходит? Я пробовал без TCP опций отправлять, пробовал Ethernet заголовки добавлять (ну чтобы как в WireShark). У меня идея по SYN-ASC спалить открытый порт, но у меня получился только SYN-флуд… Я упустил какой-то момент. Кто может подсказать какой? ю