mirror of
https://github.com/nmap/nmap.git
synced 2025-12-22 07:29:01 +00:00
merge soc07 r4727 - Added --top-ports/--port-ratio and wildcard/[] -p switch extensions.
This commit is contained in:
@@ -192,6 +192,7 @@ void NmapOps::Initialize() {
|
|||||||
randomize_hosts = 0;
|
randomize_hosts = 0;
|
||||||
sendpref = PACKET_SEND_NOPREF;
|
sendpref = PACKET_SEND_NOPREF;
|
||||||
spoofsource = 0;
|
spoofsource = 0;
|
||||||
|
fastscan = 0;
|
||||||
device[0] = '\0';
|
device[0] = '\0';
|
||||||
interactivemode = 0;
|
interactivemode = 0;
|
||||||
ping_group_sz = PING_GROUP_SZ;
|
ping_group_sz = PING_GROUP_SZ;
|
||||||
@@ -261,6 +262,7 @@ void NmapOps::Initialize() {
|
|||||||
ipopt_firsthop = 0;
|
ipopt_firsthop = 0;
|
||||||
ipopt_lasthop = 0;
|
ipopt_lasthop = 0;
|
||||||
release_memory = false;
|
release_memory = false;
|
||||||
|
topportlevel = -1;
|
||||||
#ifndef NOLUA
|
#ifndef NOLUA
|
||||||
script = 0;
|
script = 0;
|
||||||
scriptversion = 0;
|
scriptversion = 0;
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ class NmapOps {
|
|||||||
int verbose;
|
int verbose;
|
||||||
int randomize_hosts;
|
int randomize_hosts;
|
||||||
int spoofsource; /* -S used */
|
int spoofsource; /* -S used */
|
||||||
|
int fastscan;
|
||||||
char device[64];
|
char device[64];
|
||||||
int interactivemode;
|
int interactivemode;
|
||||||
int ping_group_sz;
|
int ping_group_sz;
|
||||||
@@ -191,6 +192,7 @@ class NmapOps {
|
|||||||
int timing_level; // 0-5, corresponding to Paranoid, Sneaky, Polite, Normal, Aggressive, Insane
|
int timing_level; // 0-5, corresponding to Paranoid, Sneaky, Polite, Normal, Aggressive, Insane
|
||||||
int max_parallelism; // 0 means it has not been set
|
int max_parallelism; // 0 means it has not been set
|
||||||
int min_parallelism; // 0 means it has not been set
|
int min_parallelism; // 0 means it has not been set
|
||||||
|
double topportlevel; // -1 means it has not been set
|
||||||
|
|
||||||
/* The maximum number of OS detection (gen2) tries we will make
|
/* The maximum number of OS detection (gen2) tries we will make
|
||||||
without any matches before giving up on a host. We may well give
|
without any matches before giving up on a host. We may well give
|
||||||
|
|||||||
299
nmap.cc
299
nmap.cc
@@ -230,8 +230,10 @@ printf("%s %s ( %s )\n"
|
|||||||
"PORT SPECIFICATION AND SCAN ORDER:\n"
|
"PORT SPECIFICATION AND SCAN ORDER:\n"
|
||||||
" -p <port ranges>: Only scan specified ports\n"
|
" -p <port ranges>: Only scan specified ports\n"
|
||||||
" Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080\n"
|
" Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080\n"
|
||||||
" -F: Fast - Scan only the ports listed in the nmap-services file)\n"
|
" -F: Fast mode - Scan fewer ports than the default scan\n"
|
||||||
" -r: Scan ports consecutively - don't randomize\n"
|
" -r: Scan ports consecutively - don't randomize\n"
|
||||||
|
" --top-ports <number>: Scan <number> most common ports\n"
|
||||||
|
" --port-ratio <ratio>: Scan ports more common than <ratio>\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-intensity <level>: Set from 0 (light) to 9 (try all probes)\n"
|
" --version-intensity <level>: Set from 0 (light) to 9 (try all probes)\n"
|
||||||
@@ -451,7 +453,7 @@ int nmap_main(int argc, char *argv[]) {
|
|||||||
unsigned int targetno;
|
unsigned int targetno;
|
||||||
FILE *inputfd = NULL, *excludefd = NULL;
|
FILE *inputfd = NULL, *excludefd = NULL;
|
||||||
char *host_spec = NULL, *exclude_spec = NULL;
|
char *host_spec = NULL, *exclude_spec = NULL;
|
||||||
short fastscan=0, randomize=1;
|
short randomize=1;
|
||||||
short quashargv = 0;
|
short quashargv = 0;
|
||||||
char **host_exp_group;
|
char **host_exp_group;
|
||||||
char *idleProxy = NULL; /* The idle host used to "Proxy" an Idlescan */
|
char *idleProxy = NULL; /* The idle host used to "Proxy" an Idlescan */
|
||||||
@@ -600,6 +602,8 @@ int nmap_main(int argc, char *argv[]) {
|
|||||||
{"log-errors", no_argument, 0, 0},
|
{"log-errors", no_argument, 0, 0},
|
||||||
{"dns_servers", required_argument, 0, 0},
|
{"dns_servers", required_argument, 0, 0},
|
||||||
{"dns-servers", required_argument, 0, 0},
|
{"dns-servers", required_argument, 0, 0},
|
||||||
|
{"port-ratio", required_argument, 0, 0},
|
||||||
|
{"top-ports", required_argument, 0, 0},
|
||||||
#ifndef NOLUA
|
#ifndef NOLUA
|
||||||
{"script", required_argument, 0, 0},
|
{"script", required_argument, 0, 0},
|
||||||
{"script-trace", no_argument, 0, 0},
|
{"script-trace", no_argument, 0, 0},
|
||||||
@@ -829,6 +833,16 @@ int nmap_main(int argc, char *argv[]) {
|
|||||||
o.fragscan = atoi(optarg);
|
o.fragscan = atoi(optarg);
|
||||||
if (o.fragscan <= 0 || o.fragscan % 8 != 0)
|
if (o.fragscan <= 0 || o.fragscan % 8 != 0)
|
||||||
fatal("Data payload MTU must be >0 and multiple of 8");
|
fatal("Data payload MTU must be >0 and multiple of 8");
|
||||||
|
} else if (strcmp(long_options[option_index].name, "port-ratio") == 0) {
|
||||||
|
char *ptr;
|
||||||
|
o.topportlevel = strtod(optarg, &ptr);
|
||||||
|
if (!ptr || o.topportlevel < 0 || o.topportlevel >= 1)
|
||||||
|
fatal("--port-ratio should be between [0 and 1)");
|
||||||
|
} else if (strcmp(long_options[option_index].name, "top-ports") == 0) {
|
||||||
|
char *ptr;
|
||||||
|
o.topportlevel = strtod(optarg, &ptr);
|
||||||
|
if (!ptr || o.topportlevel < 1 || ((double)((int)o.topportlevel)) != o.topportlevel)
|
||||||
|
fatal("--top-ports should be an integer 1 or greater");
|
||||||
} else if (optcmp(long_options[option_index].name, "ip-options") == 0){
|
} else if (optcmp(long_options[option_index].name, "ip-options") == 0){
|
||||||
o.ipoptions = (u8*) safe_malloc(4*10+1);
|
o.ipoptions = (u8*) safe_malloc(4*10+1);
|
||||||
o.ipoptionslen = parse_ip_options(optarg, o.ipoptions, 4*10+1, &o.ipopt_firsthop, &o.ipopt_lasthop);
|
o.ipoptionslen = parse_ip_options(optarg, o.ipoptions, 4*10+1, &o.ipopt_firsthop, &o.ipopt_lasthop);
|
||||||
@@ -896,7 +910,7 @@ int nmap_main(int argc, char *argv[]) {
|
|||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
Strncpy(o.device, optarg, sizeof(o.device)); break;
|
Strncpy(o.device, optarg, sizeof(o.device)); break;
|
||||||
case 'F': fastscan++; break;
|
case 'F': o.fastscan++; break;
|
||||||
case 'f': o.fragscan += 8; break;
|
case 'f': o.fragscan += 8; break;
|
||||||
case 'g':
|
case 'g':
|
||||||
o.magic_port = atoi(optarg);
|
o.magic_port = atoi(optarg);
|
||||||
@@ -1202,25 +1216,29 @@ int nmap_main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((o.pingscan || o.listscan) && (portlist || fastscan)) {
|
if ((o.pingscan || o.listscan) && (portlist || o.fastscan))
|
||||||
fatal("You cannot use -F (fast scan) or -p (explicit port selection) with PING scan or LIST scan");
|
fatal("You cannot use -F (fast scan) or -p (explicit port selection) with PING scan or LIST scan");
|
||||||
|
|
||||||
|
if (portlist && o.fastscan)
|
||||||
|
fatal("You cannot use -F (fast scan) with -p (explicit port selection) but see --top-ports and --port-ratio to fast scan a range of ports");
|
||||||
|
|
||||||
|
if (o.ipprotscan) {
|
||||||
|
if (portlist) ports = getpts(portlist);
|
||||||
|
else ports = getpts((char *) (o.fastscan ? "[P:0-]" : "0-")); // Default protocols to scan
|
||||||
|
} else {
|
||||||
|
ports = gettoppts(o.topportlevel, portlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (portlist && !ports)
|
||||||
|
fatal("Your port specification string is not parseable");
|
||||||
|
|
||||||
if (portlist) {
|
if (portlist) {
|
||||||
ports = getpts(portlist);
|
|
||||||
if (!ports)
|
|
||||||
fatal("Your port specification string is not parseable");
|
|
||||||
free(portlist);
|
free(portlist);
|
||||||
portlist = NULL;
|
portlist = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fastscan && ports) {
|
// Uncomment the following line to use the common lisp port spec test suite
|
||||||
fatal("You can specify fast scan (-F) or explicitly select individual ports (-p), but not both");
|
//printf("port spec: (%d %d %d)\n", ports->tcp_count, ports->udp_count, ports->prot_count); exit(0);
|
||||||
} else if (fastscan && o.ipprotscan) {
|
|
||||||
ports = getfastprots();
|
|
||||||
} else if (fastscan) {
|
|
||||||
ports = getfastports(o.TCPScan(), o.UDPScan());
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (o.sendpref & PACKET_SEND_IP) {
|
if (o.sendpref & PACKET_SEND_IP) {
|
||||||
@@ -1274,14 +1292,6 @@ int nmap_main(int argc, char *argv[]) {
|
|||||||
o.sendpref = PACKET_SEND_ETH_STRONG;
|
o.sendpref = PACKET_SEND_ETH_STRONG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ports) {
|
|
||||||
if (o.ipprotscan) {
|
|
||||||
ports = getdefaultprots();
|
|
||||||
} else {
|
|
||||||
ports = getdefaultports(o.TCPScan(), o.UDPScan());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* By now, we've got our port lists. Give the user a warning if no
|
/* By now, we've got our port lists. Give the user a warning if no
|
||||||
* ports are specified for the type of scan being requested. Other things
|
* ports are specified for the type of scan being requested. Other things
|
||||||
* (such as OS ident scan) might break cause no ports were specified, but
|
* (such as OS ident scan) might break cause no ports were specified, but
|
||||||
@@ -1930,19 +1940,74 @@ void init_socket(int sd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert a string like "-100,200-1024,3000-4000,60000-" into an array
|
|
||||||
of port numbers. Note that one trailing comma is OK -- this is actually
|
|
||||||
useful for machine generated lists */
|
/* Convert a string like "-100,n*tp,200-1024,3000-4000,[60000-]" into an array
|
||||||
|
* of port numbers. Note that one trailing comma is OK -- this is actually
|
||||||
|
* useful for machine generated lists
|
||||||
|
*
|
||||||
|
* Fyodor - Wrote original
|
||||||
|
* William McVey - Added T:, U:, P: directives
|
||||||
|
* Doug Hoyte - Added [], name lookups, and wildcard expansion
|
||||||
|
*
|
||||||
|
* getpts() handles []
|
||||||
|
* Any port ranges included inside square brackets will have all
|
||||||
|
* their ports looked up in nmap-services or nmap-protocols
|
||||||
|
* and will only be included if they are found.
|
||||||
|
* Returns a scan_list* with all the ports that should be scanned.
|
||||||
|
*
|
||||||
|
* getpts() handles service/protocol name lookups and wildcard expansion.
|
||||||
|
* The service name can be specified instead of the port number.
|
||||||
|
* For example, "ssh" can be used instead of "22". You can use wildcards
|
||||||
|
* like "*" and "?". See the function wildtest() for the exact details.
|
||||||
|
* For example,
|
||||||
|
*
|
||||||
|
* nmap -p http* host
|
||||||
|
*
|
||||||
|
* Will scan http (80), http-mgmt (280), http-proxy (8080), https (443), etc.
|
||||||
|
*
|
||||||
|
* Matching is case INsensitive but the first character in a match MUST
|
||||||
|
* be lowercase so it doesn't conflict with the T:, U:, and P: directives.
|
||||||
|
*
|
||||||
|
* getpts() is unable to match service names that start with a digit
|
||||||
|
* like 3com-tsmux (106/udp). Use a pattern like "?com-*" instead.
|
||||||
|
*
|
||||||
|
* BE CAREFUL ABOUT SHELL EXPANSIONS!!!
|
||||||
|
* If you are trying to match the services nmsp (537/tcp) and nms (1429/tcp)
|
||||||
|
* and you execute the command
|
||||||
|
*
|
||||||
|
* ./nmap -p nm* host
|
||||||
|
*
|
||||||
|
* You will see
|
||||||
|
*
|
||||||
|
* Found no matches for the service mask 'nmap' and your specified protocols
|
||||||
|
* QUITTING!
|
||||||
|
*
|
||||||
|
* This is because nm* was expanded to the name of the binary file nmap in
|
||||||
|
* the current directory by your shell. When unsure, quote your port strings
|
||||||
|
* to be safe:
|
||||||
|
*
|
||||||
|
* ./nmap -p 'nm*' host
|
||||||
|
*
|
||||||
|
* getpts() is smart enough to keep the T: U: and P: directives nested
|
||||||
|
* and working in a logical manner. For instance,
|
||||||
|
*
|
||||||
|
* nmap -sTU -p [U:1025-],1-1024 host
|
||||||
|
*
|
||||||
|
* Will scan UDP ports 1025 and up that are found in the service file
|
||||||
|
* and all TCP/UDP ports below <= 1024. Notice that the U doesn't affect
|
||||||
|
* the outer part of the port expression. It's "closed".
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void getpts_aux(char *origexpr, int nested, u8 *porttbl, struct scan_lists *ports, int range_type, int
|
||||||
|
*portwarning);
|
||||||
|
|
||||||
struct scan_lists *getpts(char *origexpr) {
|
struct scan_lists *getpts(char *origexpr) {
|
||||||
u8 *porttbl;
|
u8 *porttbl;
|
||||||
int portwarning = 0; /* have we warned idiot about dup ports yet? */
|
|
||||||
long rangestart = -2343242, rangeend = -9324423;
|
|
||||||
char *current_range;
|
|
||||||
char *endptr;
|
|
||||||
int i;
|
|
||||||
int tcpportcount = 0, udpportcount = 0, protcount = 0;
|
|
||||||
struct scan_lists *ports;
|
struct scan_lists *ports;
|
||||||
int range_type = 0;
|
int range_type = 0;
|
||||||
|
int portwarning = 0;
|
||||||
|
int i, tcpi, udpi, proti;
|
||||||
|
|
||||||
if (o.TCPScan())
|
if (o.TCPScan())
|
||||||
range_type |= SCAN_TCP_PORT;
|
range_type |= SCAN_TCP_PORT;
|
||||||
@@ -1952,11 +2017,58 @@ struct scan_lists *getpts(char *origexpr) {
|
|||||||
range_type |= SCAN_PROTOCOLS;
|
range_type |= SCAN_PROTOCOLS;
|
||||||
|
|
||||||
porttbl = (u8 *) safe_zalloc(65536);
|
porttbl = (u8 *) safe_zalloc(65536);
|
||||||
|
ports = (struct scan_lists *) safe_zalloc(sizeof(struct scan_lists));
|
||||||
|
|
||||||
|
getpts_aux(origexpr, // Pass on the expression
|
||||||
|
0, // Don't start off nested
|
||||||
|
porttbl, // Our allocated port table
|
||||||
|
ports, // The destination structure - passed so we can track the number of tcp/udp/prot ports
|
||||||
|
range_type, // Defaults to TCP/UDP/Protos
|
||||||
|
&portwarning); // No, we haven't warned them about dup ports yet
|
||||||
|
|
||||||
|
if ( 0 == (ports->tcp_count + ports->udp_count + ports->prot_count))
|
||||||
|
fatal("No ports specified -- If you really don't want to scan any ports use ping scan...");
|
||||||
|
|
||||||
|
if (ports->tcp_count) {
|
||||||
|
ports->tcp_ports = (unsigned short *)safe_zalloc(ports->tcp_count * sizeof(unsigned short));
|
||||||
|
}
|
||||||
|
if (ports->udp_count) {
|
||||||
|
ports->udp_ports = (unsigned short *)safe_zalloc(ports->udp_count * sizeof(unsigned short));
|
||||||
|
}
|
||||||
|
if (ports->prot_count) {
|
||||||
|
ports->prots = (unsigned short *)safe_zalloc(ports->prot_count * sizeof(unsigned short));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=tcpi=udpi=proti=0; i <= 65535; i++) {
|
||||||
|
if (porttbl[i] & SCAN_TCP_PORT)
|
||||||
|
ports->tcp_ports[tcpi++] = i;
|
||||||
|
if (porttbl[i] & SCAN_UDP_PORT)
|
||||||
|
ports->udp_ports[udpi++] = i;
|
||||||
|
if (porttbl[i] & SCAN_PROTOCOLS && i < 256)
|
||||||
|
ports->prots[proti++] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(porttbl);
|
||||||
|
|
||||||
|
return ports;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* getpts() (see above) is a wrapper for this function */
|
||||||
|
|
||||||
|
static void getpts_aux(char *origexpr, int nested, u8 *porttbl, struct scan_lists *ports, int range_type, int *portwarning) {
|
||||||
|
long rangestart = -2343242, rangeend = -9324423;
|
||||||
|
char *current_range;
|
||||||
|
char *endptr;
|
||||||
|
char servmask[128]; // A protocol name can be up to 127 chars + nul byte
|
||||||
|
int i;
|
||||||
|
|
||||||
current_range = origexpr;
|
current_range = origexpr;
|
||||||
do {
|
do {
|
||||||
while(isspace((int) *current_range))
|
while(isspace((int) *current_range))
|
||||||
current_range++; /* I don't know why I should allow spaces here, but I will */
|
current_range++; /* I don't know why I should allow spaces here, but I will */
|
||||||
|
|
||||||
if (*current_range == 'T' && *++current_range == ':') {
|
if (*current_range == 'T' && *++current_range == ':') {
|
||||||
current_range++;
|
current_range++;
|
||||||
range_type = SCAN_TCP_PORT;
|
range_type = SCAN_TCP_PORT;
|
||||||
@@ -1972,7 +2084,26 @@ struct scan_lists *getpts(char *origexpr) {
|
|||||||
range_type = SCAN_PROTOCOLS;
|
range_type = SCAN_PROTOCOLS;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (*current_range == '-') {
|
if (*current_range == '[') {
|
||||||
|
if (nested)
|
||||||
|
fatal("Can't nest [] brackets in -p switch");
|
||||||
|
|
||||||
|
getpts_aux(++current_range, 1, porttbl, ports, range_type, portwarning);
|
||||||
|
|
||||||
|
// Skip past the ']'. This is OK because we can't nest []s
|
||||||
|
while(*current_range != ']') current_range++;
|
||||||
|
current_range++;
|
||||||
|
|
||||||
|
// Skip over a following ',' so we're ready to keep parsing
|
||||||
|
if (*current_range == ',') current_range++;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
} else if (*current_range == ']') {
|
||||||
|
if (!nested)
|
||||||
|
fatal("Unexpected ] character in -p switch");
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else if (*current_range == '-') {
|
||||||
rangestart = o.ipprotscan ? 0 : 1;
|
rangestart = o.ipprotscan ? 0 : 1;
|
||||||
}
|
}
|
||||||
else if (isdigit((int) *current_range)) {
|
else if (isdigit((int) *current_range)) {
|
||||||
@@ -1984,21 +2115,38 @@ struct scan_lists *getpts(char *origexpr) {
|
|||||||
if (rangestart < 0 || rangestart > 65535)
|
if (rangestart < 0 || rangestart > 65535)
|
||||||
fatal("Ports to be scanned must be between 0 and 65535 inclusive");
|
fatal("Ports to be scanned must be between 0 and 65535 inclusive");
|
||||||
}
|
}
|
||||||
/* if (rangestart == 0) {
|
|
||||||
error("WARNING: Scanning \"port 0\" is supported, but unusual.");
|
|
||||||
} */
|
|
||||||
current_range = endptr;
|
current_range = endptr;
|
||||||
while(isspace((int) *current_range)) current_range++;
|
while(isspace((int) *current_range)) current_range++;
|
||||||
|
} else if (islower((int) *current_range) || *current_range == '*' || *current_range == '?') {
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
while (*current_range && !isspace((int)*current_range) && *current_range != ',' && *current_range != ']') {
|
||||||
|
servmask[i++] = *(current_range++);
|
||||||
|
if (i >= ((int)sizeof(servmask)-1))
|
||||||
|
fatal("A service mask in the -p switch is either malformed or too long");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*current_range && *current_range != ']') current_range++; // We want the '] character to be picked up on the next pass
|
||||||
|
servmask[i] = '\0'; // Finish the string
|
||||||
|
|
||||||
|
i = addportsfromservmask(servmask, porttbl, ports, range_type);
|
||||||
|
if (range_type & SCAN_PROTOCOLS) i += addprotocolsfromservmask(servmask, porttbl, ports);
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
fatal("Found no matches for the service mask '%s' and your specified protocols", servmask);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fatal("Error #485: Your port specifications are illegal. Example of proper form: \"-100,200-1024,T:3000-4000,U:60000-\"");
|
fatal("Error #485: Your port specifications are illegal. Example of proper form: \"-100,200-1024,T:3000-4000,U:60000-\"");
|
||||||
}
|
}
|
||||||
/* Now I have a rangestart, time to go after rangeend */
|
/* Now I have a rangestart, time to go after rangeend */
|
||||||
if (!*current_range || *current_range == ',') {
|
if (!*current_range || *current_range == ',' || *current_range == ']') {
|
||||||
/* Single port specification */
|
/* Single port specification */
|
||||||
rangeend = rangestart;
|
rangeend = rangestart;
|
||||||
} else if (*current_range == '-') {
|
} else if (*current_range == '-') {
|
||||||
current_range++;
|
current_range++;
|
||||||
if (!*current_range || *current_range == ',') {
|
if (!*current_range || *current_range == ',' || *current_range == ']') {
|
||||||
/* Ended with a -, meaning up until the last possible port */
|
/* Ended with a -, meaning up until the last possible port */
|
||||||
rangeend = o.ipprotscan ? 255 : 65535;
|
rangeend = o.ipprotscan ? 255 : 65535;
|
||||||
} else if (isdigit((int) *current_range)) {
|
} else if (isdigit((int) *current_range)) {
|
||||||
@@ -2021,24 +2169,45 @@ struct scan_lists *getpts(char *origexpr) {
|
|||||||
/* Now I have a rangestart and a rangeend, so I can add these ports */
|
/* Now I have a rangestart and a rangeend, so I can add these ports */
|
||||||
while(rangestart <= rangeend) {
|
while(rangestart <= rangeend) {
|
||||||
if (porttbl[rangestart] & range_type) {
|
if (porttbl[rangestart] & range_type) {
|
||||||
if (!portwarning) {
|
if (!(*portwarning)) {
|
||||||
error("WARNING: Duplicate port number(s) specified. Are you alert enough to be using Nmap? Have some coffee or Jolt(tm).");
|
error("WARNING: Duplicate port number(s) specified. Are you alert enough to be using Nmap? Have some coffee or Jolt(tm).");
|
||||||
portwarning++;
|
(*portwarning)++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (range_type & SCAN_TCP_PORT)
|
if (nested) {
|
||||||
tcpportcount++;
|
if ((range_type & SCAN_TCP_PORT) &&
|
||||||
if (range_type & SCAN_UDP_PORT)
|
nmap_getservbyport(htons(rangestart), "tcp")) {
|
||||||
udpportcount++;
|
ports->tcp_count++;
|
||||||
if (range_type & SCAN_PROTOCOLS)
|
porttbl[rangestart] |= SCAN_TCP_PORT;
|
||||||
protcount++;
|
}
|
||||||
porttbl[rangestart] |= range_type;
|
if ((range_type & SCAN_UDP_PORT) &&
|
||||||
|
nmap_getservbyport(htons(rangestart), "udp")) {
|
||||||
|
ports->udp_count++;
|
||||||
|
porttbl[rangestart] |= SCAN_UDP_PORT;
|
||||||
|
}
|
||||||
|
if ((range_type & SCAN_PROTOCOLS) &&
|
||||||
|
nmap_getprotbynum(htons(rangestart))) {
|
||||||
|
ports->prot_count++;
|
||||||
|
porttbl[rangestart] |= SCAN_PROTOCOLS;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (range_type & SCAN_TCP_PORT)
|
||||||
|
ports->tcp_count++;
|
||||||
|
if (range_type & SCAN_UDP_PORT)
|
||||||
|
ports->udp_count++;
|
||||||
|
if (range_type & SCAN_PROTOCOLS && rangestart < 256)
|
||||||
|
ports->prot_count++;
|
||||||
|
porttbl[rangestart] |= range_type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rangestart++;
|
rangestart++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the next range */
|
/* Find the next range */
|
||||||
while(isspace((int) *current_range)) current_range++;
|
while(isspace((int) *current_range)) current_range++;
|
||||||
|
|
||||||
|
if (*current_range == ']') return;
|
||||||
|
|
||||||
if (*current_range && *current_range != ',') {
|
if (*current_range && *current_range != ',') {
|
||||||
fatal("Error #488: Your port specifications are illegal. Example of proper form: \"-100,200-1024,3000-4000,60000-\"");
|
fatal("Error #488: Your port specifications are illegal. Example of proper form: \"-100,200-1024,3000-4000,60000-\"");
|
||||||
}
|
}
|
||||||
@@ -2046,45 +2215,13 @@ struct scan_lists *getpts(char *origexpr) {
|
|||||||
current_range++;
|
current_range++;
|
||||||
} while(current_range && *current_range);
|
} while(current_range && *current_range);
|
||||||
|
|
||||||
if ( 0 == (tcpportcount + udpportcount + protcount))
|
|
||||||
fatal("No ports specified -- If you really don't want to scan any ports use ping scan...");
|
|
||||||
|
|
||||||
ports = (struct scan_lists *) safe_zalloc(sizeof(struct scan_lists));
|
|
||||||
|
|
||||||
if (tcpportcount) {
|
|
||||||
ports->tcp_ports = (unsigned short *)safe_zalloc(tcpportcount * sizeof(unsigned short));
|
|
||||||
}
|
|
||||||
if (udpportcount) {
|
|
||||||
ports->udp_ports = (unsigned short *)safe_zalloc(udpportcount * sizeof(unsigned short));
|
|
||||||
}
|
|
||||||
if (protcount) {
|
|
||||||
ports->prots = (unsigned short *)safe_zalloc(protcount * sizeof(unsigned short));
|
|
||||||
}
|
|
||||||
ports->tcp_count = tcpportcount;
|
|
||||||
ports->udp_count = udpportcount;
|
|
||||||
ports->prot_count = protcount;
|
|
||||||
|
|
||||||
tcpportcount=0;
|
|
||||||
udpportcount=0;
|
|
||||||
protcount=0;
|
|
||||||
for(i=0; i <= 65535; i++) {
|
|
||||||
if (porttbl[i] & SCAN_TCP_PORT)
|
|
||||||
ports->tcp_ports[tcpportcount++] = i;
|
|
||||||
if (porttbl[i] & SCAN_UDP_PORT)
|
|
||||||
ports->udp_ports[udpportcount++] = i;
|
|
||||||
if (porttbl[i] & SCAN_PROTOCOLS && i < 256)
|
|
||||||
ports->prots[protcount++] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(porttbl);
|
|
||||||
return ports;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_scan_lists(struct scan_lists *ports) {
|
void free_scan_lists(struct scan_lists *ports) {
|
||||||
if (ports) {
|
if (ports) {
|
||||||
free(ports->tcp_ports);
|
if (ports->tcp_ports) free(ports->tcp_ports);
|
||||||
free(ports->udp_ports);
|
if (ports->udp_ports) free(ports->udp_ports);
|
||||||
free(ports->prots);
|
if (ports->prots) free(ports->prots);
|
||||||
free(ports);
|
free(ports);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
90
protocols.cc
90
protocols.cc
@@ -178,9 +178,40 @@ static int nmap_protocols_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Adds protocols whose names match mask to porttbl.
|
||||||
|
* Increases the prot_count in ports by the number of protocols added.
|
||||||
|
* Returns the number of protocols added.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
int addprotocolsfromservmask(char *mask, u8 *porttbl, struct scan_lists *ports) {
|
||||||
|
struct protocol_list *current;
|
||||||
|
int bucket, t=0;
|
||||||
|
|
||||||
|
if (!protocols_initialized && nmap_protocols_init() == -1)
|
||||||
|
fatal("addprotocolsfromservmask: Couldn't get protocol numbers");
|
||||||
|
|
||||||
|
for(bucket = 0; bucket < PROTOCOL_TABLE_SIZE; bucket++) {
|
||||||
|
for(current = protocol_table[bucket % PROTOCOL_TABLE_SIZE]; current; current = current->next) {
|
||||||
|
if (wildtest(mask, current->protoent->p_name)) {
|
||||||
|
porttbl[ntohs(current->protoent->p_proto)] |= SCAN_PROTOCOLS;
|
||||||
|
ports->prot_count++;
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct protoent *nmap_getprotbynum(int num) {
|
struct protoent *nmap_getprotbynum(int num) {
|
||||||
struct protocol_list *current;
|
struct protocol_list *current;
|
||||||
nmap_protocols_init();
|
|
||||||
|
if (nmap_protocols_init() == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
for(current = protocol_table[num % PROTOCOL_TABLE_SIZE];
|
for(current = protocol_table[num % PROTOCOL_TABLE_SIZE];
|
||||||
current; current = current->next) {
|
current; current = current->next) {
|
||||||
if (num == current->protoent->p_proto)
|
if (num == current->protoent->p_proto)
|
||||||
@@ -189,61 +220,4 @@ struct protoent *nmap_getprotbynum(int num) {
|
|||||||
|
|
||||||
/* Couldn't find it ... oh well. */
|
/* Couldn't find it ... oh well. */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* By default we do all prots 0-255. */
|
|
||||||
struct scan_lists *getdefaultprots(void) {
|
|
||||||
int protindex = 0;
|
|
||||||
struct scan_lists *scanlist;
|
|
||||||
/*struct protocol_list *current;*/
|
|
||||||
int bucket;
|
|
||||||
int protsneeded = 256;
|
|
||||||
|
|
||||||
if (nmap_protocols_init() == -1)
|
|
||||||
fatal("getdefaultprots(): Couldn't get protocol numbers");
|
|
||||||
|
|
||||||
scanlist = (struct scan_lists *) safe_zalloc(sizeof(struct scan_lists));
|
|
||||||
scanlist->prots = (unsigned short *) safe_zalloc((protsneeded) * sizeof(unsigned short));
|
|
||||||
scanlist->prot_count = protsneeded;
|
|
||||||
|
|
||||||
for(bucket = 0; bucket < protsneeded; bucket++) {
|
|
||||||
scanlist->prots[protindex++] = bucket;
|
|
||||||
}
|
|
||||||
return scanlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct scan_lists *getfastprots(void) {
|
|
||||||
int protindex = 0;
|
|
||||||
struct scan_lists *scanlist;
|
|
||||||
char usedprots[256];
|
|
||||||
struct protocol_list *current;
|
|
||||||
int bucket;
|
|
||||||
int protsneeded = 0;
|
|
||||||
|
|
||||||
if (nmap_protocols_init() == -1)
|
|
||||||
fatal("Getfastprots: Couldn't get protocol numbers");
|
|
||||||
|
|
||||||
memset(usedprots, 0, sizeof(usedprots));
|
|
||||||
|
|
||||||
for(bucket = 0; bucket < PROTOCOL_TABLE_SIZE; bucket++) {
|
|
||||||
for(current = protocol_table[bucket % PROTOCOL_TABLE_SIZE];
|
|
||||||
current; current = current->next) {
|
|
||||||
if (!usedprots[ntohs(current->protoent->p_proto)])
|
|
||||||
usedprots[ntohs(current->protoent->p_proto)] = 1;
|
|
||||||
protsneeded++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scanlist = (struct scan_lists *) safe_zalloc(sizeof(struct scan_lists));
|
|
||||||
scanlist->prots = (unsigned short *) safe_zalloc((protsneeded ) * sizeof(unsigned short));
|
|
||||||
scanlist->prot_count = protsneeded;
|
|
||||||
|
|
||||||
for(bucket = 0; bucket < 256; bucket++) {
|
|
||||||
if (usedprots[bucket])
|
|
||||||
scanlist->prots[protindex++] = bucket;
|
|
||||||
}
|
|
||||||
|
|
||||||
return scanlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -119,9 +119,7 @@ struct protocol_list {
|
|||||||
struct protocol_list *next;
|
struct protocol_list *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int addprotocolsfromservmask(char *mask, u8 *porttbl, struct scan_lists *ports);
|
||||||
struct protoent *nmap_getprotbynum(int num);
|
struct protoent *nmap_getprotbynum(int num);
|
||||||
struct scan_lists *getfastprots(void);
|
|
||||||
struct scan_lists *getdefaultprots(void);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
339
services.cc
339
services.cc
@@ -106,9 +106,11 @@ extern NmapOps o;
|
|||||||
static int numtcpports = 0;
|
static int numtcpports = 0;
|
||||||
static int numudpports = 0;
|
static int numudpports = 0;
|
||||||
static struct service_list *service_table[SERVICE_TABLE_SIZE];
|
static struct service_list *service_table[SERVICE_TABLE_SIZE];
|
||||||
|
static struct service_list *sorted_services = NULL;
|
||||||
|
static int services_initialized = 0;
|
||||||
|
static int ratio_format = 0; // 0 = /etc/services no-ratio format. 1 = new nmap format
|
||||||
|
|
||||||
static int nmap_services_init() {
|
static int nmap_services_init() {
|
||||||
static int services_initialized = 0;
|
|
||||||
if (services_initialized) return 0;
|
if (services_initialized) return 0;
|
||||||
|
|
||||||
char filename[512];
|
char filename[512];
|
||||||
@@ -118,8 +120,10 @@ static int nmap_services_init() {
|
|||||||
char *p;
|
char *p;
|
||||||
char line[1024];
|
char line[1024];
|
||||||
int lineno = 0;
|
int lineno = 0;
|
||||||
struct service_list *current, *previous;
|
struct service_list *current, *previous, *sp;
|
||||||
int res;
|
int res;
|
||||||
|
double ratio;
|
||||||
|
int ratio_n, ratio_d;
|
||||||
|
|
||||||
if (nmap_fetchfile(filename, sizeof(filename), "nmap-services") != 1) {
|
if (nmap_fetchfile(filename, sizeof(filename), "nmap-services") != 1) {
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@@ -159,12 +163,27 @@ static int nmap_services_init() {
|
|||||||
p++;
|
p++;
|
||||||
if (*p == '#')
|
if (*p == '#')
|
||||||
continue;
|
continue;
|
||||||
res = sscanf(line, "%127s %hu/%15s", servicename, &portno, proto);
|
|
||||||
if (res !=3)
|
res = sscanf(line, "%127s %hu/%15s %d/%d", servicename, &portno, proto, &ratio_n, &ratio_d);
|
||||||
|
|
||||||
|
if (res == 3) {
|
||||||
|
ratio = 0;
|
||||||
|
} else if (res == 5) {
|
||||||
|
if (ratio_n > ratio_d)
|
||||||
|
fatal("%s:%d has a ratio %g. All ratios must be < 1", filename, lineno, (double)ratio_n/ratio_d);
|
||||||
|
|
||||||
|
if (ratio_d == 0)
|
||||||
|
fatal("%s:%d has a ratio denominator of 0 causing a division by 0 error", filename, lineno);
|
||||||
|
|
||||||
|
ratio = (double)ratio_n / ratio_d;
|
||||||
|
ratio_format = 1;
|
||||||
|
} else {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
portno = htons(portno);
|
portno = htons(portno);
|
||||||
|
|
||||||
/* Now we make sure our services doesn't have duplicates */
|
/* Now we make sure our service table doesn't have duplicates */
|
||||||
for(current = service_table[portno % SERVICE_TABLE_SIZE], previous = NULL;
|
for(current = service_table[portno % SERVICE_TABLE_SIZE], previous = NULL;
|
||||||
current; current = current->next) {
|
current; current = current->next) {
|
||||||
if (portno == (u16) current->servent->s_port &&
|
if (portno == (u16) current->servent->s_port &&
|
||||||
@@ -198,6 +217,7 @@ static int nmap_services_init() {
|
|||||||
|
|
||||||
current = (struct service_list *) cp_alloc(sizeof(struct service_list));
|
current = (struct service_list *) cp_alloc(sizeof(struct service_list));
|
||||||
current->servent = (struct servent *) cp_alloc(sizeof(struct servent));
|
current->servent = (struct servent *) cp_alloc(sizeof(struct servent));
|
||||||
|
current->ratio = ratio;
|
||||||
current->next = NULL;
|
current->next = NULL;
|
||||||
if (previous == NULL) {
|
if (previous == NULL) {
|
||||||
service_table[portno % SERVICE_TABLE_SIZE] = current;
|
service_table[portno % SERVICE_TABLE_SIZE] = current;
|
||||||
@@ -208,13 +228,75 @@ static int nmap_services_init() {
|
|||||||
current->servent->s_port = portno;
|
current->servent->s_port = portno;
|
||||||
current->servent->s_proto = cp_strdup(proto);
|
current->servent->s_proto = cp_strdup(proto);
|
||||||
current->servent->s_aliases = NULL;
|
current->servent->s_aliases = NULL;
|
||||||
|
|
||||||
|
sp = (struct service_list *) cp_alloc(sizeof(struct service_list));
|
||||||
|
sp->servent = current->servent;
|
||||||
|
sp->ratio = current->ratio;
|
||||||
|
sp->next = NULL;
|
||||||
|
|
||||||
|
if (sorted_services == NULL || sorted_services->ratio < sp->ratio) {
|
||||||
|
sp->next = sorted_services;
|
||||||
|
sorted_services = sp;
|
||||||
|
} else
|
||||||
|
for (current=sorted_services;;current=current->next) {
|
||||||
|
if (current->next == NULL) {
|
||||||
|
current->next = sp;
|
||||||
|
break;
|
||||||
|
} else if (current->next->ratio < sp->ratio) {
|
||||||
|
sp->next = current->next;
|
||||||
|
current->next = sp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
services_initialized = 1;
|
services_initialized = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Adds ports whose names match mask and one or more protocols
|
||||||
|
* specified by range_type to porttbl. Increases the respective
|
||||||
|
* protocol counts in ports.
|
||||||
|
* Returns the number of ports added in total.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int addportsfromservmask(char *mask, u8 *porttbl, struct scan_lists *ports, int range_type) {
|
||||||
|
struct service_list *current;
|
||||||
|
int bucket,t=0;
|
||||||
|
|
||||||
|
if (!services_initialized && nmap_services_init() == -1)
|
||||||
|
fatal("addportsfromservmask: Couldn't get port numbers");
|
||||||
|
|
||||||
|
for(bucket = 0; bucket < SERVICE_TABLE_SIZE; bucket++) {
|
||||||
|
for(current = service_table[bucket % SERVICE_TABLE_SIZE]; current; current = current->next) {
|
||||||
|
if (wildtest(mask, current->servent->s_name)) {
|
||||||
|
|
||||||
|
if ((range_type & SCAN_TCP_PORT) && strcmp(current->servent->s_proto, "tcp") == 0) {
|
||||||
|
porttbl[ntohs(current->servent->s_port)] |= SCAN_TCP_PORT;
|
||||||
|
ports->tcp_count++;
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((range_type & SCAN_UDP_PORT) && strcmp(current->servent->s_proto, "udp") == 0) {
|
||||||
|
porttbl[ntohs(current->servent->s_port)] |= SCAN_UDP_PORT;
|
||||||
|
ports->udp_count++;
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct servent *nmap_getservbyport(int port, const char *proto) {
|
struct servent *nmap_getservbyport(int port, const char *proto) {
|
||||||
struct service_list *current;
|
struct service_list *current;
|
||||||
|
|
||||||
@@ -222,7 +304,7 @@ struct servent *nmap_getservbyport(int port, const char *proto) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for(current = service_table[port % SERVICE_TABLE_SIZE];
|
for(current = service_table[port % SERVICE_TABLE_SIZE];
|
||||||
current; current = current->next) {
|
current; current = current->next) {
|
||||||
if (((u16) port == (u16) current->servent->s_port) &&
|
if (((u16) port == (u16) current->servent->s_port) &&
|
||||||
strcmp(proto, current->servent->s_proto) == 0)
|
strcmp(proto, current->servent->s_proto) == 0)
|
||||||
return current->servent;
|
return current->servent;
|
||||||
@@ -230,123 +312,152 @@ struct servent *nmap_getservbyport(int port, const char *proto) {
|
|||||||
|
|
||||||
/* Couldn't find it ... oh well. */
|
/* Couldn't find it ... oh well. */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Be default we do all ports 1-1024 as well as any higher ports
|
|
||||||
that are in the services file */
|
|
||||||
struct scan_lists *getdefaultports(int tcpscan, int udpscan) {
|
static int port_compare(const void *a, const void *b) {
|
||||||
int tcpportindex = 0;
|
unsigned short ua = *((unsigned short *) a), ub = *((unsigned short *) b);
|
||||||
int udpportindex = 0;
|
if (ua > ub) return 1;
|
||||||
struct scan_lists *ports;
|
else return -1;
|
||||||
u8 *usedports;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// is_port_member() returns true if serv is an element of ptsdata.
|
||||||
|
// This could be implemented MUCH more efficiently but it should only be
|
||||||
|
// called when you use a non-default top-ports or port-ratio value TOGETHER WITH
|
||||||
|
// a -p portlist.
|
||||||
|
|
||||||
|
static int is_port_member(struct scan_lists *ptsdata, struct service_list *serv) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (serv->servent->s_proto[0] == 't') {
|
||||||
|
for (i=0; i<ptsdata->tcp_count; i++)
|
||||||
|
if (ntohs(serv->servent->s_port) == ptsdata->tcp_ports[i]) return 1;
|
||||||
|
} else {
|
||||||
|
for (i=0; i<ptsdata->udp_count; i++)
|
||||||
|
if (ntohs(serv->servent->s_port) == ptsdata->udp_ports[i]) return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// gettoppts() returns a scan_list with the most common ports scanned by
|
||||||
|
// Nmap according to the ratios specified in the nmap-services file.
|
||||||
|
//
|
||||||
|
// If level is below 1.0 then we treat it as a minimum ratio and we
|
||||||
|
// add all ports with ratios above level.
|
||||||
|
//
|
||||||
|
// If level is 1 or above, we treat it as a "top ports" directive
|
||||||
|
// and return the N highest ratio ports (where N==level).
|
||||||
|
//
|
||||||
|
// This function doesn't support IP protocol scan so only call this
|
||||||
|
// function if o.TCPScan() || o.UDPScan()
|
||||||
|
|
||||||
|
struct scan_lists *gettoppts(double level, char *portlist) {
|
||||||
|
int ti=0, ui=0;
|
||||||
|
struct scan_lists *sl, *ptsdata=NULL;
|
||||||
struct service_list *current;
|
struct service_list *current;
|
||||||
int bucket;
|
|
||||||
int tcpportsneeded = 0;
|
|
||||||
int udpportsneeded = 0;
|
|
||||||
|
|
||||||
if (nmap_services_init() == -1)
|
if (!services_initialized && nmap_services_init() == -1)
|
||||||
fatal("Getfastports: Couldn't get port numbers");
|
fatal("gettoppts: Couldn't get port numbers");
|
||||||
|
|
||||||
usedports = (u8 *) safe_zalloc(sizeof(*usedports) * 65536);
|
|
||||||
|
|
||||||
for(bucket = 1; bucket < 1025; bucket++) {
|
if (ratio_format == 0) {
|
||||||
if (tcpscan) {
|
if (level != -1)
|
||||||
usedports[bucket] |= SCAN_TCP_PORT;
|
fatal("Unable to use --top-ports or --port-ratio with an old style (no-ratio) services file");
|
||||||
tcpportsneeded++;
|
|
||||||
}
|
if (portlist)
|
||||||
if (udpscan) {
|
return getpts(portlist);
|
||||||
usedports[bucket] |= SCAN_UDP_PORT;
|
else if (o.fastscan)
|
||||||
udpportsneeded++;
|
return getpts("[-]");
|
||||||
}
|
else
|
||||||
|
return getpts("1-1024,[1025-]");
|
||||||
}
|
}
|
||||||
|
|
||||||
for(bucket = 0; bucket < SERVICE_TABLE_SIZE; bucket++) {
|
// TOP PORT DEFAULTS
|
||||||
for(current = service_table[bucket % SERVICE_TABLE_SIZE];
|
if (level == -1) {
|
||||||
current; current = current->next) {
|
if (portlist)
|
||||||
if (tcpscan &&
|
return getpts(portlist);
|
||||||
! (usedports[ntohs(current->servent->s_port)] & SCAN_TCP_PORT) &&
|
|
||||||
! strncmp(current->servent->s_proto, "tcp", 3)) {
|
if (o.fastscan) level = 100;
|
||||||
usedports[ntohs(current->servent->s_port)] |= SCAN_TCP_PORT;
|
else level = 0.01;
|
||||||
tcpportsneeded++;
|
}
|
||||||
}
|
|
||||||
if (udpscan &&
|
sl = (struct scan_lists *) safe_zalloc(sizeof(struct scan_lists));
|
||||||
! (usedports[ntohs(current->servent->s_port)] & SCAN_UDP_PORT) &&
|
if (portlist) ptsdata = getpts(portlist);
|
||||||
!strncmp(current->servent->s_proto, "udp", 3)) {
|
|
||||||
usedports[ntohs(current->servent->s_port)] |= SCAN_UDP_PORT;
|
if (level < 1) {
|
||||||
udpportsneeded++;
|
for (current=sorted_services; current; current=current->next) {
|
||||||
}
|
if (ptsdata && !is_port_member(ptsdata, current)) continue;
|
||||||
|
|
||||||
|
if (current->ratio >= level) {
|
||||||
|
if (o.TCPScan() && current->servent->s_proto[0] == 't') sl->tcp_count++;
|
||||||
|
else if (o.UDPScan() && current->servent->s_proto[0] == 'u') sl->udp_count++;
|
||||||
|
} else break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ports = (struct scan_lists *) safe_zalloc(sizeof(struct scan_lists));
|
if (sl->tcp_count)
|
||||||
if (tcpscan)
|
sl->tcp_ports = (unsigned short *)safe_zalloc(sl->tcp_count * sizeof(unsigned short));
|
||||||
ports->tcp_ports = (unsigned short *) safe_zalloc((tcpportsneeded) * sizeof(unsigned short));
|
|
||||||
if (udpscan)
|
|
||||||
ports->udp_ports = (unsigned short *) safe_zalloc((udpportsneeded) * sizeof(unsigned short));
|
|
||||||
ports->tcp_count= tcpportsneeded;
|
|
||||||
ports->udp_count= udpportsneeded;
|
|
||||||
|
|
||||||
for(bucket = 0; bucket < 65536; bucket++) {
|
if (sl->udp_count)
|
||||||
if (usedports[bucket] & SCAN_TCP_PORT)
|
sl->udp_ports = (unsigned short *)safe_zalloc(sl->udp_count * sizeof(unsigned short));
|
||||||
ports->tcp_ports[tcpportindex++] = bucket;
|
|
||||||
if (usedports[bucket] & SCAN_UDP_PORT)
|
|
||||||
ports->udp_ports[udpportindex++] = bucket;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(usedports);
|
sl->prots = NULL;
|
||||||
return ports;
|
|
||||||
|
for (current=sorted_services;current;current=current->next) {
|
||||||
|
if (ptsdata && !is_port_member(ptsdata, current)) continue;
|
||||||
|
|
||||||
|
if (current->ratio >= level) {
|
||||||
|
if (o.TCPScan() && current->servent->s_proto[0] == 't')
|
||||||
|
sl->tcp_ports[ti++] = ntohs(current->servent->s_port);
|
||||||
|
else if (o.UDPScan() && current->servent->s_proto[0] == 'u')
|
||||||
|
sl->udp_ports[ui++] = ntohs(current->servent->s_port);
|
||||||
|
} else break;
|
||||||
|
}
|
||||||
|
} else if (level >= 1) {
|
||||||
|
if (level > 65536)
|
||||||
|
fatal("Level argument to gettoppts (%g) is too large", level);
|
||||||
|
|
||||||
|
if (o.TCPScan()) {
|
||||||
|
sl->tcp_count = MIN((int) level, numtcpports);
|
||||||
|
sl->tcp_ports = (unsigned short *)safe_zalloc(sl->tcp_count * sizeof(unsigned short));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.UDPScan()) {
|
||||||
|
sl->udp_count = MIN((int) level, numudpports);
|
||||||
|
sl->udp_ports = (unsigned short *)safe_zalloc(sl->udp_count * sizeof(unsigned short));
|
||||||
|
}
|
||||||
|
|
||||||
|
sl->prots = NULL;
|
||||||
|
|
||||||
|
for (current=sorted_services;current && (ti < sl->tcp_count || ui < sl->udp_count);current=current->next) {
|
||||||
|
if (ptsdata && !is_port_member(ptsdata, current)) continue;
|
||||||
|
|
||||||
|
if (o.TCPScan() && current->servent->s_proto[0] == 't' && ti < sl->tcp_count)
|
||||||
|
sl->tcp_ports[ti++] = ntohs(current->servent->s_port);
|
||||||
|
else if (o.UDPScan() && current->servent->s_proto[0] == 'u' && ui < sl->udp_count)
|
||||||
|
sl->udp_ports[ui++] = ntohs(current->servent->s_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ti < sl->tcp_count) sl->tcp_count = ti;
|
||||||
|
if (ui < sl->udp_count) sl->udp_count = ui;
|
||||||
|
} else
|
||||||
|
fatal("Argument to gettoppts (%g) should be a positive ratio below 1 or an integer of 1 or higher", level);
|
||||||
|
|
||||||
|
if (ptsdata) free_scan_lists(ptsdata);
|
||||||
|
|
||||||
|
if (sl->tcp_count > 1)
|
||||||
|
qsort(sl->tcp_ports, sl->tcp_count, sizeof(unsigned short), &port_compare);
|
||||||
|
|
||||||
|
if (sl->udp_count > 1)
|
||||||
|
qsort(sl->udp_ports, sl->udp_count, sizeof(unsigned short), &port_compare);
|
||||||
|
|
||||||
|
if (o.debugging && level < 1)
|
||||||
|
log_write(LOG_STDOUT, "PORTS: Using ports open on %g%% or more average hosts (TCP:%d, UDP:%d)\n", level*100, sl->tcp_count, sl->udp_count);
|
||||||
|
else if (o.debugging && level >= 1)
|
||||||
|
log_write(LOG_STDOUT, "PORTS: Using top %d ports found open (TCP:%d, UDP:%d)\n", (int) level, sl->tcp_count, sl->udp_count);
|
||||||
|
|
||||||
|
return sl;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct scan_lists *getfastports(int tcpscan, int udpscan) {
|
|
||||||
int tcpportindex = 0;
|
|
||||||
int udpportindex = 0;
|
|
||||||
struct scan_lists *ports;
|
|
||||||
u8 *usedports;
|
|
||||||
struct service_list *current;
|
|
||||||
int bucket;
|
|
||||||
int tcpportsneeded = 0;
|
|
||||||
int udpportsneeded = 0;
|
|
||||||
|
|
||||||
if (nmap_services_init() == -1)
|
|
||||||
fatal("Getfastports: Couldn't get port numbers");
|
|
||||||
|
|
||||||
usedports = (u8 *) safe_zalloc(sizeof(*usedports) * 65536);
|
|
||||||
|
|
||||||
for(bucket = 0; bucket < SERVICE_TABLE_SIZE; bucket++) {
|
|
||||||
for(current = service_table[bucket % SERVICE_TABLE_SIZE];
|
|
||||||
current; current = current->next) {
|
|
||||||
if (tcpscan &&
|
|
||||||
! (usedports[ntohs(current->servent->s_port)] & SCAN_TCP_PORT) &&
|
|
||||||
!strncmp(current->servent->s_proto, "tcp", 3)) {
|
|
||||||
usedports[ntohs(current->servent->s_port)] |= SCAN_TCP_PORT;
|
|
||||||
tcpportsneeded++;
|
|
||||||
}
|
|
||||||
if (udpscan &&
|
|
||||||
! (usedports[ntohs(current->servent->s_port)] & SCAN_UDP_PORT) &&
|
|
||||||
!strncmp(current->servent->s_proto, "udp", 3)) {
|
|
||||||
usedports[ntohs(current->servent->s_port)] |= SCAN_UDP_PORT;
|
|
||||||
udpportsneeded++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ports = (struct scan_lists *) safe_zalloc(sizeof(struct scan_lists));
|
|
||||||
if (tcpscan)
|
|
||||||
ports->tcp_ports = (unsigned short *) safe_zalloc((tcpportsneeded) * sizeof(unsigned short));
|
|
||||||
if (udpscan)
|
|
||||||
ports->udp_ports = (unsigned short *) safe_zalloc((udpportsneeded) * sizeof(unsigned short));
|
|
||||||
ports->tcp_count= tcpportsneeded;
|
|
||||||
ports->udp_count= udpportsneeded;
|
|
||||||
|
|
||||||
for(bucket = 0; bucket < 65536; bucket++) {
|
|
||||||
if (usedports[bucket] & SCAN_TCP_PORT)
|
|
||||||
ports->tcp_ports[tcpportindex++] = bucket;
|
|
||||||
if (usedports[bucket] & SCAN_UDP_PORT)
|
|
||||||
ports->udp_ports[udpportindex++] = bucket;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(usedports);
|
|
||||||
return ports;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -125,11 +125,12 @@
|
|||||||
|
|
||||||
struct service_list {
|
struct service_list {
|
||||||
struct servent *servent;
|
struct servent *servent;
|
||||||
|
double ratio;
|
||||||
struct service_list *next;
|
struct service_list *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int addportsfromservmask(char *mask, u8 *porttbl, struct scan_lists *ports, int range_type);
|
||||||
struct servent *nmap_getservbyport(int port, const char *proto);
|
struct servent *nmap_getservbyport(int port, const char *proto);
|
||||||
struct scan_lists *getfastports(int tcpscan, int udpscan);
|
struct scan_lists *gettoppts(double level, char *portlist);
|
||||||
struct scan_lists *getdefaultports(int tcpscan, int udpscan);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
43
utils.cc
43
utils.cc
@@ -105,6 +105,49 @@
|
|||||||
|
|
||||||
extern NmapOps o;
|
extern NmapOps o;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Test a wildcard mask against a test string. Wildcard mask
|
||||||
|
* can include '*' and '?' which work the same as they do
|
||||||
|
* in /bin/sh (except it's case insensitive)
|
||||||
|
* Return val of 1 means it DID match. 0 means it DIDN'T
|
||||||
|
* - Doug Hoyte, 2005
|
||||||
|
*/
|
||||||
|
|
||||||
|
int wildtest(char *wild, char *test) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while(*wild != '\0' || *test != '\0') {
|
||||||
|
if (*wild == '*') {
|
||||||
|
|
||||||
|
/* --- Deal with multiple asterisks. --- */
|
||||||
|
while (wild[1] == '*') wild++;
|
||||||
|
|
||||||
|
/* --- Deal with terminating asterisks. --- */
|
||||||
|
if (wild[1] == '\0') return 1;
|
||||||
|
|
||||||
|
for(i=0; test[i]!='\0'; i++)
|
||||||
|
if ((wild[1] == test[i] || wild[1] == '?')
|
||||||
|
&& wildtest(wild+1, test+i) == 1) return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- '?' can't match '\0'. --- */
|
||||||
|
if (*wild == '?' && *test == '\0') return 0;
|
||||||
|
|
||||||
|
if (*wild != '?' && tolower((int)*wild) != tolower((int)*test)) return 0;
|
||||||
|
wild++; test++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tolower((int)*wild) == tolower((int)*test)) return 1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Hex dump */
|
/* Hex dump */
|
||||||
void hdump(unsigned char *packet, unsigned int len) {
|
void hdump(unsigned char *packet, unsigned int len) {
|
||||||
unsigned int i=0, j=0;
|
unsigned int i=0, j=0;
|
||||||
|
|||||||
2
utils.h
2
utils.h
@@ -189,6 +189,8 @@ template<class T> T box(T bmin, T bmax, T bnum) {
|
|||||||
return bnum;
|
return bnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wildtest(char *wild, char *test);
|
||||||
|
|
||||||
void hdump(unsigned char *packet, unsigned int len);
|
void hdump(unsigned char *packet, unsigned int len);
|
||||||
void lamont_hdump(char *cp, unsigned int length);
|
void lamont_hdump(char *cp, unsigned int length);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user