Nmap Development mailing list archives

Nmap/libnetutil: route tables rework


From: Djalal Harouni <tixxdz () opendz org>
Date: Tue, 26 Jun 2012 18:50:48 +0100

Hi nmap-dev, David,

This is a quick summary of the network routes bugs that were reported by
Nmap users on nmap-dev, and others that I've found my self. Some of them
are easy to fix, others are not. David I need your point on the provided
solution and what do you think of updating libdnet ?


Attached are two files: one with all git logs and the other one is a
simple 'git diff' output.

These patches are currently only for Linux, there is no support for other
systems. One of the Nmap developers should continue the work.



For the record:
"./nmap --iflist" output differs from nmap route selection and
"./nmap --route-dst" output since:

First one will just show results of netutil.cc:getsysroutes()
Second one which calls netutil.cc:route_dst() includes
netutil.cc:getsysroutes() results + logic to match and force interfaces
by name and network destination...

BTW the "./nmap --route-dst X" is very helpful :)


Bugs:
(1) Some route entries will be attached to the device that handles default
    route. This will be visible to the eye on boxes with a lot of network
    devices ...

    The same bug was also reported by Thomas in this thread [1].

    This is due to the logic of the second stage searching when we try to
    find remaining routes that don't have interfaces. This behaviour was
    added to support some special cases of PPP, or when the gateway goes
    through another route, etc.

Fix: check the device name and see if we are dealing with the same
     network interface.
     Please see:  [PATCH 11/16] in the long patch file.


(2) On a box without a default route, netutil.cc:getsysroutes() will just
    report 0 routes, and Nmap may fail.

    getsysroutes() =>
      getsysroutes_dnet() =>  (number of returned routes here will be zero).
        sysroutes_dnet_find_interfaces() =>
          ...
          1526       if (sockaddr_equal_netmask(&ifaces[j].addr,
                        &dcrn->routes[i].gw, ifaces[j].netmask_bits)) {
          1527           dcrn->routes[i].device = &ifaces[j];
          1528         break;
          1529       }

    Here we only use the gateway to match routes.

Fix: please see: [PATCH 13/16] in the long patch file.


(3) Some route entries will match an interface address which is on the
    wrong device.

    The best example is the IPv6 link local generated addresses which are
    assigned to every IPv6 network interface with the prefix fe80::/64.
    If we do not explicitly check the interface name, then the first
    returned interface with an IPv6 link local address will match all
    fe80::/64 routes.

    This will result on: all these routes will be attached to that first
    same interface.

Fix: please see: [PATCH 15/16] in the long patch file.


(4) Perhaps other PPP and unknown interface type bugs which we'll fix later.


Notes:
o I'm not speaking about the code path that uses rtnetlink Linux.

o Here I'm trying to fix netutil.cc:getsysroutes() logic first which is
  part of the "./nmap --iflist" output. If Nmap takes the --unprivileged
  code path, then some features should work normally, however we must fix
  netutil.cc:getsysroutes() due to the previous bugs.

o Some of these bugs were hidden on Linux due to the use of
  netutil.cc:getsysroutes_proc() function that was deprecated.
  netutil.cc:getsysroutes_proc() was used by netutil.cc:getsysroutes().

  Now we see them because we are using netutil.cc:getsysroutes_dnet()
  which I suspect was never correct, plus the netutil.cc:route_dst() which
  was also hidding these bugs %-) and fixing one bug just triggers the
  other one %-)
  
  netutil.cc:route_dst() makes Nmap just work ;)



Solution:
First from the previous bugs it's clear to me that we need the interfaces
name to match routes correctly, we can't predict all the configs that
are there.


o I've updated libdnet to report all interfaces name in the route entries.
  Seriously we need that info, perhaps there are other solutions, but why
  bother if this is what we need and the kernel provides it. However now
  we should also add support for other systems which currently I can't do.
  Only Linux is supported.

o I've updated libnetutil to take advantage of that info.


Patch summary:
o Patches from 01-07: update libdnet/libnetutil to return interfaces
                      name in routes.
o Patche 08: copy interface name into libnetutil route struct.
o Patches from 09-16: fix all the previous reported bugs. 


Now please read the nmap_routes_rework_long_logs.patch file, and report
any new introduced bug :D


[1] http://seclists.org/nmap-dev/2012/q2/884


Thanks.

-- 
tixxdz
http://opendz.org

Attachment: nmap_routes_rework.patch
Description:

Attachment: nmap_routes_rework_long_logs.patch
Description:

_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/

Current thread: