Home page logo

nmap-dev logo Nmap Development mailing list archives

Re: nmap -sT localhost showing ephemeral ports?
From: Jacek Wielemborek <d33tah () gmail com>
Date: Fri, 06 Jun 2014 16:26:08 +0200

15/02/2014 07:15:43 Daniel Miller <bonsaiviking () gmail com>:
On Fri, Feb 14, 2014 at 12:14 PM, Daniel Miller
<bonsaiviking () gmail com> wrote:
On 02/14/2014 11:21 AM, Daniel Miller wrote:
I think the attached patch detects and fixes this. It seems
to work on my Linux system, and I think I haven't used any
non-portable calls. I'd appreciate testing.

I realized I left a debug statement without a check for
o.debugging and with an extra format argument. Corrected
patch attached.



When checking to see how far back my patch would cleanly apply,
I found the interesting case of r30583:

--------- r30583 | david | 2013-02-05 04:55:29 +0000 (Tue, 05
Feb 2013) | 9 lines

Remove some old Linux compatibility code from connect scan.

This code was quite old (dating from r854 in 2000) and may not
serve a purpose anymore. Let's try removing it.

Apart from being obsolete, the code had a race condition where
the connection could be closed with a RST before getpeername
was called, leading to a fatal error message.

The code in question did something similar to what I've done in
this patch:
  if (getsockname(sd, (struct sockaddr *) &sout, &soutlen) <
  0) {>
    pfatal("error in getsockname for port %hu", (u16) pport);

  s_in = (struct sockaddr_in *) &sout;
  s_in6 = (struct sockaddr_in6 *) &sout;
  if ((o.af() == AF_INET && htons(s_in->sin_port) == pport)

#ifdef HAVE_IPV6

        || (o.af() == AF_INET6 && htons(s_in6->sin6_port) => >         || pport)


     ) {

    /* Linux 2.2 bug can lead to bogus successful

       in this case -- we treat the port as bogus even though
       is POSSIBLE that this is a real connection */

    newportstate = PORT_CLOSED;

  } else {

    newhoststate = HOST_UP;
    newportstate = PORT_OPEN;


This may explain why this report only came up recently, if
there was code to handle the case prior to February 2013. I
think my code is safer with respect to the race condition
because I simply mark the probe as timed-out and allow it to
be retried, counting on the low probability of re-triggering
the self-connection condition. Of course, I am not certain
that my implementation is entirely correct. It works for me so
far, but others more familiar with the API may discover that I
am introducing some other bug.


Nmap still finds ephemeral ports on with -sT on my box. Here's how
I tested that:

nmap --unprivileged localhost/8 -sT -v -p- -Pn -n  | \
    grep 'Discovered' | \
    fgrep -v -f <( \
      nmap localhost -sT -p- -n -Pn | \
      egrep '[0-9]+/tcp\s+open' | \
      cut -f1 -d ' ' | \
      sed 's/^/Discovered open port /g' )

This command scans all ports on all 127.x.x.x IPs, which on my
system is mapped to the loopback device. Then, since Nmap was
launched in verbose mode, it looks for lines starting with
"Discovered" and filters out the ones we found in the second scan,
which should make Nmap only report ports that are either
ephemeral or opened after running the command.

I didn't check if Daniel's patch was applied and wrote my own to
fix the problem. I'm not sure if it's as good as Daniel's, but I
attach it anyway.

Attachment: nmap-fix-ephemeral-ports-detection-r32914.diff

Attachment: signature.asc
Description: This is a digitally signed message part.

Sent through the dev mailing list
Archived at http://seclists.org/nmap-dev/

  By Date           By Thread  

Current thread:
[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]