From c58b7b25266bf1da9b02dc450d6593489000f3ab Mon Sep 17 00:00:00 2001 From: dmiller Date: Mon, 27 Jun 2022 23:01:44 +0000 Subject: [PATCH] Fix #2496: new targets couldn't be added because singleton object was not created --- CHANGELOG | 3 +++ NewTargets.cc | 39 +++++++-------------------------------- NewTargets.h | 16 +++------------- nmap.cc | 2 +- nse_nmaplib.cc | 2 +- targets.cc | 12 ++++++------ 6 files changed, 21 insertions(+), 53 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1af61ef27..8e8d66e10 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ #Nmap Changelog ($Id$); -*-text-*- +o [NSE][GH#2496] Fix newtargets support: since Nmap 7.92, scripts could not add + targets in script pre-scanning phase. [Daniel Miller] + o [GH#2468] Scripts dhcp-discover and broadcast-dhcp-discover now support setting a client identifier. [nnposter] diff --git a/NewTargets.cc b/NewTargets.cc index 934d6bd69..62ddfd952 100644 --- a/NewTargets.cc +++ b/NewTargets.cc @@ -66,30 +66,12 @@ #include "nmap_error.h" extern NmapOps o; /* option structure */ -NewTargets *NewTargets::new_targets; - -/* debug level for the adding target is: 3 */ -NewTargets *NewTargets::get (void) { - if (new_targets) - return new_targets; - new_targets = new NewTargets(); - return new_targets; -} +NewTargets *NewTargets::new_targets = NULL; void NewTargets::free_new_targets (void) { delete new_targets; } -NewTargets::NewTargets (void) { - Initialize(); -} - -void NewTargets::Initialize (void) { - history.clear(); - while (!queue.empty()) - queue.pop(); -} - /* This private method is used to push new targets to the * queue. It returns the number of targets in the queue. */ unsigned long NewTargets::push (const char *target) { @@ -109,7 +91,7 @@ unsigned long NewTargets::push (const char *target) { log_write(LOG_PLAIN, "New Targets: target %s pushed onto the queue.\n", tg.c_str()); } else { if (o.debugging > 2) - log_write(LOG_PLAIN, "New Targets: target %s is already in the queue.\n", tg.c_str()); + log_write(LOG_PLAIN, "New Targets: target %s was already added.\n", tg.c_str()); /* Return 1 when the target is already in the history cache, * this will prevent returning 0 when the target queue is * empty since no target was added. */ @@ -125,6 +107,8 @@ unsigned long NewTargets::push (const char *target) { std::string NewTargets::read (void) { std::string str; + new_targets = new_targets ? new_targets : new NewTargets(); + /* check to see it there are targets in the queue */ if (!new_targets->queue.empty()) { str = new_targets->queue.front(); @@ -134,19 +118,13 @@ std::string NewTargets::read (void) { return str; } -void NewTargets::clear (void) { - new_targets->history.clear(); -} - unsigned long NewTargets::get_number (void) { + new_targets = new_targets ? new_targets : new NewTargets(); return new_targets->history.size(); } -unsigned long NewTargets::get_scanned (void) { - return new_targets->history.size() - new_targets->queue.size(); -} - unsigned long NewTargets::get_queued (void) { + new_targets = new_targets ? new_targets : new NewTargets(); return new_targets->queue.size(); } @@ -155,11 +133,8 @@ unsigned long NewTargets::get_queued (void) { * Returns the number of targets in the queue on success, or 0 on * failures or when the queue is empty. */ unsigned long NewTargets::insert (const char *target) { + new_targets = new_targets ? new_targets : new NewTargets(); if (*target) { - if (new_targets == NULL) { - error("ERROR: to add targets run with -sC or --script options."); - return 0; - } if (o.current_scantype == SCRIPT_POST_SCAN) { error("ERROR: adding targets is disabled in the Post-scanning phase."); return 0; diff --git a/NewTargets.h b/NewTargets.h index 69b602085..01a2efe91 100644 --- a/NewTargets.h +++ b/NewTargets.h @@ -71,32 +71,24 @@ /* Adding new targets is for NSE scripts */ class NewTargets { public: - NewTargets(); /* return a previous inserted target */ static std::string read (void); - /* clear the scanned_targets_cache */ - static void clear (void); - /* get the number of all new added targets */ static unsigned long get_number (void); - /* get the number that have been scanned */ - static unsigned long get_scanned (void); - /* get the number of queued targets left to scan */ static unsigned long get_queued (void); - /* get the new_targets object */ - static NewTargets *get (void); /* Free the new_targets object. */ static void free_new_targets (void); /* insert targets to the new_targets_queue */ static unsigned long insert (const char *target); + private: - /* unsigned long mex_new_targets; */ + NewTargets() {}; /* A queue to push new targets that were discovered by NSE scripts. * Nmap will pop future targets from this queue. */ @@ -106,11 +98,9 @@ private: * (These are targets that were pushed to Nmap scan queue) */ std::set history; - void Initialize(); - /* Save new targets onto the queue */ unsigned long push (const char *target); -protected: + static NewTargets *new_targets; }; diff --git a/nmap.cc b/nmap.cc index e6964f61f..5aa21b87a 100644 --- a/nmap.cc +++ b/nmap.cc @@ -1786,6 +1786,7 @@ void apply_delayed_options() { // Free some global memory allocations. // This is used for detecting memory leaks. void nmap_free_mem() { + NewTargets::free_new_targets(); PortList::freePortMap(); cp_free(); free_services(); @@ -2313,7 +2314,6 @@ int nmap_main(int argc, char *argv[]) { #endif addrset_free(exclude_group); - NewTargets::free_new_targets(); if (o.inputfd != NULL) fclose(o.inputfd); diff --git a/nse_nmaplib.cc b/nse_nmaplib.cc index d333712ec..6b7c0e1b6 100644 --- a/nse_nmaplib.cc +++ b/nse_nmaplib.cc @@ -779,7 +779,7 @@ static int l_add_targets (lua_State *L) } else { /* function called without arguments */ /* push the number of pending targets that are in the queue */ - lua_pushinteger(L, NewTargets::insert("")); + lua_pushinteger(L, NewTargets::get_queued()); return 1; } } diff --git a/targets.cc b/targets.cc index 113bfaf21..97c459df8 100644 --- a/targets.cc +++ b/targets.cc @@ -325,15 +325,15 @@ const char *HostGroupState::next_expression() { /* Add any new NSE discovered targets to the scan queue */ static char buf[1024]; - NewTargets *new_targets = NewTargets::get(); - if (o.script && new_targets != NULL) { - if (new_targets->get_queued() > 0) { + if (o.script) { + unsigned long new_targets = NewTargets::get_queued(); + if (new_targets > 0) { std::string expr_string; - expr_string = new_targets->read().c_str(); + expr_string = NewTargets::read().c_str(); if (o.debugging > 3) { log_write(LOG_PLAIN, - "New targets in the scanned cache: %ld, pending ones: %ld.\n", - new_targets->get_scanned(), new_targets->get_queued()); + "New targets: retrieved one of %ld pending in queue.\n", + new_targets); } if (!expr_string.empty()) { Strncpy(buf, expr_string.c_str(), sizeof(buf));