The second argument to RTA_NEXT was missing a dereference, so it was
changing the pointer rather than the integer pointed to. I got this
assertion failure with an IPv6 link-local address:
nmap: netutil.cc:3048: void add_rtattr_addr(nlmsghdr*, rtattr**, unsigned int*, unsigned char, const sockaddr_storage*): Assertion `((*len) >= (int)sizeof(struct rtattr) && (*rtattr)->rta_len >= sizeof(struct rtattr) && (*rtattr)->rta_len <= (*len))' failed.
As well as being shorter, this prevents connecting using a different
address family (e.g., IPv6 rather than IPv4) compared to doing this:
http.get(host.targetname, port.number)
Patch by John Bond.
http://seclists.org/nmap-dev/2012/q2/637
This is what setTargetNextHopMAC already did, but the code change was
not copied here. This provided a way for NSE scripts to cause an
assertion failure:
local math = require "math"
local packet = require "packet"
function portrule(host, port)
return port.protocol == "udp"
end
function action(host, port)
local ip_raw = bin.pack("H", "60000000000d11ff")
.. host.bin_ip_src .. host.bin_ip
.. bin.pack(">S", math.random(32768, 65535)) .. bin.pack(">S",
port.number)
.. bin.pack("H", "000d8082") .. "hello"
local p = packet.Packet:new(ip_raw, #ip_raw)
p:udp_count_checksum()
local s = nmap.new_dnet()
s:ip_open()
s:ip_send(p.buf)
end
This would fail with the message "doArp can only handle IPv4 addresses"
when ip_send called getNextHopMAC. (Only with --send-eth.)
ssl-enum-ciphers was producing output against non-ssl services, listing
"least strength: strong" when there was no cipher matched. Fixed to
return nil in this case, and to clearly indicate when a protocol is
supported but does not support any of our ciphers (a very unlikely
situation! Had to artificially reduce attempted ciphers to test.)
Was crashing on unparseable dates (example: "2147483647Z"). Now the
exact string is placed in structured output when it cannot be
normalized. Also, the structured-format timestamp is used for Normal
output for consistency; no timezone offset was previously displayed.
This value gets clobbered after the netlink recvmsg. It was giving me a
bogus address family (234), which caused the call to getInterfaceByName
to fail:
Could not find interface wlan0 which was specified by -e
This seems to have been exposed by r29754. Specifying a source address
that is not on any actual route seems to result in a netlink query
result with 0 entries, and the changed value of rtm_family. (The fact
that there are no routes returned is not a problem, because we bail out
early when -e is given, now that getInterfaceByName works again.)
--route-dst has been a useful debugging option, but it ran inline during
option processing and always used AF_UNSPEC to resolve names. Let it run
after options have been processed, so it can obey things like -6, -S,
and -e. Let it always resolve with o.af(), so you get different results:
nmap --route-dst scanme.nmap.org
nmap -6 --route-dst scanme.nmap.org
We previously restricted by destination address; do it for source
address as well. This can matter in some configurations.
http://seclists.org/nmap-dev/2012/q3/831
There still seems to be a problem with the wrong route being chosen with
--send-ip, but this patch is reported to work with --send-eth.
The script was checking the returned data, but not the status. When
status is false, data is actually an error message. So in case of a
timeout, the script was receiving nil, "TIMEOUT" and interpreting
"TIMEOUT" as a response from the server. It looked like this:
Discovered open port 1434/udp on 127.0.0.1
NSE: rpc-grind: RPC checking function response data is not RPC.
NSE: Target port 1434 is not a RPC port.
This was reported by Christopher Clements.
http://seclists.org/nmap-dev/2012/q3/685
On platforms supporting sa_len, NEXTIFR would skip over sa_len bytes
starting at the beginning of ifr_addr, and assume that was the end of
the struct. (The idea being that a large address such as a sockaddr_in6
could overflow the nominal struct boundary.) This logic was wrong when
there was something else in the union bigger than sa_len; we would
increment into somewhere in the middle of the same struct.
This exhibited itself on NetBSD, where struct ifreq has a
sockaddr_storage member in its internal union:
struct ifreq {
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr_storage ifru_space;
No, we skip over sa_len bytes, or to the nominal end of the struct,
whichever is larger.
Unix Network Programming gets this wrong too; in figure 17.8 they do
ptr += sizeof(ifr->ifr_name) + max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);