Nmap Development mailing list archives

Re: Scans failing on Win32 - failures differ depending on args len (maybe)


From: jah <jah () zadkiel plus com>
Date: Sat, 08 Oct 2011 19:38:22 +0100

Hello,

The failures I reported stem from the call to GetAdaptersAddresses
from _refresh_tables in libdnet-stripped/src/intf-win32.c

With the args: -F -v -d -n 195.166.128.231, GetAdaptersAddresses
returns ERROR_INVALID_PARAMETER the very first time _refresh_tables
is called:

nmap.exe!_refresh_tables(intf_handle * intf)  Line 216    C
nmap.exe!intf_loop(intf_handle * intf, int (const intf_entry *, void *)* callback, void * arg)  Line 373 + 0x9 bytes    
C
nmap.exe!getinterfaces_dnet(int * howmany, char * errstr, unsigned int errstrlen)  Line 1312 + 0x12 bytes    C++
nmap.exe!getinterfaces(int * howmany, char * errstr, unsigned int errstrlen)  Line 1335 + 0x12 bytes    C++
nmap.exe!sysroutes_dnet_find_interfaces(dnet_collector_route_nfo * dcrn)  Line 1490 + 0xd bytes    C++
nmap.exe!getsysroutes_dnet(int * howmany, char * errstr, unsigned int errstrlen)  Line 1596 + 0x9 bytes    C++
nmap.exe!getsysroutes(int * howmany, char * errstr, unsigned int errstrlen)  Line 1625 + 0x11 bytes    C++
nmap.exe!route_dst_generic(const sockaddr_storage * dst, route_nfo * rnfo, const char * device, const sockaddr_storage 
* spoofss)  Line 3233 + 0x15 bytes    C++
nmap.exe!route_dst(const sockaddr_storage * dst, route_nfo * rnfo, const char * device, const sockaddr_storage * 
spoofss)  Line 3329 + 0x15 bytes    C++
nmap.exe!nmap_route_dst(const sockaddr_storage * dst, route_nfo * rnfo)  Line 2031 + 0x17 bytes    C++
nmap.exe!nexthost(HostGroupState * hs, const addrset * exclude_group, scan_lists * ports, int pingtype)  Line 359 + 
0x13 bytes    C++
nmap.exe!nmap_main(int argc, char * * argv)  Line 1778 + 0x1e bytes    C++
nmap.exe!main(int argc, char * * argv)  Line 195 + 0xd bytes    C++
nmap.exe!__tmainCRTStartup()  Line 278 + 0x19 bytes    C
nmap.exe!mainCRTStartup()  Line 189    C
kernel32.dll!_BaseProcessStart@4()  + 0x23 bytes   

With the args -F -v -v -d -n 195.166.128.231, GetAdaptersAddresses
returns NO_ERROR the first time _refresh_tables is called and
ERROR_INVALID_PARAMETER the second time _refresh_tables is called:

nmap.exe!_refresh_tables(intf_handle * intf)  Line 216    C
nmap.exe!intf_get_pcap_devname(const char * intf_name, char * pcapdev, int pcapdevlen)  Line 417 + 0x9 bytes    C
nmap.exe!eth_get_pcap_devname(const char * intf_name, char * pcapdev, int pcapdevlen)  Line 117 + 0x11 bytes    C
nmap.exe!eth_open(const char * device)  Line 39 + 0x15 bytes    C
nmap.exe!eth_open_cached(const char * device)  Line 942 + 0x9 bytes    C++
nmap.exe!UltraScanInfo::Init(std::vector<Target *,std::allocator<Target *> > & Targets, scan_lists * pts, stype scantp) 
 Line 1653 + 0x17 bytes    C++
nmap.exe!UltraScanInfo::UltraScanInfo(std::vector<Target *,std::allocator<Target *> > & Targets, scan_lists * pts, 
stype scantype)  Line 607 + 0xa3 bytes    C++
nmap.exe!ultra_scan(std::vector<Target *,std::allocator<Target *> > & Targets, scan_lists * ports, stype scantype, 
timeout_info * to)  Line 5718 + 0x3a bytes    C++
nmap.exe!massping(Target * * hostbatch, int num_hosts, scan_lists * ports)  Line 257 + 0x14 bytes    C++
nmap.exe!nexthost(HostGroupState * hs, const addrset * exclude_group, scan_lists * ports, int pingtype)  Line 465 + 
0x16 bytes    C++
nmap.exe!nmap_main(int argc, char * * argv)  Line 1778 + 0x1e bytes    C++
nmap.exe!main(int argc, char * * argv)  Line 195 + 0xd bytes    C++
nmap.exe!__tmainCRTStartup()  Line 278 + 0x19 bytes    C
nmap.exe!mainCRTStartup()  Line 189    C
kernel32.dll!_BaseProcessStart@4()  + 0x23 bytes

GetAdaptersAddresses is called in a loop, first with a 2 byte buffer
allocation for the adapter addresses and then again, if it returned
ERROR_BUFFER_OVERFLOW, with a larger allocation having the length as
updated by GetAdaptersAddresses.

In each of the two aforementioned cases GetAdaptersAddresses returns
ERROR_INVALID_PARAMETER during the first go round the loop.  In the
latter of the cases, during the first call to _refresh_tables, it
takes two loops to allocate the (assumed) correct buffer size - I've
observed that 2940 bytes is allocated.

According to the msdn docs for GetAdaptersAddresses [1], this method
of determining the buffer size is "Strongly discouraged" (it doesn't
say exactly why, but it does say that the function "requires a
significant amount of network resources and time to complete since all
of the low-level network interface tables must be traversed"). Instead
the docs suggest pre-allocating a 15KB buffer which, "on typical
computers", "dramatically reduces the chances that the
GetAdaptersAddresses function returns ERROR_BUFFER_OVERFLOW, which
would require calling GetAdaptersAddresses function multiple times".

The msdn docs say this about the reasons why ERROR_INVALID_PARAMETER
is returned: "One of the parameters is invalid. This error is returned
for any of the following conditions: the SizePointer parameter is
NULL, the Address parameter is not AF_INET, AF_INET6, or AF_UNSPEC, or
the address information for the parameters requested is greater than
ULONG_MAX".
For sure, neither of the first two reasons apply and ULONG_MAX,
defined in limits.h (included from Visual Studio includes), is
0xffffffff so I don't think that can be it either.  I can't find any
other clue as to why this might happen.

The attached patch implements the suggested method for allocating the
adapter addresses buffer and all of the scans which had previously
failed on XP SP3 complete successfully with the change.  I wasn't able
to reproduce the failures on Windows 7 and the patched binary made no
difference to the scan results on that OS.

I haven't yet discovered why one -v makes such a difference to the
code path taken when failure occurs.

jah

[1] - GetAdaptersAddresses
http://msdn.microsoft.com/en-us/library/aa365915%28VS.85%29.aspx#Remarks

Attachment: libdnet-stripped_intf-win32.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: