Search code examples
socketstcpscapyicmpnetwork-security

How to build forged ICMP "Destination Unreachable" Type 3 Code 4 packet


I have created forged destination unreachable ICMP with type 3 and code 4 (fragmentation needed and DF bit is set). My setup has Server, Client, and a switch between them. Ideally this ICMP gets generated by router/gateway but I'm generating this at client. I'm creating this ICMP using Scapy tool. Here is how I'm creating:

ip = IP()
icmp = ICMP()
# IP Packet sent to client
ip.dst = ip_server
ip.src = ip_client
ip.protocol = 1 #shows that ip header contains icmp as data 
# icmp type 3 + code 4 
icmp.type = 3
icmp.code = 4
mtu =1300
icmp.unused = mtu
#
# build original packet for ICMP ping request
#
ip_orig = IP()
ip_orig.src = ip_server
ip_orig.dst = ip_client
icmp_orig = TCP()
tcp_orig.sport = 50000 
tcp_orig.dport = 50000
tcp_orig.seq= original sequence number
#
# send the packet
#
send (ip/icmp/ip_orig/tcp_orig)

Steps I'm following to demonstrate the effect of this ICMP: 1> Server and client are talking to each other using sockets 2> As soon as server accepts the connection, I'm giving a 60 seconds pause in the machine during which I disable all the TCP ACKs going out of client machine (because if server receives ACKs for the message it sent then it wouldn't respond to ICMP). 3> Server sends it first message to client but won't receive any ACKs and server keeps re-transmitting the message, meanwhile I inject an ICMP message as mentioned in the above scapy code: send (ip/icmp/ip_orig/tcp/orig). I'm reporting MTU 1300 in the icmp i'm sending. 4> Ideally Server should reduce it's MTU and sends message back to client with MTU size of 1300.

But Server keeps re-transmitting the message with MTU size 1500. Kindly help me with this. Why is server not reducing its MTU? Am I doing something wrong in my demonstration? Any help would be greatly appreciated.


Solution

  • There are a few pointers I outlined in this answer and in its comments:

    1. The specification requires that the original IP header that is encapsulated in the ICMP error message (i.e. ip_orig) is exactly identical to the one received. Therefore, setting just its source IP address and destination IP addresses (i.e. ip_orig.src and ip_orig.dst, respectively) is probably not enough.
    2. The sequence number of the original TCP header that is encapsulated in the ICMP error message (i.e. tcp_orig.seq) should be set as well, since the specification requires that at least 8 bytes of the problematic packet's IP layer payload are included in the ICMP error message.
    3. Verify that path MTU discovery is enabled and that the DF bit is set. You can enable path MTU discovery with sysctl -w net.ipv4.ip_no_pmtu_disc=0.
    4. Verify that there isn't any firewall and/or iptables rule that blocks ICMP messages.