diff --git a/CHANGELOG b/CHANGELOG index adefbc2b6..8a90d37f7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -56,6 +56,11 @@ o Added IPv6 host support to the RPC scan. Attempting this before (via -sV) caused a segmentation fault. Thanks to Will Cladek for the report. [Kris] +o Reordered the UDP port selection for Traceroute: a closed port is + now chosen before an open one. This is because an open UDP port is + usually due to running version detection (-sV), so a Traceroute + probe wouldn't elicit a response. [Kris] + o We now escape newlines, carriage returns, and tabs (\n\r\t) in XML output. While those are allowed in XML attributes, they get normalized which can make formatting the output difficult for diff --git a/traceroute.cc b/traceroute.cc index 46b854d29..04340b564 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -325,8 +325,8 @@ Traceroute::getTracePort (u8 proto, Target * t) { u16 open_port = 1; u16 closed_port = 1; u16 filtered_port = 1; - u16 state = 0; u16 port = 0; + int state = -1; struct Port *np; /* Use the first specified port for ping traceroutes */ @@ -347,21 +347,31 @@ Traceroute::getTracePort (u8 proto, Target * t) { open_port = (!scaninfo.open_response) ? 0 : 1; } - /* First we try to find an open port, if not we try to find a closed - * port and lastly we try to find a filtered port */ - if (open_port && t->ports.getStateCounts (proto, scaninfo.open_state)) - state = scaninfo.open_state; - else if (closed_port && t->ports.getStateCounts (proto, scaninfo.closed_state)) - state = scaninfo.closed_state; - else if (filtered_port && t->ports.getStateCounts (proto, PORT_FILTERED)) { + /* For UDP we try for a closed port, then an open one. For everything else + * we try the opposite. When all else fails, we try for filtered */ + if (proto == IPPROTO_UDP) { + if (closed_port && t->ports.getStateCounts (proto, scaninfo.closed_state)) + state = scaninfo.closed_state; + else if (open_port && t->ports.getStateCounts (proto, scaninfo.open_state)) + state = scaninfo.open_state; + } else { + if (open_port && t->ports.getStateCounts (proto, scaninfo.open_state)) + state = scaninfo.open_state; + else if (closed_port && t->ports.getStateCounts (proto, scaninfo.closed_state)) + state = scaninfo.closed_state; + } + + if (state == -1 && filtered_port && + t->ports.getStateCounts (proto, PORT_FILTERED)) { state = PORT_FILTERED; if (o.verbose) log_write (LOG_PLAIN, "%s: only filtered %s available, results may be incorrect\n", t->targetipstr (), o.ipprotscan ? "protocols" : "ports"); - } else { - return -1; } + if (state == -1) + return -1; + np = t->ports.nextPort (NULL, proto, state); if (!np) return -1;