Как подделать TCP-рукопожатие в scapy?

1

Недавно я пытался написать скрипт Scapy, который выполняет полное рукопожатие TCP. Идея заключалась в том, что я подключаю две виртуальные -net socket Qemu с использованием пользовательского интерфейса -net socket (который, похоже, обрабатывает raw IP/ethernet fine) и инструктирует машину B блокировать все входные данные от A (чтобы предотвратить его отправку RST). Затем я использовал telnet для connect() от машины A к B и выполнил следующий сценарий на машине B:

#!/usr/bin/python

import scapy.all as scapy

filter = "port 31337"
iface = "eth0"

def prepare_response(t):
    print("Received: %s" % repr(t))
    t.src, t.dst = t.dst, t.src  # swap ethernet addresses
    ip = t.getlayer("IP")
    ip.src, ip.dst = ip.dst, ip.src
    t.dport, t.sport = t.sport, t.dport
    t.ack = t.seq
    t.ack += 1

syn = scapy.sniff(filter=filter, count=1, iface=iface)[0]
print(syn.sprintf('%TCP.flags%'))

syn_ack = syn
prepare_response(syn_ack)
syn_ack.getlayer("TCP").flags |= 0x10  # set the ACK flag
print(syn_ack.sprintf('%TCP.flags%'))

print("Sending: %s" % repr(syn_ack))
scapy.sendp(syn_ack, iface=iface, verbose=False)

ack = scapy.sniff(filter=filter, count=1, iface=iface)[0]
assert(ack.flags & 0x10)

Проблема в том, что вместо получения ACK от A до B я, похоже, получаю повторную передачу SYN, как если бы SYN + ACK не был правильно интерпретирован:

Изображение 174551

tcp на машине A подтверждает, что SYN + ACK достиг машины:

05:47:03.925100 IP 10.0.0.1.39634 > debian.31337: Flags [S], seq 2426802888, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 4], length 0
05:47:03.927515 IP debian.31337 > 10.0.0.1.39634: Flags [S.], seq 2426802888, ack 2426802889, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 4], length 0

Здесь файл PCAP с точки зрения машины B в Base64:

1MOyoQIABAAAAAAAAAAAAP//AAABAAAAYlilUwieDgARAQAAEQEAAAEAXgAA + 1JUABI0VggARQABA2UUQAD/ESrYCgAAAuAAAPsU6RTpAO/г /QAAAAAAAwAAAAUAAAE2ATUBNAEzATIBMQFlAWYBZgFmATABMAE0ATUBMAE1ATABMAEwATABMAEwATABMAEwATABMAEwATABOAFlAWYDaXA2BGFycGEAAP8AAQtkZWJpYW4tMTA5MwVsb2NhbAAA/wABATIBMAEwAjEwB2luLWFkZHLAUAD/AAHAWgANAAEAAAB4AAsESTY4NgVMSU5VWMBaAAEAAQAAAHgABAoAAALAcQAMAAEAAAB4AALAWsBaABwAAQAAAHgAEP6AAAAAAAAAUFQA//4SNFbADAAMAAEAAAB4AALAWmJYpVMJoA4AnAAAAJwAAAABAF4AAPtSVAASNFYIAEUAAI4GlEAA/xGJzgoAAAHgAAD7FOkU6QB6hFgAAIQAAAAAAQAAAAABNgE1ATQBMwEyATEBZQFmAWYBZgEwATABNAE1ATABNQEwATABMAEwATABMAEwATABMAEwATABMAEwATgBZQFmA2lwNgRhcnBhAAAMgAEAAAB4ABIKZGViaWFuLTQwNwVsb2NhbABnWKVTvIYIAEIAAABCAAAAUlQAEjRWUlQAEjRWCABFAAA0HdtAAEAGCOcKAAABCgAAAprbemmul/p8AAAAAIACOQhjsAAAAgQFtAEBBAIBAwMEZ1ilU5COCABCAAAAQgAAAFJUABI0VlJUABI0VggARQAANB3bQABABgjnCgAAAgoAAAF6aZrbrpf6fK6X + n2AEjkIY7AAAAIEBbQBAQQCAQMDBGhYpVPTfggAQgAAAEIAAABSVAASNFZSVAASNFYIAEUAADQd3EAAQAYI5goAAAEKAAACmtt6aa6X + nwAAAAAgAI5CGOwAAACBAW0AQEEAgEDAwRqWKVTrI4IAEIAAABCAAAAUlQA EjRWUlQAEjRWCABFAAA0Hd1AAEAGCOUKAAABCgAAAprbemmul/p8AAAAAIACOQhjsAAAAgQFtAEBBAIBAwME

И один из аспектов A-B:

1MOyoQIABAAAAAAAAAAAAP//AAABAAAAVVilU9NXCABCAAAAQgAAAFJUABI0VlJUABI0VggARQAANB3bQABABgjnCgAAAQoAAAKa23pprpf6fAAAAACAAjkIFCkAAAIEBbQBAQQCAQMDBFVYpVPIYAgAQgAAAEIAAABSVAASNFZSVAASNFYIAEUAADQd20AAQAYI5woAAAIKAAABemma266X + Nyul/p9gBI5CGOwAAACBAW0AQEEAgEDAwRWWKVT008IAEIAAABCAAAAUlQAEjRWUlQAEjRWCABFAAA0HdxAAEAGCOYKAAABCgAAAprbemmul/p8AAAAAIACOQgUKQAAAgQFtAEBBAIBAwMEWFilU4FfCABCAAAAQgAAAFJUABI0VlJUABI0VggARQAANB3dQABABgjlCgAAAQoAAAKa23pprpf6fAAAAACAAjkIFCkAAAIEBbQBAQQCAQMDBA ==

Сначала я подумал, что это как-то связано с некоторой прихожей Linux TCP/IP, поэтому я экспериментировал с отключением временных меток TCP и файлов SYN. Я также пытался увеличить IP-идентификатор, что тоже не помогло. Обе машины работают под управлением Debian 7.5 с linux-image-3.2.0-4-686-pae под qemu 1.6.2. Что мне не хватает?

Теги:
scapy
tcp

1 ответ

2
Лучший ответ

Это проблема контрольной суммы.

В IP-слоте это происходит, потому что вы просто меняете исходный и целевой адреса, но на уровне TCP исходная контрольная сумма становится неправильной, когда вы меняете значение флагов.

Лучший вариант - позволить Scapy вычислить правильное значение контрольной суммы для вас, добавив del(t[TCP].chksum) в prepare_response().

  • 0
    Ничего себе, Wireshark не проверил контрольные суммы TCP для меня! Теперь это работает как шарм.
  • 1
    Wireshark имеет возможность отключить проверку контрольной суммы, потому что многие стеки переносят вычисление контрольной суммы на оборудование. Вы должны иметь возможность включить их в настройках.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню