1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 12:41:29 +00:00

Getting very darn close to Nmap 3.97Shmoo

This commit is contained in:
fyodor
2006-01-12 04:47:03 +00:00
parent f4df290c14
commit 0f9cd6f73d
5 changed files with 75 additions and 61 deletions

View File

@@ -1,18 +1,6 @@
# Nmap Changelog ($Id$); -*-text-*- # Nmap Changelog ($Id$); -*-text-*-
3.97Shmoo 3.97Shmoo
o Reverse DNS resolution is now done in parallel rather than one at a
time. All scans of large networks (particularly list, ping and
just-a-few-ports scans) should benefit substantially from this
change. If you encounter any problems, please let us know. The new
--system_dns option was added so you can use the (slow) system
resolver if you prefer that for some reason. You can specify a
comma separated list of DNS server IP addresses for Nmap to use with
the new --dns_servers option. Otherwise, Nmap looks in
/etc/resolve.conf (UNIX) or the system registry (Windows) to obtain
the nameservers already configured for your system. This excellent
patch was written by Doug Hoyte (doug(a)hcsw.org).
o Added run time interaction as documented at o Added run time interaction as documented at
http://www.insecure.org/nmap/man/man-runtime-interaction.html . http://www.insecure.org/nmap/man/man-runtime-interaction.html .
While Nmap is running, you can now press 'v' to increase verbosity, While Nmap is running, you can now press 'v' to increase verbosity,
@@ -25,6 +13,18 @@ o Added run time interaction as documented at
equivalents. This feature was created by Paul Tarjan equivalents. This feature was created by Paul Tarjan
(ptarjan(a)stanford.edu) as part of the Google Summer of Code. (ptarjan(a)stanford.edu) as part of the Google Summer of Code.
o Reverse DNS resolution is now done in parallel rather than one at a
time. All scans of large networks (particularly list, ping and
just-a-few-ports scans) should benefit substantially from this
change. If you encounter any problems, please let us know. The new
--system_dns option was added so you can use the (slow) system
resolver if you prefer that for some reason. You can specify a
comma separated list of DNS server IP addresses for Nmap to use with
the new --dns_servers option. Otherwise, Nmap looks in
/etc/resolve.conf (UNIX) or the system registry (Windows) to obtain
the nameservers already configured for your system. This excellent
patch was written by Doug Hoyte (doug(a)hcsw.org).
o Added the --badsum option, which causes Nmap to use invalid TCP or o Added the --badsum option, which causes Nmap to use invalid TCP or
UDP checksums for packets sent to target hosts. Since UDP checksums for packets sent to target hosts. Since
virtually all host IP stacks properly drop these packets, any virtually all host IP stacks properly drop these packets, any

View File

@@ -1620,8 +1620,9 @@ printf("%s %s ( %s )\n"
" -r: Scan ports consecutively - don't randomize\n" " -r: Scan ports consecutively - don't randomize\n"
"SERVICE/VERSION DETECTION:\n" "SERVICE/VERSION DETECTION:\n"
" -sV: Probe open ports to determine service/version info\n" " -sV: Probe open ports to determine service/version info\n"
" --version_light: Limit to most likely probes for faster identification\n" " --version_intensity <level>: Set from 0 (light) to 9 (try all probes)\n"
" --version_all: Try every single probe for version detection\n" " --version_light: Limit to most likely probes (intensity 2)\n"
" --version_all: Try every single probe (intensity 9)\n"
" --version_trace: Show detailed version scan activity (for debugging)\n" " --version_trace: Show detailed version scan activity (for debugging)\n"
"OS DETECTION:\n" "OS DETECTION:\n"
" -O: Enable OS detection\n" " -O: Enable OS detection\n"

View File

@@ -286,28 +286,32 @@ static u16 id_counter;
static ScanProgressMeter *SPM; static ScanProgressMeter *SPM;
//------------------- Prototypes --------------------- //------------------- Prototypes and macros ---------------------
void close_dns_servers(); void close_dns_servers();
void write_evt_handler(nsock_pool nsp, nsock_event evt, void *req_v); void write_evt_handler(nsock_pool nsp, nsock_event evt, void *req_v);
void do_possible_writes(); void do_possible_writes();
int deal_with_timedout_reads();
#define ACTION_FINISHED 0
#define ACTION_CNAME_LIST 1
#define ACTION_TIMEOUT 2
//------------------- Misc code --------------------- //------------------- Misc code ---------------------
void output_summary() { void output_summary() {
int tp = stat_ok + stat_nx + stat_sf + stat_dropped; int tp = stat_ok + stat_nx + stat_dropped;
struct timeval now; struct timeval now;
memcpy(&now, nsock_gettimeofday(), sizeof(struct timeval)); memcpy(&now, nsock_gettimeofday(), sizeof(struct timeval));
if (o.debugging && (tp%SUMMARY_DELAY == 0)) if (o.debugging && (tp%SUMMARY_DELAY == 0))
log_write(LOG_STDOUT, "mass_rdns: %.2fs %d/%d [#: %lu, OK: %d, NX: %d, SF: %d, DR: %d, TR: %d]\n", log_write(LOG_STDOUT, "mass_rdns: %.2fs %d/%d [#: %lu, OK: %d, NX: %d, DR: %d, SF: %d, TR: %d]\n",
TIMEVAL_MSEC_SUBTRACT(now, starttv) / 1000.0, TIMEVAL_MSEC_SUBTRACT(now, starttv) / 1000.0,
tp, stat_actual, tp, stat_actual,
servs.size(), stat_ok, stat_nx, stat_sf, stat_dropped, stat_trans); servs.size(), stat_ok, stat_nx, stat_dropped, stat_sf, stat_trans);
} }
@@ -326,7 +330,7 @@ void check_capacities(dns_server *tpserv) {
// After processing a DNS response, we search through the IPs we're // After processing a DNS response, we search through the IPs we're
// looking for and update their results as necessary. // looking for and update their results as necessary.
// Returns non-zero if this matches a query we're looking for // Returns non-zero if this matches a query we're looking for
int process_result(u32 ia, char *result, int needs_system_dns) { int process_result(u32 ia, char *result, int action, u16 id) {
std::list<dns_server *>::iterator servI; std::list<dns_server *>::iterator servI;
std::list<request *>::iterator reqI; std::list<request *>::iterator reqI;
dns_server *tpserv; dns_server *tpserv;
@@ -338,19 +342,26 @@ int process_result(u32 ia, char *result, int needs_system_dns) {
for(reqI = tpserv->in_process.begin(); reqI != tpserv->in_process.end(); reqI++) { for(reqI = tpserv->in_process.begin(); reqI != tpserv->in_process.end(); reqI++) {
tpreq = *reqI; tpreq = *reqI;
if ((u32) (tpreq->targ->v4host().s_addr) == ia) { if (id == tpreq->id) {
if (ia != 0 && (u32) (tpreq->targ->v4host().s_addr) != ia) continue;
if (action == ACTION_CNAME_LIST || action == ACTION_FINISHED) {
tpserv->capacity += CAPACITY_UP_STEP; tpserv->capacity += CAPACITY_UP_STEP;
check_capacities(tpserv); check_capacities(tpserv);
if (result) tpreq->targ->setHostName(result); if (result) tpreq->targ->setHostName(result);
tpserv->in_process.remove(tpreq); tpserv->in_process.remove(tpreq);
tpserv->reqs_on_wire--; tpserv->reqs_on_wire--;
total_reqs--; total_reqs--;
if (needs_system_dns) if (action == ACTION_CNAME_LIST) cname_reqs.push_back(tpreq);
cname_reqs.push_back(tpreq); if (action == ACTION_FINISHED) delete tpreq;
else } else {
delete tpreq; memcpy(&tpreq->timeout, nsock_gettimeofday(), sizeof(struct timeval));
deal_with_timedout_reads();
}
do_possible_writes(); do_possible_writes();
@@ -457,6 +468,7 @@ void read_evt_handler(nsock_pool nsp, nsock_event evt, void *nothing) {
int i, nameloc, rdlen, atype, aclass; int i, nameloc, rdlen, atype, aclass;
int errcode=0; int errcode=0;
int queries, answers; int queries, answers;
u16 packet_id;
if (total_reqs >= 1) if (total_reqs >= 1)
nsock_read(nsp, nse_iod(evt), read_evt_handler, -1, NULL); nsock_read(nsp, nse_iod(evt), read_evt_handler, -1, NULL);
@@ -474,6 +486,8 @@ void read_evt_handler(nsock_pool nsp, nsock_event evt, void *nothing) {
// Size of header is 12, and we must have additional data as well // Size of header is 12, and we must have additional data as well
if (buflen <= 12) return; if (buflen <= 12) return;
packet_id = (buf[1] & 0xFF) + ((buf[0] & 0xFF) << 8);
// Check that this is a response, standard query, and that no truncation was performed // Check that this is a response, standard query, and that no truncation was performed
// 0xFA == 11111010 (we're not concerned with AA or RD bits) // 0xFA == 11111010 (we're not concerned with AA or RD bits)
if ((buf[2] & 0xFA) != 0x80) return; if ((buf[2] & 0xFA) != 0x80) return;
@@ -493,11 +507,26 @@ void read_evt_handler(nsock_pool nsp, nsock_event evt, void *nothing) {
// If the domain doesn't resolve (NXDOMAIN or SERVFAIL) we should have // If the domain doesn't resolve (NXDOMAIN or SERVFAIL) we should have
// 1+ queries and 0 answers: // 1+ queries and 0 answers:
if (errcode) { if (errcode) {
if (queries <= 0 || answers > 0) return; int found;
} else {
if (queries <= 0 || answers <= 0) return; // NXDomain means we're finished (doesn't exist for sure)
// but SERVFAIL might just mean a server timeout
found = process_result(0, NULL, errcode == 3 ? ACTION_FINISHED : ACTION_TIMEOUT, packet_id);
if (errcode == 2 && found) {
if (o.debugging >= TRACE_DEBUG_LEVEL) log_write(LOG_STDOUT, "mass_rdns: SERVFAIL <id = %d>\n", packet_id);
stat_sf++;
} else if (errcode == 3 && found) {
if (o.debugging >= TRACE_DEBUG_LEVEL) log_write(LOG_STDOUT, "mass_rdns: NXDOMAIN <id = %d>\n", packet_id);
output_summary();
stat_nx++;
} }
return;
}
if (queries <= 0 || answers <= 0) return;
curbuf = 12; curbuf = 12;
// Need to safely skip past QUERY section // Need to safely skip past QUERY section
@@ -509,30 +538,7 @@ void read_evt_handler(nsock_pool nsp, nsock_event evt, void *nothing) {
// Make sure we have the QTYPE and QCLASS fields // Make sure we have the QTYPE and QCLASS fields
if (curbuf + 4 >= buflen) return; if (curbuf + 4 >= buflen) return;
curbuf += 4; curbuf += 4;
if (errcode) {
struct in_addr ia;
int found;
ia.s_addr = parse_inaddr_arpa(buf+nameloc, buflen-nameloc);
if (ia.s_addr == 0) return;
found = process_result(ia.s_addr, NULL, 0);
if (errcode == 2 && found) {
if (o.debugging >= TRACE_DEBUG_LEVEL) log_write(LOG_STDOUT, "mass_rdns: SERVFAIL <%s>\n", inet_ntoa(ia));
output_summary();
stat_sf++;
} else if (errcode == 3 && found) {
if (o.debugging >= TRACE_DEBUG_LEVEL) log_write(LOG_STDOUT, "mass_rdns: NXDOMAIN <%s>\n", inet_ntoa(ia));
output_summary();
stat_nx++;
} }
}
}
// No answers if NXDOMAIN/SERVFAIL
if (errcode) return;
// We're now at the ANSWER section // We're now at the ANSWER section
@@ -562,7 +568,7 @@ void read_evt_handler(nsock_pool nsp, nsock_event evt, void *nothing) {
if (encoded_name_to_normal(buf+nameloc, outbuf, sizeof(outbuf)) == -1) return; if (encoded_name_to_normal(buf+nameloc, outbuf, sizeof(outbuf)) == -1) return;
if (process_result(ia.s_addr, outbuf, 0)) { if (process_result(ia.s_addr, outbuf, ACTION_FINISHED, packet_id)) {
if (o.debugging >= TRACE_DEBUG_LEVEL) log_write(LOG_STDOUT, "mass_rdns: OK MATCHED <%s> to <%s>\n", inet_ntoa(ia), outbuf); if (o.debugging >= TRACE_DEBUG_LEVEL) log_write(LOG_STDOUT, "mass_rdns: OK MATCHED <%s> to <%s>\n", inet_ntoa(ia), outbuf);
output_summary(); output_summary();
stat_ok++; stat_ok++;
@@ -575,7 +581,7 @@ void read_evt_handler(nsock_pool nsp, nsock_event evt, void *nothing) {
if (ia.s_addr == 0) return; if (ia.s_addr == 0) return;
if (o.debugging >= TRACE_DEBUG_LEVEL) log_write(LOG_STDOUT, "mass_rdns: CNAME found for <%s>\n", inet_ntoa(ia)); if (o.debugging >= TRACE_DEBUG_LEVEL) log_write(LOG_STDOUT, "mass_rdns: CNAME found for <%s>\n", inet_ntoa(ia));
process_result(ia.s_addr, NULL, 1); process_result(ia.s_addr, NULL, ACTION_CNAME_LIST, packet_id);
} else { } else {
if (rdlen < 0 || rdlen + curbuf >= buflen) return; if (rdlen < 0 || rdlen + curbuf >= buflen) return;
curbuf += rdlen; curbuf += rdlen;
@@ -662,7 +668,7 @@ int deal_with_timedout_reads() {
memcpy(&now, nsock_gettimeofday(), sizeof(struct timeval)); memcpy(&now, nsock_gettimeofday(), sizeof(struct timeval));
if (keyWasPressed()) if (keyWasPressed())
SPM->printStats((double) (stat_ok + stat_nx + stat_sf + stat_dropped) / stat_actual, &now); SPM->printStats((double) (stat_ok + stat_nx + stat_dropped) / stat_actual, &now);
for(servI = servs.begin(); servI != servs.end(); servI++) { for(servI = servs.begin(); servI != servs.end(); servI++) {
tpserv = *servI; tpserv = *servI;
@@ -1006,6 +1012,7 @@ void nmap_mass_rdns_core(Target **targets, int num_targets) {
int timeout; int timeout;
char *tpname; char *tpname;
int i; int i;
bool lasttrace = false;
if (o.mass_dns == false) { if (o.mass_dns == false) {
Target *currenths; Target *currenths;
@@ -1115,7 +1122,7 @@ void nmap_mass_rdns_core(Target **targets, int num_targets) {
if ((dnspool = nsp_new(NULL)) == NULL) if ((dnspool = nsp_new(NULL)) == NULL)
fatal("Unable to create nsock pool in nmap_mass_rdns_core()"); fatal("Unable to create nsock pool in nmap_mass_rdns_core()");
if (o.packetTrace()) if ((lasttrace = o.packetTrace()))
nsp_settrace(dnspool, 5, o.getStartTime()); nsp_settrace(dnspool, 5, o.getStartTime());
connect_dns_servers(); connect_dns_servers();
@@ -1133,6 +1140,13 @@ void nmap_mass_rdns_core(Target **targets, int num_targets) {
if (total_reqs <= 0) break; if (total_reqs <= 0) break;
/* Because this can change with runtime interaction */
if (o.packetTrace() != lasttrace) {
lasttrace = !lasttrace;
if (lasttrace)
nsp_settrace(dnspool, 5, o.getStartTime());
else nsp_settrace(dnspool, 0, o.getStartTime());
}
nsock_loop(dnspool, timeout); nsock_loop(dnspool, timeout);
} }
@@ -1198,12 +1212,12 @@ void nmap_mass_rdns(Target **targets, int num_targets) {
// #: Number of DNS servers used // #: Number of DNS servers used
// OK: Number of fully reverse resolved queries // OK: Number of fully reverse resolved queries
// NX: Number of confirmations of 'No such reverse domain eXists' // NX: Number of confirmations of 'No such reverse domain eXists'
// SF: Number of IPs that got 'Server Failure's
// DR: Dropped IPs (no valid responses were received) // DR: Dropped IPs (no valid responses were received)
// SF: Number of IPs that got 'Server Failure's
// TR: Total number of transmissions necessary. The number of domains is ideal, higher is worse // TR: Total number of transmissions necessary. The number of domains is ideal, higher is worse
log_write(LOG_STDOUT, "DNS resolution of %d IPs took %.2fs. Mode: Async [#: %lu, OK: %d, NX: %d, SF: %d, DR: %d, TR: %d, CN: %d]\n", log_write(LOG_STDOUT, "DNS resolution of %d IPs took %.2fs. Mode: Async [#: %lu, OK: %d, NX: %d, DR: %d, SF: %d, TR: %d, CN: %d]\n",
stat_actual, TIMEVAL_MSEC_SUBTRACT(now, starttv) / 1000.0, stat_actual, TIMEVAL_MSEC_SUBTRACT(now, starttv) / 1000.0,
servs.size(), stat_ok, stat_nx, stat_sf, stat_dropped, stat_trans, stat_cname); servs.size(), stat_ok, stat_nx, stat_dropped, stat_sf, stat_trans, stat_cname);
} else { } else {
log_write(LOG_STDOUT, "DNS resolution of %d IPs took %.2fs. Mode: System [OK: %d, ??: %d]\n", log_write(LOG_STDOUT, "DNS resolution of %d IPs took %.2fs. Mode: System [OK: %d, ??: %d]\n",
stat_actual, TIMEVAL_MSEC_SUBTRACT(now, starttv) / 1000.0, stat_actual, TIMEVAL_MSEC_SUBTRACT(now, starttv) / 1000.0,

View File

@@ -264,8 +264,6 @@ ScanProgressMeter::~ScanProgressMeter() {
bool ScanProgressMeter::mayBePrinted(const struct timeval *now) { bool ScanProgressMeter::mayBePrinted(const struct timeval *now) {
struct timeval tv; struct timeval tv;
return true;
if (!o.verbose) if (!o.verbose)
return false; return false;

5
tty.cc
View File

@@ -211,13 +211,14 @@ bool keyWasPressed()
o.verbose++; o.verbose++;
log_write(LOG_STDOUT, "Verbosity Increased to %d.\n", o.verbose); log_write(LOG_STDOUT, "Verbosity Increased to %d.\n", o.verbose);
} else if (c == 'V') { } else if (c == 'V') {
o.verbose--; if (o.verbose > 0)
o.verbose--;
log_write(LOG_STDOUT, "Verbosity Decreased to %d.\n", o.verbose); log_write(LOG_STDOUT, "Verbosity Decreased to %d.\n", o.verbose);
} else if (c == 'd') { } else if (c == 'd') {
o.debugging++; o.debugging++;
log_write(LOG_STDOUT, "Debugging Increased to %d.\n", o.debugging); log_write(LOG_STDOUT, "Debugging Increased to %d.\n", o.debugging);
} else if (c == 'D') { } else if (c == 'D') {
o.debugging--; if (o.debugging > 0) o.debugging--;
log_write(LOG_STDOUT, "Debugging Decreased to %d.\n", o.debugging); log_write(LOG_STDOUT, "Debugging Decreased to %d.\n", o.debugging);
} else if (c == 'p') { } else if (c == 'p') {
o.setPacketTrace(true); o.setPacketTrace(true);