1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-11 10:19:03 +00:00

Better CNAME handling in mass_rdns.

If mass_rdns gets a CNAME and PTR for that name in one answer, parse
both. This means that the majority of CNAME answers can now be handled
without falling back to system resolver. A test of 40K random IPs
produced 21 CNAME answers, 18 of which had an associated PTR that was
correctly parsed in this way.
This commit is contained in:
dmiller
2016-07-23 00:22:54 +00:00
parent 28ff5841bc
commit 274027bf61

View File

@@ -757,6 +757,10 @@ static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) {
bool processing_successful = false; bool processing_successful = false;
sockaddr_storage ip;
ip.ss_family = AF_UNSPEC;
std::string alias;
for(std::list<DNS::Answer>::const_iterator it = p.answers.begin(); for(std::list<DNS::Answer>::const_iterator it = p.answers.begin();
it != p.answers.end() && !processing_successful; ++it ) it != p.answers.end() && !processing_successful; ++it )
{ {
@@ -769,8 +773,11 @@ static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) {
{ {
DNS::PTR_Record * ptr = static_cast<DNS::PTR_Record *>(a.record); DNS::PTR_Record * ptr = static_cast<DNS::PTR_Record *>(a.record);
sockaddr_storage ip; if(
if(DNS::Factory::ptrToIp(a.name, ip)) // If CNAME answer filled in ip with a matching alias
(ip.ss_family != AF_UNSPEC && a.name == alias )
// Or if we can get an IP from reversing the .arpa PTR address
|| DNS::Factory::ptrToIp(a.name, ip))
{ {
if ((processing_successful = process_result(ip, ptr->value, ACTION_FINISHED, p.id))) if ((processing_successful = process_result(ip, ptr->value, ACTION_FINISHED, p.id)))
{ {
@@ -790,16 +797,16 @@ static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) {
} }
case DNS::CNAME: case DNS::CNAME:
{ {
sockaddr_storage ip;
if(DNS::Factory::ptrToIp(a.name, ip)) if(DNS::Factory::ptrToIp(a.name, ip))
{ {
DNS::CNAME_Record * cname = static_cast<DNS::CNAME_Record *>(a.record);
alias = cname->value;
if (o.debugging >= TRACE_DEBUG_LEVEL) if (o.debugging >= TRACE_DEBUG_LEVEL)
{ {
char ipstr[INET6_ADDRSTRLEN]; char ipstr[INET6_ADDRSTRLEN];
sockaddr_storage_iptop(&ip, ipstr); sockaddr_storage_iptop(&ip, ipstr);
log_write(LOG_STDOUT, "mass_rdns: CNAME found for <%s>\n", ipstr); log_write(LOG_STDOUT, "mass_rdns: CNAME found for <%s> to <%s>\n", ipstr, alias.c_str());
} }
processing_successful = process_result(ip, "", ACTION_SYSTEM_RESOLVE, p.id);
} }
break; break;
} }
@@ -811,8 +818,20 @@ static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) {
if (!processing_successful) { if (!processing_successful) {
if (DNS_HAS_FLAG(f, DNS::TRUNCATED)) { if (DNS_HAS_FLAG(f, DNS::TRUNCATED)) {
sockaddr_storage discard; // TODO: TCP fallback, or only use system resolver if user didn't specify --dns-servers
process_result(discard, "", ACTION_SYSTEM_RESOLVE, p.id); process_result(ip, "", ACTION_SYSTEM_RESOLVE, p.id);
}
else if (!alias.empty()) {
if (o.debugging >= TRACE_DEBUG_LEVEL)
{
char ipstr[INET6_ADDRSTRLEN];
sockaddr_storage_iptop(&ip, ipstr);
log_write(LOG_STDOUT, "mass_rdns: CNAME for <%s> not processed.\n", ipstr);
}
// TODO: Send a PTR request for alias instead. Meanwhile, we'll just fall
// back to using system resolver. Alternative: report the canonical name
// (alias), but that's not very useful.
process_result(ip, "", ACTION_SYSTEM_RESOLVE, p.id);
} }
else { else {
if (o.debugging >= TRACE_DEBUG_LEVEL) { if (o.debugging >= TRACE_DEBUG_LEVEL) {