Fixed Dest Port for traceroute(8)

From: Crist J. Clark (cristjc_at_comcast.net)
Date: 09/23/05

  • Next message: Brian: "Software distribution."
    Date: Fri, 23 Sep 2005 10:51:25 -0700
    To: net@freebsd.org
    
    

    Gee. It would be nice if one could fix the outgoing port for
    UDP and TCP traceroutes. Sometimes firewalls, load balancers,
    and various other systems treat packets differently depending
    on the transport layer destination port. The current traceroute
    implementation allows one to specify a starting port, but
    increments the port with each packet sent out. It doesn't do
    this without reason. The value is essentially a sequence number
    that is used to identify out-of-order responses, but this
    screws up our ability to traceroute a specific port.

    Also, traceroute just needs more options. It's closing on
    ping(8).

    I have added a '-e' option. A firewall "evasion," fixed-port
    option. For TCP and UDP scans, the destination port is not
    changed. Doing this in TCP is pretty straightforward. The
    sequence number field was already being loaded with the
    source port (which in turn is the PID) and destination port.
    I stopped incrementing the destination port, but continiued
    to increment the dest port part of the sequence number. I
    added the sequence number to the out-of-order check.

    For UDP, that approach won't work. There isn't much space
    available in the header to store a counter, so I switched the
    conter to the source port rather than destination. I thought
    about abusing the UDP checksum. But that has the side effect
    that the destination will drop our last packet rather than
    return a port unreachable and has the potential to confuse
    NATing devices and other nastiness (although we somehow got
    away without TCP checksums at all for a long time). The counter
    is only switched when the fixed port option is given.

    Anyone mind if I see if my commit bit still works and merge
    this in?

    Index: traceroute.8
    ===================================================================
    RCS file: /ncvs/freebsd/src/contrib/traceroute/traceroute.8,v
    retrieving revision 1.11
    diff -u -r1.11 traceroute.8
    --- traceroute.8 12 Apr 2005 15:16:32 -0000 1.11
    +++ traceroute.8 23 Sep 2005 17:47:12 -0000
    @@ -24,7 +24,7 @@
     .na
     .B traceroute
     [
    -.B \-dFISdnrvx
    +.B \-deFISdnrvx
     ] [
     .B \-f
     .I first_ttl
    @@ -98,6 +98,11 @@
     .PP
     Other options are:
     .TP
    +.B \-e
    +Firewall evasion mode.
    +Use fixed destination ports for UDP and TCP probes.
    +The destination port does NOT increment with each packet sent.
    +.TP
     .B \-f
     Set the initial time-to-live used in the first outgoing probe packet.
     .TP
    Index: traceroute.c
    ===================================================================
    RCS file: /ncvs/freebsd/src/contrib/traceroute/traceroute.c,v
    retrieving revision 1.27
    diff -u -r1.27 traceroute.c
    --- traceroute.c 26 Aug 2005 18:08:24 -0000 1.27
    +++ traceroute.c 23 Sep 2005 17:47:45 -0000
    @@ -353,6 +353,7 @@
     int doipcksum = 1; /* calculate ip checksums by default */
     #endif
     int optlen; /* length of ip options */
    +int fixedPort = 0; /* Use fixed destination port for TCP and UDP */
     
     extern int optind;
     extern int opterr;
    @@ -521,13 +522,17 @@
                     prog = argv[0];
     
             opterr = 0;
    - while ((op = getopt(argc, argv, "dFInrSvxf:g:i:M:m:P:p:q:s:t:w:z:")) != EOF)
    + while ((op = getopt(argc, argv, "edFInrSvxf:g:i:M:m:P:p:q:s:t:w:z:")) != EOF)
                     switch (op) {
     
                     case 'd':
                             options |= SO_DEBUG;
                             break;
     
    + case 'e':
    + fixedPort = 1;
    + break;
    +
                     case 'f':
                     case 'M': /* FreeBSD compat. */
                             first_ttl = str2val(optarg, "first ttl", 1, 255);
    @@ -1289,8 +1294,8 @@
     {
             struct udphdr *const outudp = (struct udphdr *) outp;
     
    - outudp->uh_sport = htons(ident);
    - outudp->uh_dport = htons(port + outdata->seq);
    + outudp->uh_sport = htons(ident + (fixedPort ? outdata->seq : 0));
    + outudp->uh_dport = htons(port + (fixedPort ? 0 : outdata->seq));
             outudp->uh_ulen = htons((u_short)protlen);
             outudp->uh_sum = 0;
             if (doipcksum) {
    @@ -1306,8 +1311,8 @@
     {
             struct udphdr *const udp = (struct udphdr *) data;
     
    - return (ntohs(udp->uh_sport) == ident
    - && ntohs(udp->uh_dport) == port + seq);
    + return (ntohs(udp->uh_sport) == ident + (fixedPort ? seq : 0) &&
    + ntohs(udp->uh_dport) == port + (fixedPort ? 0 : seq));
     }
     
     void
    @@ -1316,8 +1321,9 @@
             struct tcphdr *const tcp = (struct tcphdr *) outp;
     
             tcp->th_sport = htons(ident);
    - tcp->th_dport = htons(port + outdata->seq);
    - tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
    + tcp->th_dport = htons(port + (fixedPort ? 0 : outdata->seq));
    + tcp->th_seq = (tcp->th_sport << 16) | (tcp->th_dport +
    + (fixedPort ? outdata->seq : 0));
             tcp->th_ack = 0;
             tcp->th_off = 5;
             tcp->th_flags = TH_SYN;
    @@ -1335,7 +1341,8 @@
             struct tcphdr *const tcp = (struct tcphdr *) data;
     
             return (ntohs(tcp->th_sport) == ident
    - && ntohs(tcp->th_dport) == port + seq);
    + && ntohs(tcp->th_dport) == port + (fixedPort ? 0 : seq))
    + && tcp->th_seq == (ident << 16) | (port + seq);
     }
     
     void

    -- 
    Crist J. Clark                     |     cjclark@alum.mit.edu
    _______________________________________________
    freebsd-net@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-net
    To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"
    

  • Next message: Brian: "Software distribution."

    Relevant Pages

    • Re: excessive TCP dulplicate acks revisted
      ... The tcp duplicate ACK attack is back. ... there was a thread on duplicate TCP acks in -CURRENT. ... TCP STREAM TEST from localhost port 0 AF_INET to greenhouse- george.18clay.com port 0 AF_INET ... Socket Socket Message Elapsed ...
      (freebsd-current)
    • excessive TCP dulplicate acks revisted
      ... The tcp duplicate ACK attack is back. ... there was a thread on duplicate TCP acks in -CURRENT. ... TCP STREAM TEST from localhost port 0 AF_INET to greenhouse- george.18clay.com port 0 AF_INET ... Socket Socket Message Elapsed ...
      (freebsd-current)
    • Re: Windows ControlAd experience this morning
      ... TCP non-syn/non-ack packet on invalid connection. ... TCP Destination Port: 3665. ... OrgTechName: Network Operations ...
      (alt.computer.security)
    • Re: UDP catchall
      ... This is a kind of port knocking. ... Thanks to TCP ... If an RST packet is generated in response to the first TCP SYN packet, ... there might be no retransmission as the sender would think the TCP ...
      (freebsd-net)
    • Re: Problem with Port forwarding, NATD and IPFW
      ... You need some more knowledge to understand how TCP works. ... sender, port of sender, receiver, port of receiver. ... So there will be never a packet matching to this rule. ... Back to your problem with natd. ...
      (comp.unix.bsd.freebsd.misc)