一、环境
nmap-7.80
二、扫描前准备
2.1 初始化默认值
NmapOps o;//全局类对象 //构造函数 NmapOps::NmapOps() { datadir = NULL; xsl_stylesheet = NULL; Initialize(); } //构造函数中调用 Initialize 函数,进行类对象成员初始化,设置默认值 void NmapOps::Initialize() { ... isr00t //是否为root权限运行 randomize_ports = true; //随机端口 fastscan = false; //禁止快速扫描 ... osscan = false; //禁止扫描操作系统 servicescan = false; ... pingtype = PINGTYPE_UNKNOWN; ... /*禁用各种扫描*/ listscan = ackscan = bouncescan = connectscan = 0; nullscan = xmasscan = fragscan = synscan = windowscan = 0; maimonscan = idlescan = finscan = udpscan = ipprotscan = 0; noportscan = noresolve = false; sctpinitscan = 0; sctpcookieechoscan = 0; append_output = false; ... implicitARPPing = true; ... topportlevel = -1; }
2.2 解析用户参数,设置相应值
// -s(X) 设置各种扫描方式 case 's': ... p = optarg; while (*p) { switch (*p) { ... case 'n': o.noportscan = true; break; case 'A': o.ackscan = true; break; ... case 'F': o.finscan = 1; break; case 'L': o.listscan = true; o.noportscan = true; o.pingtype |= PINGTYPE_NONE; break; case 'M': o.maimonscan = 1; break; case 'N': o.nullscan = 1; break; case 'O': o.ipprotscan = 1; break; /* Alias for -sV since March 2011. */ case 'R': o.servicescan = true; delayed_options.warn_deprecated("sR", "sV"); error("WARNING: -sR is now an alias for -sV and activates version detection as well as RPC scan."); break; case 'S': o.synscan = 1; break; case 'T': o.connectscan = 1; break; case 'U': o.udpscan++; break; case 'V': o.servicescan = true; break; ... } } //指定端口 case 'p': ... o.portlist = strdup(optarg); break; //指定ping端口,用于主机发现 case 'P': ... else if (*optarg == 'S') { ... o.pingtype |= (PINGTYPE_TCP | PINGTYPE_TCP_USE_SYN); if (*(optarg + 1) != '\0') { getpts_simple(optarg + 1, SCAN_TCP_PORT, &ports.syn_ping_ports, &ports.syn_ping_count); ... } else { getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &ports.syn_ping_ports, &ports.syn_ping_count); ... } } else if (*optarg == 'T' || *optarg == 'A') { ... o.pingtype |= (PINGTYPE_TCP | PINGTYPE_TCP_USE_ACK); if (*(optarg + 1) != '\0') { getpts_simple(optarg + 1, SCAN_TCP_PORT, &ports.ack_ping_ports, &ports.ack_ping_count); ... } else { getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &ports.ack_ping_ports, &ports.ack_ping_count); ... } } else if (*optarg == 'U') { ... o.pingtype |= (PINGTYPE_UDP); if (*(optarg + 1) != '\0') { getpts_simple(optarg + 1, SCAN_UDP_PORT, &ports.udp_ping_ports, &ports.udp_ping_count); ... } else { getpts_simple(DEFAULT_UDP_PROBE_PORT_SPEC, SCAN_UDP_PORT, &ports.udp_ping_ports, &ports.udp_ping_count); .. } } else if (*optarg == 'Y') { ... o.pingtype |= (PINGTYPE_SCTP_INIT); if (*(optarg + 1) != '\0') { getpts_simple(optarg + 1, SCAN_SCTP_PORT, &ports.sctp_ping_ports, &ports.sctp_ping_count); ... } else { getpts_simple(DEFAULT_SCTP_PROBE_PORT_SPEC, SCAN_SCTP_PORT, &ports.sctp_ping_ports, &ports.sctp_ping_count); ... } } else if (*optarg == 'B') { ... o.pingtype = DEFAULT_IPV4_PING_TYPES; if (*(optarg + 1) != '\0') { getpts_simple(optarg + 1, SCAN_TCP_PORT, &ports.ack_ping_ports, &ports.ack_ping_count); ... } else { getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &ports.ack_ping_ports, &ports.ack_ping_count); ... } } else if (*optarg == 'O') { ... o.pingtype |= PINGTYPE_PROTO; if (*(optarg + 1) != '\0') { getpts_simple(optarg + 1, SCAN_PROTOCOLS, &ports.proto_ping_ports, &ports.proto_ping_count); ... } else { getpts_simple(DEFAULT_PROTO_PROBE_PORT_SPEC, SCAN_PROTOCOLS, &ports.proto_ping_ports, &ports.proto_ping_count); ... } } else { fatal("Illegal Argument to -P, use -Pn, -PE, -PS, -PA, -PP, -PM, -PU, -PY, or -PO"); } break;
2.3 端口处理
(1)排除掉不扫描端口
removepts(o.exclude_portlist, &ports);
(2) 初始化 PortList 类
if (o.ipprotscan) PortList::initializePortMap(IPPROTO_IP, ports.prots, ports.prot_count); if (o.TCPScan()) PortList::initializePortMap(IPPROTO_TCP, ports.tcp_ports, ports.tcp_count); if (o.UDPScan()) PortList::initializePortMap(IPPROTO_UDP, ports.udp_ports, ports.udp_count); if (o.SCTPScan()) PortList::initializePortMap(IPPROTO_SCTP, ports.sctp_ports, ports.sctp_count);
(3) 将端口随机化
case 'r': o.randomize_ports = false; //默认为true //如果没有设置-r 选项, 则将端口随机化 if (ports.tcp_count) { shortfry(ports.tcp_ports, ports.tcp_count); // 将众所周知的端口移动到最前面 random_port_cheat(ports.tcp_ports, ports.tcp_count); } if (ports.udp_count) shortfry(ports.udp_ports, ports.udp_count); if (ports.sctp_count) shortfry(ports.sctp_ports, ports.sctp_count); if (ports.prot_count) shortfry(ports.prots, ports.prot_count);