摘要:最近花了几天时间,读了nmap的手册之后总结下面的全部经验,有点意思,貌似只要使用nmap进行探测,除了某些特定选项能避免之外,其他总能被反查。又臭又长,但是能学到不少东西。

建议

建议nmap最好以root用户运行,这样会扫踩很多坑,有的选项不使用root权限无法使用。
在UNIX机器上,通常只有特权用户 root 能够发送和接收 原始的TCP报文。因此作为一个变通的方法,对于非特权用户, Nmap会为每个目标主机进行系统调用connect() 也就是正常的TCP三次握手,发送一个带有SYN标志位的TCP报文来尝试建立连接。如果connect()迅速返回成功或者一个ECONNREFUSED 失败,下面的TCP堆栈一定已经收到了一个SYN/ACK或者RST。

目标选择

nmap命令行里不属于nmap选项或者nmap选项的参数的部分都会被当成目标扫描。当使用域名时,nmap会调用DNS解析目标的ip地址。即使只使用ipv4地址时,也会去根据dns解析域名,禁用DNS解析时使用-n。

命令行指定ipv4

nmap www.keepnight.com
nmap 192.168.10.40/0 # 最小值为/0,表示扫描整个互联网
nmap 192.168.10.40/32 # 最大值为/32,表示192.168.10.40这个特定地址
nmap 192.168.3-5,7.1 # 扫描四个地址192.168.3.1、192.168.4.1、192.168.5.1和192.168.7.1
nmap 192.168.3.- # 扫描192.168.3.0到192.168.3.255的256个地址
nmap  0-255.0-255.13.37 # 将对以13.37结尾的所有IP地址执行Internet范围内的扫描

命令行指定ipv6

nmap fe80::a8bb:ccff:fedd:eeff/128 # 扫描fe80::a8bb:ccff:fedd:eeff这个地址
nmap fe80::a8bb:ccff:fedd:eeff%eth0 
# 貌似多网卡的情况下,使用fe80这个link-local地址需要,表示流量要从这个网卡出去
# windows下在cmd中使用netsh interface ipv6 show interface,把eth0换成对应Idx就行
# 没有ipv6地址未测试

精细控制地址

1.txt中的内容(一行代表一个地址范围)

192.168.1.100
192.168.1.101

2.txt中的内容(一行代表一个地址范围)

192.168.1.101
  • -iL # 从文件中读取目标

    nmap -T4 -iL 1.txt
  • -iR # 随机选择目标

    nmap -PP -sn -iL 1.txt -iR 1
    # -iR 1 随机生成一个ip然后扫描,-iR 0 随机生成无限个ip然后扫描。此时-iL没用不会去读取1.txt中的目标,不生效。
  • --exclude # 排除某些目标

    nmap -PP -sn -iL 1.txt --exclude 192.168.1.101
    # 此时不会扫描192.168.1.101这个ip
  • --excludefile # 排除文件中的目标

    nmap -PP -sn -iL 1.txt --excludefile 2.txt
    # 此时不会去扫描2.txt中记录的ip。excludefile中可以用#当成注释符

主机发现

在UNIX机器上,通常只有特权用户 root 能够发送和接收 原始的TCP报文。因此作为一个变通的方法,对于非特权用户, Nmap会为每个目标主机进行系统调用connect() 也就是正常的TCP三次握手,发出一个带有SYN标志位的TCP报文来尝试建立连接。如果connect()迅速返回成功或者一个ECONNREFUSED 失败,下面的TCP堆栈一定已经收到了一个SYN/ACK或者RST。

如果不使用主机发现的选项默认会发送一个带有ACK标志位的TCP报文到80,发出一个带有SYN标志位的TCP报文去443,以及ICMP报文到目标地址。如果nmap不是以root用户运行就不能发送一个带有ACK标志位的TCP报文到80,只能调用connect来实现。如果使用了下面的选项则按照选项指定的实现。
关闭主机发现可以使用-P0或者-Pn。

-sL(列表扫描)

作用:根据ip地址解析域名或者根据域名解析ip地址并打印。不会有数据包发送到扫描主机,因此无法知道目标是否存活,经过测试例如下面图片中的 0 hosts up 貌似不太准,鸡肋功能。
例子:

nmap -sL 192.168.1.0-255 

主机扫描1.png

-sn/-sP(ping扫描)

作用:仅仅探测存活的主机。发送一个TCP的ACK报文到80,一个TCP的SYN报文去443,以及ICMP报文到目标地址,然后nmap结束运行。仅仅进行ping扫描 (主机发现),然后打印出对扫描做出响应的那些主机。 没有进一步的测试 (如端口扫描或者操作系统探测)。-sP和-sn功能一样,只不过-sP时老版本的,虽然-sP确实也能使用。
例子:

nmap -sP -T4 192.168.1.100 --max-retries=0
# --max-retries=0,如果丢包了,最大重发0次,即不进行重发

-Pn/-P0(无ping)

作用:该选项完全跳过Nmap发现阶段。 通常Nmap在进行高强度的扫描时用它确定正在运行的机器。 默认情况下,Nmap只对正在运行的主机进行高强度的探测如 端口扫描,版本探测,或者操作系统探测。用-P0禁止 主机发现会使Nmap对每一个指定的目标IP地址 进行所要求的扫描。所以如果在命令行指定一个B类目标地址空间(/16), 所有 65,536 个IP地址都会被扫描。 -P0的第二个字符是数字0而不是字母O。 和列表扫描一样,跳过正常的主机发现,但不是打印一个目标列表, 而是继续执行所要求的功能,就好像每个IP都是可用的,会降低nmap的运行速度。-P0和-Pn以及-PN功能一样,只不过-P0时老版本的,虽然-P0确实也能使用。

要跳过主机发现和端口扫描,同时仍然允许NSE运行,请同时使用这两个选项 -Pn -sn。

对于本地以太网上的计算机,将继续执行ARP扫描(除非指定 --disable-arp-ping 或--send-ip ),因为Nmap需要MAC地址来进一步扫描目标主机。

例子:

nmap -n -P0 -sS -p6379 --packet-trace 192.168.1.100
# -n跳过dns解析
# -P0不进行主机发现
# -sS进行syn扫描
# -p6379指定扫描端口为6379
# --packet-trace 打印出nmap发出的包

-PS[portlist] (TCP SYN Ping)

作用:发出一个带有SYN标志位的TCP报文到80端口。SYN表示请求向远程系统建立连接。正常情况下,目标端口将关闭,然后发送回RST(复位)数据包。如果端口恰好是开放的,则目标将执行TCP三向握手的第二步,通过响应SYN/ACK TCP数据包。然后,运行Nmap的计算机通过使用RST响应而不是发送ACK数据包来断开连接,中止TCP三次握手。RST数据包由运行Nmap的计算机的内核发送,以响应意外的SYN / ACK,而不是由Nmap本身发送。

Nmap不在乎端口是打开还是关闭。前面讨论的RST或SYN / ACK响应都告诉Nmap主机可用且响应。因为-PS的作用就是探测主机是否可用。

在Unix机器上,通常只有特权用户 root 能够发送和接收原始TCP数据包。因此作为一个变通的方法,对于非特权用户, Nmap会为每个目标主机进行系统调用connect() 也就是正常的TCP三次握手,发送一个SYN 报文来尝试建立连接。如果connect以快速成功或ECONNREFUSED失败返回,则基础TCP堆栈必须已收到SYN / ACK或RST,并且主机被标记为可用。如果连接尝试一直挂起直到达到超时,主机将标记为关闭。

例子:

nmap -PS -sn -n --packet-trace --max-retries=0 47.3.1.1
nmap -PS443,3306 -sn -n --packet-trace --max-retries=0 47.3.1.1
# -sn忽略端口扫描
# -PS默认目的端口为80,可以通过编译时对nmap.h文件中的DEFAULT-TCP-PROBE-PORT值进行配置
# 扫描目的端口也可以使用 -PS443,3306 进行指定

主机扫描2.png

-PA[portlist] (TCP ACK Ping)

-PA和-PS用法一样,只不过发出一个带有ACK标志位的TCP报文到80端口。在TCP数据传输中,接收方通过发送带有ACK标志位的TCP报文向发送方确认收到数据。nmap模仿接收方,扫描目标是发送方, 所以扫描目标应该总是回应一个RST报文,因为nmap和扫描目标之间没有建立过TCP链接。如果什么都不返回就说明扫描目标是关闭状态。

-PA选项使用和-PS探测相同的默认端口(80),也可以 用相同的格式指定目标端口列表。如果非特权用户尝试该功能, 或者指定的是IPv6目标,前面说过的connect()方法将被使用。 这个方法并不完美,因为它实际上发送的是SYN报文,而不是ACK报文。

提供SYN和ACK两种ping探测的原因是使通过防火墙的机会尽可能大。 许多管理员会配置他们的路由器或者其它简单的防火墙来封锁SYN报文,除非 连接目标是那些公开的服务器像公司网站或者邮件服务器。 这可以阻止其它进入组织的连接,同时也允许用户访问互联网。 这种无状态的方法几乎不占用防火墙/路由器的资源,因而被硬件和软件过滤器 广泛支持。Linux Netfilter/iptables 防火墙软件提供方便的 --syn选项来实现这种无状态的方法。 当这样的无状态防火墙规则存在时,发送到关闭目标端口的SYN ping探测 (-PS) 很可能被封锁。这种情况下,ACK探测特别有用,因为它正好利用了这样的规则。

另外一种常用的防火墙用有状态的规则来封锁非预期的报文。 这一特性已开始只存在于高端防火墙,但是这些年类它越来越普遍了。 Linux Netfilter/iptables 通过 --state选项支持这一特性,它根据连接状态把报文 进行分类。SYN探测更有可能用于这样的系统,由于没头没脑的ACK报文 通常会被识别成伪造的而丢弃。解决这个两难的方法是通过即指定 -PS又指定-PA来即发送SYN又发送ACK。

例子:

nmap -PA443,3306 -sn -n --packet-trace --max-retries=0 47.3.1.1
nmap -PA443,3306 -sn -n --packet-trace --max-retries=0 47.3.1.1
nmap -PA -PS -sn -n --packet-trace --max-retries=0 47.3.1.1

-PU[portlist] (UDP Ping)

还有一个主机发现的选项是UDP ping,它发送一个空的(除非指定了--data-length)UDP报文到给定的端口。端口列表的格式和前面讨论过的-PS和-PA选项还是一样。 如果不指定端口,默认是40125。该默认值可以通过在编译时改变nmap.h文件中的 DEFAULT-UDP-PROBE-PORT值进行配置。默认使用这样一个奇怪的端口是因为对开放端口 进行这种扫描一般都不受欢迎。

如果目标机器的端口是关闭的,UDP探测应该马上得到一个ICMP的Port unreachable的回应报文。 这对于Nmap意味着该机器正在运行。 许多其它类型的ICMP错误,像主机/网络无法到达或者TTL超时或者没有回应或者被防火墙过滤 都表示关闭的主机。如果到达一个开放的端口,大部分服务仅仅忽略这个 空报文而不做任何回应。这就是为什么默认探测端口是31338这样一个 极不可能被使用的端口。少数服务如chargen会响应一个空的UDP报文, 从而向Nmap表明该机器正在运行。

该扫描类型的主要优势是它可以穿越只过滤TCP的防火墙和过滤器。 例如。我曾经有过一个Linksys BEFW11S4无线宽带路由器。默认情况下, 该设备对外的网卡过滤所有TCP端口,但UDP探测仍然会引发一个端口不可到达 的消息,从而暴露了它自己。

例子:

nmap -PU -sn -n --packet-trace --max-retries=0 150.1.1.1
nmap -PU80,3306 -sn -n --packet-trace --max-retries=0 150.1.1.1

-PY[port list] (SCTP INIT Ping)

此选项发送包含最小INIT块的SCTP数据包。默认目标端口为80(可以通过在编译时修改在nmap.h在DEFAULT_SCTP_PROBE_PORT_SPEC的值改变)。可以将备用端口指定为参数。-p除了S:不允许的端口类型说明符外, 该语法与其他语法相同 。示例是 -PY22和 -PY22,80,179,5060。请注意,-PY和端口列表之间不能有空格。如果指定了多个端口,则将并行发送。

INIT块向远程系统建议您正在尝试建立关联。通常,目标端口将关闭,并且ABORT块将被发回。如果端口恰好是开放的,则目标将采取SCTP四次握手的第二步 通过响应一个INIT-ACK块。如果运行Nmap的计算机具有正常的SCTP堆栈,则它将通过使用ABORT块而不是发送COOKIE-ECHO块来进行响应来断开新生的关联,这将是四次握手的下一步。ABORT数据包是由运行Nmap的计算机的内核发送的,以响应意外的INIT-ACK,而不是由Nmap本身发送的。

Nmap不在乎端口是打开还是关闭。前面讨论的ABORT响应或INIT-ACK响应都告诉Nmap主机可用并且响应。

在Unix机器上,只有特权用户 root 通常能够发送和接收原始SCTP数据包。 当前,非特权用户无法使用SCTP INIT Pings。

nmap -PY80,3306 -sn -n --packet-trace --max-retries=0 150.1.1.1
# 150.1.1.1主机是活的
# 扫描结果
Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scan

-PE; -PP; -PM (ICMP Ping Types)

-PE:发送ICMP请求报文
-PP:发送ICMP时间戳请求报文
-PM:发送ICMP地址掩码请求报文,实测ubuntu 18.04不会回复这个请求。

除了前面讨论的这些不常见的TCP和UDP主机发现类型, Nmap也能发送常见的ICMP请求报文。Nmap发送一个ICMP type 8 (ICMP请求报文)报文到目标IP地址, 期待从运行的主机得到一个type 0 (ICMP应答)报文。 对于网络探索者而言,不幸的是,许多主机和 防火墙现在封锁这些报文,而不是按期望的那样响应, 参见RFC 1122。因此,仅仅ICMP扫描对于互联网上的目标通常是不够的。 但对于系统管理员监视一个内部网络,它们可能是实际有效的途径。 。

虽然ICMP请求报文是标准的ICMP ping查询, Nmap并不止于此。ICMP标准 (RFC 792)还规范了时间戳请求,信息请求 request,和地址掩码请求,它们的代码分别是13,15和17。 虽然这些查询的表面目的是获取信息如地址掩码和当前时间, 它们也可以很容易地用于主机发现。 很简单,回应的系统就是在运行的系统。Nmap目前没有实现信息请求报文, 因为它们还没有被广泛支持。RFC 1122 坚持 “主机不应该实现这些消息”。 时间戳和地址掩码查询可以分别用-PP和-PM选项发送。 时间戳响应(ICMP代码14)或者地址掩码响应(代码18)表示主机在运行。 当管理员特别封锁了ICMP请求报文而忘了其它ICMP查询可能用于 相同目的时,这两个查询可能很有价值。

nmap -PE -sn 150.1.1.1 # ICMP回显请求

nmap -PP -sn 150.1.1.1 # ICMP时间戳请求

nmap -PM -sn 150.1.1.1 # ICMP地址掩码请求,ubuntu 18.04没有回复

-PO[protocol list] (IP协议Ping)

IP协议ping是较新的主机发现选项之一,它发送IP数据包,该IP数据包在其IP标头中设置了指定的协议号。协议列表格式和-PS和-PA一样。如果未指定协议,则默认为发送多个IP数据包用于ICMP(协议1),IGMP(协议2)和IP-in-IP(协议4)。默认协议可以在编译时通过更改配置nmap.h中的DEFAULT_PROTO_PROBE_PORT_SPEC值来实现。请注意,对于ICMP,IGMP,TCP(协议6),UDP(协议17)和SCTP(协议132),数据包会以适当的协议头发送,而其他协议在发送时除了IP头之外没有附加数据(除非使用 --data, --data-string或 --data-length 选项指定)。

nmap -PO1 -sn 150.1.1.1 # 发送ICMP回显请求,协议号为1 和-PE选项相同

nmap -PO2 -sn 150.1.1.1 # 发送IGMP,协议号为2

-PR (ARP Ping)

最常见的Nmap使用场景之一是扫描一个局域网。 在大部分局域网上,特别是那些使用基于 RFC1918私有地址范围的网络,在一个给定的时间绝大部分IP地址都是不使用的。 当Nmap试图发送一个原始IP报文如ICMP请求报文时, 操作系统必须确定对应于目标IP的硬件地址(ARP),这样它才能把以太帧送往正确的地址。 这一般比较慢而且会有些问题,因为操作系统设计者认为一般不会在短时间内 对没有运行的机器作几百万次的ARP请求。

当进行ARP扫描时,Nmap用它优化的算法管理ARP请求。 当它收到响应时, Nmap甚至不需要使用基于IP的ping报文,既然它已经知道该主机正在运行了。 这使得ARP扫描比基于IP的扫描更快更可靠。 所以默认情况下,如果Nmap发现目标主机就在它所在的局域网上,它会进行ARP扫描。 即使指定了不同的ping类型(如 -PI或者 -PS) ,Nmap也会对任何相同局域网上的目标机使用ARP。 如果您真的不想要ARP扫描,指定--disable-arp-ping或者--send-ip。

nmap -PR -sn -n --packet-trace --max-retries=0 104.194.247.168/24

--disable-arp-ping (No ARP or ND Ping)

即使使用其他主机发现选项(例如 -Pn或-PE ),Nmap通常也会对本地连接的以太网主机执行ARP或IPv6邻居发现(ND)发现-PE。要禁用此隐式行为,请使用该--disable-arp-ping 选项。

默认行为通常更快,但是此选项在使用代理ARP的网络上很有用,在该网络中,路由器以推测方式答复所有ARP请求,从而根据ARP扫描使每个目标都处于启动状态。ps:我也不知道arp代理是啥。

nmap -n -PE -sn --packet-trace --disable-arp-ping 104.194.247.168/30

--discovery-ignore-rst

在某些情况下,防火墙可能会欺骗TCP重置(RST)响应,以响应对未占用或不允许的地址的探测。由于Nmap通常认为RST答复可以证明目标已启动,因此可能会浪费时间扫描不存在的目标。使用--discovery-ignore-rst将会阻止Nmap在主机发现期间考虑这些答复。您可能需要选择其他主机发现选项,以确保在这种情况下不会错过目标。

--traceroute (Trace path to host)

使用来自扫描结果的信息在扫描后执行跟踪路由,以确定最有可能到达目标的端口和协议。它适用于除连接扫描(-sT)和空闲扫描(-sI)以外的所有扫描类型。所有迹线均使用Nmap的动态时序模型并并行执行。

Traceroute通过发送具有低TTL(生存时间)的数据包来工作,以尝试从扫描程序和目标主机之间的中间跃点中引出ICMP超时消息。标准traceroute实施以TTL为1开始,并递增TTL,直到到达目标主机为止。Nmap的跟踪路由以较高的TTL开始,然后递减TTL直到达到零。向后执行此操作可使Nmap使用巧妙的缓存算法来加快对多个主机的跟踪。平均而言,根据网络状况,Nmap每台主机少发送5-10个数据包。如果正在扫描单个子网(即192.168.0.0/24),则Nmap可能只需要向大多数主机发送两个数据包。

nmap -n -PE -sn --traceroute 150.1.1.1

-n (No DNS resolution)

告诉Nmap永远不要对找到的活动IP地址进行DNS解析。由于即使使用Nmap内置的并行DNS解析器,DNS也会变慢,因此此选项可以减少扫描时间。

nmap -n -PE -sn --packet-trace 150.1.1.1

-R (DNS resolution for all targets)

告诉Nmap 始终对目标IP地址执行反向DNS解析。通常,反向DNS仅针对响应型(在线)主机执行。

--resolve-all (Scan each resolved address)

如果主机名目标解析为多个地址,扫描所有地址。默认行为是仅扫描第一个解析的地址。默认扫描ipv4,使用-6的话使用ipv6?(ps:我没ipv6环境所以没法尝试)

--system-dns (Use system DNS resolver)

使用自己本地比如win10自带的dns解析器。

默认情况下,Nmap通过直接向自己电脑上配置的名称服务器发送查询,然后监听响应来反向解析IP地址。许多请求(通常是几十个)被并行执行以提高性能。指定这个选项来使用您的系统解析器(通过getnameinfo()一次解析一个IP),这比较慢,而且很少有用,除非您发现Nmap并行解析器的错误(如果您发现了,请告诉我们)。系统解析器总是用于前向查询(从主机名中获取IP地址)。

nmap -PE -sn --system-dns --packet-trace -v 150.1.1.1
# -v 打印详细信息
nmap -PE -sn --system-dns --packet-trace -v -v 150.1.1.1
# -v -v 打印更详细信息,最多只能使用两个-v -v

--dns-servers <server1>[,<server2>[,...]] (Servers to use for reverse DNS queries)

默认情况下,Nmap通过resolv.conf文件(Unix)或注册表(Win32)确定DNS服务器(用于rDNS解析)。或者,您可以使用此选项来指定备用服务器。如果使用,则不支持该选项--system-dns。使用多个DNS服务器通常更快,尤其是如果您为目标IP空间选择了权威服务器时。此选项还可以提高隐身性,因为您的请求几乎可以在Internet上的任何递归DNS服务器上被退回。

扫描专用网络时,此选项也很方便。有时只有少数名称服务器提供正确的rDNS信息,您甚至可能不知道它们在哪里。您可以在网络上扫描端口53(也许使用版本检测),然后尝试使用Nmap列表扫描(-sL)一次指定每个名称服务器,--dns-servers直到找到一个可用的名称服务器。

如果DNS响应超出UDP数据包的大小,则可能不支持该选项。在这种情况下,我们的DNS解析器将尽最大努力从截断的数据包中提取响应,如果失败,它将使用system resolver。同样,响应中包含CNAME也会使用system resolver。

nmap -PE -sn --packet-trace --dns-servers 8.8.8.8 150.1.1.1

端口扫描基础

nmap <target>可以扫描主机<target>上的1000个TCP端口。Nmap将端口分为六种状态:开放、关闭、过滤、未过滤、开放|过滤或关闭|过滤。

open (开放的)

应用程序正在该端口接收 TCP 连接或者 UDP 报文。

closed (关闭的)

关闭的端口对于 Nmap 也是可访问的 ( 它接受 Nmap 的探测报文并作出响应 ),但没有应用程序在其上监听。比如应用程序监听127.0.0.1时,用nmap扫描的时候自然就是closed。

filtered (被过滤的)

由于防火墙阻止探测报文到达端口,Nmap 无法确定该端口是否开放。

unfiltered (未被过滤的)

未被过滤状态意味着端口可访问,但 Nmap 不能确定它是开放还是关闭。

例如:当使用-sA扫描端口时,不管端口开不开放都会返回RST报文。Nmap把它们标记为 unfiltered(未被过滤的),意思是 ACK报文不能到达,但至于它们是open(开放的)或者 closed(关闭的) 无法确定。不响应的端口 或者发送特定的ICMP错误消息(类型3,代号1,2,3,9,10, 或者13)的端口,标记为 filtered(被过滤的)。

open|filtered (开放或者被过滤的)

当无法确定端口是开放还是被过滤的,Nmap 就把该端口划分成 这种状态。开放的端口不响应就是一个例子。

例如:当使用-sU扫描的时候,UDP扫描发送空的(没有数据)UDP报文到每个目标端口。 如果返回ICMP端口不可到达错误(类型3,代码3), 该端口是closed(关闭的)。 其它ICMP不可到达错误(类型3, 代码1,2,9,10,或者13)表明该端口是filtered(被过滤的)。 偶尔地,某服务会响应一个UDP报文,证明该端口是open(开放的)。 如果几次重试后还没有响应,该端口就被认为是 open|filtered(开放|被过滤的)。 这意味着该端口可能是开放的,也可能包过滤器正在封锁通信。 可以用版本扫描(-sV)帮助区分真正的开放端口和被过滤的端口。

closed|filtered (关闭或者被过滤的)

该状态用于 Nmap 不能确定端口是关闭的还是被过滤的。 它只可能出现在 IPID Idle 扫描中

关于nmap具体扫描哪些端口可以在 https://nmap.org/book/port-scanning.html#port-scanning-port-intro 中看

端口扫描技术

作为一个修车新手,我可能折腾几个小时来摸索怎样把基本工具(锤子,胶带,扳子等) 用于手头的任务。当我惨痛地失败,把我的老爷车拖到一个真正的技师那儿的时候 ,他总是在他的工具箱里翻来翻去,直到拽出一个完美的工具然后似乎不费吹灰之力搞定它。 端口扫描的艺术和这个类似。专家理解成打的扫描技术,选择最适合的一种 (或者组合)来完成给定的 任务。 另一方面,没有经验的用户和刚入门者总是用默认的SYN扫描解决每个问题。 既然Nmap是免费的,掌握端口扫描的唯一障碍就是知识。这当然是汽车世界所不能比的, 在那里,可能需要高超的技巧才能确定您需要一个压杆弹簧压缩机,接着您还得为它付数千美金。

大部分扫描类型只对特权用户可用。 这是因为他们发送接收原始报文,这在Unix系统需要root权限。 在Windows上推荐使用administrator账户,但是当WinPcap已经被加载到操作系统时, 非特权用户也可以正常使用Nmap。当Nmap在1997年发布时,需要root权限是一个严重的 局限,因为很多用户只有共享的shell账户。现在,世界变了,计算机便宜了,更多人拥有互联网连接 ,桌面UNIX系统 (包括Linux和MAC OS X)很普遍了。Windows版本的Nmap现在也有了,这使它可以运行在更多的桌面上。 由于所有这些原因,用户不再需要用有限的共享shell账户运行Nmap。 这是很幸运的,因为特权选项让Nmap强大得多也灵活得多。

虽然Nmap努力产生正确的结果,但请记住所有结果都是基于目标机器(或者它们前面的防火墙)返回的报文的。 。这些主机也许是不值得信任的,它们可能响应以迷惑或误导Nmap的报文。 更普遍的是非RFC兼容的主机以不正确的方式响应Nmap探测。FIN,Null和Xmas扫描 特别容易遇到这个问题。这些是特定扫描类型的问题,因此我们在个别扫描类型里讨论它们。

这一节讨论Nmap支持的大约十几种扫描技术。 一般一次只用一种方法, 除了UDP扫描(-sU)可能和任何一种TCP扫描类型结合使用。 友情提示一下,端口扫描类型的选项格式是-s<C>, 其中<C> 是个显眼的字符,通常是第一个字符。 一个例外是deprecated FTP bounce扫描(-b)。默认情况下,Nmap执行一个 SYN扫描,但是如果用户没有权限发送原始报文(在UNIX上需要root权限)或者如果指定的是IPv6目标,Nmap调用connect()。 本节列出的扫描中,非特权用户只能执行connect()和ftp bounce扫描。

-sS (TCP SYN扫描)

SYN扫描作为默认的也是最受欢迎的扫描选项,是有充分理由的。 它执行得很快,在一个没有入侵防火墙的快速网络上,每秒钟可以扫描数千个 端口。 SYN扫描相对来说不张扬,不易被注意到,因为它从来不完成TCP连接。 它也不像Fin/Null/Xmas,Maimon和Idle扫描依赖于特定平台,而可以应对任何兼容的 TCP协议栈。 它还可以明确可靠地区分open(开放的), closed(关闭的),和filtered(被过滤的) 状态

它常常被称为半开放扫描, 因为它不打开一个完全的TCP连接。它发送一个SYN报文, 就像您真的要打开一个连接,然后等待响应。 SYN/ACK表示端口在监听 (开放),而 RST (复位)表示没有监听者。如果数次重发后仍没响应, 该端口就被标记为被过滤。如果收到ICMP不可到达错误 (类型3,代码1,2,3,9,10,或者13),该端口也被标记为被过滤。如果收到一个SYN数据包(没有ACK标志)作为响应,则该端口也被认为是开放的。这可能是由于一种极为罕见的TCP功能(称为同时打开或拆分握手连接)(请参阅https://nmap.org/misc/split-handshake.pdf)。

nmap -n -P0 -sS -p6379 --packet-trace 192.168.1.100

-sT (TCP connect()扫描)

当SYN扫描不能用时,TCP Connect()扫描就是默认的TCP扫描。 当用户没有权限发送原始报文或者扫描IPv6网络时,就是这种情况。 Nmap不会像大多数其他扫描类型那样写入原始数据包,而是通过发出connect系统调用来要求底层操作系统与目标计算机和端口建立连接。 这个高层系统调用通常是系统用来和Web浏览器,P2P客户端以及大多数其它网络应用程序建立连接。它是Berkeley Sockets API编程接口的一部分。Nmap用 该API获得每个连接尝试的状态信息,而不是读取响应的原始报文。

当SYN扫描可用时,它通常是更好的选择。因为Nmap对高层的 connect()调用比对原始报文控制更少, 所以前者效率较低。 该系统调用完全连接到开放的目标端口而不是像SYN扫描进行 半开放的复位。这不仅花更长时间,需要更多报文得到同样信息,目标机也更可能 记录下连接。IDS(入侵检测系统)可以捕获两者,但大部分机器没有这样的警报系统。 当Nmap连接,然后不发送数据又关闭连接, 许多普通UNIX系统上的服务会在syslog留下记录,有时候是一条加密的错误消息。 此时,有些真正可怜的服务会崩溃,虽然这不常发生。如果管理员在日志里看到来自同一系统的 一堆连接尝试,她应该知道她的系统被扫描了。

nmap -n -P0 -sT -p80 --packet-trace 150.1.1.1

-sU (UDP扫描)

虽然互联网上很多流行的服务运行在TCP 协议上,UDP服务也不少。 DNS,SNMP,和DHCP (注册的端口是53,161/162,和67/68)是最常见的三个。 因为UDP扫描一般较慢,比TCP更困难,一些安全审核人员忽略这些端口。 这是一个错误,因为可探测的UDP服务相当普遍,攻击者当然不会忽略整个协议。 所幸,Nmap可以帮助记录并报告UDP端口。

UDP扫描用-sU选项激活。它可以和TCP扫描如 SYN扫描 (-sS)结合使用来同时检查两种协议。

UDP扫描发送空的(没有数据)UDP报头到每个目标端口。 如果返回ICMP端口不可到达错误(类型3,代码3), 该端口是closed(关闭的)。 其它ICMP不可到达错误(类型3, 代码1,2,9,10,或者13)表明该端口是filtered(被过滤的)。 偶尔地,某服务会响应一个UDP报文,证明该端口是open(开放的)。 如果几次重试后还没有响应,该端口就被认为是 open|filtered(开放|被过滤的)。 这意味着该端口可能是开放的,也可能包过滤器正在封锁通信。 可以用版本扫描(-sV)帮助区分真正的开放端口和被过滤的端口。

UDP扫描的巨大挑战是怎样使它更快速。 开放的和被过滤的端口很少响应,让Nmap超时然后再探测,以防探测帧或者 响应丢失。关闭的端口常常是更大的问题。 它们一般发回一个ICMP端口无法到达错误。但是不像关闭的TCP端口响应SYN或者Connect 扫描所发送的RST报文,许多主机在默认情况下限制ICMP端口不可到达消息。 Linux和Solaris对此特别严格。例如, Linux 2.4.20内核限制一秒钟只发送一条目标不可到达消息 (见net/ipv4/icmp。c)。

Nmap探测速率限制并相应地减慢来避免用那些目标机会丢弃的无用报文来阻塞 网络。不幸的是,Linux式的一秒钟一个报文的限制使65,536个端口的扫描要花 18小时以上。加速UDP扫描的方法包括并发扫描更多的主机,先只对主要端口进行快速 扫描,从防火墙后面扫描,使用--host-timeout跳过慢速的主机。

nmap -n -P0 -sU -p80 --max-retries=0 --packet-trace -v 150.1.1.1

-sY (SCTP INIT扫描)

SCTP 是TCP和UDP协议的一个相对较新的替代方案,它结合了TCP和UDP的大多数特征,还增加了新功能,例如多宿主和多流。它主要用于与SS7 / SIGTRAN相关的服务,但也有可能用于其他应用程序。SCTP INIT扫描与TCP SYN扫描的SCTP等效。它可以快速执行,在不受限制性防火墙阻碍的快速网络上每秒扫描数千个端口。像SYN扫描一样,INIT扫描相对不引人注目且隐秘,因为它从未完成SCTP关联。它还允许之间的明确,可靠的分化open, closed和filtered 状态。

此技术通常称为半开扫描,因为您没有打开完整的SCTP关联。您发送一个INIT块,就好像您要打开一个真实的关联,然后等待响应一样。INIT-ACK块表示端口正在监听(打开),而ABORT块表示未监听。如果在几次重传后仍未收到响应,则将该端口标记为已过滤。如果收到ICMP无法访问的错误(类型3,代码0、1、2、3、9、10或13),该端口也将标记为已过滤。

nmap -n -P0 -sY -p80 --max-retries=0 --packet-trace -v 150.1.1.1
# 全是filtered状态,估计是协议不支持,并且好多防火墙只有放开TCP或者UDP选项。
# 150.1.1.1的80端口明明是开放的

-sN; -sF; -sX (TCP Null,FIN,and Xmas扫描)

这三种扫描类型 (甚至用下一节描述的 --scanflags 选项的更多类型) 在TCP RFC 中发掘了一个微妙的方法来区分open(开放的)和 closed(关闭的)端口。第65页说“如果 [目标]端口状态是关闭的.... 进入的不含RST的报文导致一个RST响应。” 接下来的一页 讨论不设置SYN,RST,或者ACK位的报文发送到开放端口: “理论上,这不应该发生,如果您确实收到了,丢弃该报文,返回。 ”

如果扫描系统遵循该RFC,当端口关闭时,任何不包含SYN,RST,或者ACK位的报文会导致 一个RST返回,而当端口开放时,应该没有任何响应。只要不包含SYN,RST,或者ACK, 任何其它三种(FIN,PSH,and URG)的组合都行。Nmap有三种扫描类型利用这一点:

Null扫描 (-sN)
不设置任何标志位(tcp标志头是0)

FIN扫描 (-sF)
只设置TCP FIN标志位。

Xmas扫描 (-sX)
设置FIN,PSH,和URG标志位,就像点亮圣诞树上所有的灯一样。

除了探测报文的标志位不同,这三种扫描在行为上完全一致。 如果收到一个RST报文,该端口被认为是 closed(关闭的),而没有响应则意味着 端口是open|filtered(开放或者被过滤的)。 如果收到ICMP不可到达错误(类型 3,代号 1,2,3,9,10,或者13),该端口就被标记为 被过滤的。

这些扫描的关键优势是它们能躲过一些无状态防火墙和报文过滤路由器。 另一个优势是这些扫描类型甚至比SYN扫描还要隐秘一些。但是别依赖它 -- 多数 现代的IDS产品可以发现它们。一个很大的不足是并非所有系统都严格遵循RFC 793。 许多系统不管端口开放还是关闭,都响应RST。 这导致所有端口都标记为closed(关闭的)。 这样的操作系统主要有Microsoft Windows,许多Cisco设备,BSDI,以及IBM OS/400。 但是这种扫描对多数UNIX系统都能工作。这些扫描的另一个不足是 它们不能辨别open(开放的)端口和一些特定的 filtered(被过滤的)端口,从而返回 open|filtered(开放或者被过滤的)。

nmap -n -P0 -sN -p80 --max-retries=0 --packet-trace -v 150.1.1.1
nmap -n -P0 -sF -p80 --max-retries=0 --packet-trace -v 150.1.1.1
nmap -n -P0 -sX -p80 --max-retries=0 --packet-trace -v 150.1.1.1
# 上面三个扫描80端口都是open|filtered
# 150.1.1.1的80端口明明是开放的
# 扫描结果
Host is up.
PORT   STATE         SERVICE
80/tcp open|filtered http

-sA (TCP ACK扫描)

这种扫描与目前为止讨论的其它扫描的不同之处在于 它不能确定open(开放的)或者 open|filtered(开放或者过滤的))端口。 它用于发现防火墙规则,确定它们是有状态的还是无状态的,哪些端口是被过滤的。

ACK扫描探测报文只设置ACK标志位(除非您使用 --scanflags)。当扫描未被过滤的系统时, open(开放的)和closed(关闭的) 端口 都会返回RST报文。Nmap把它们标记为 unfiltered(未被过滤的),意思是 ACK报文不能到达,但至于它们是open(开放的)或者 closed(关闭的) 无法确定。不响应的端口 或者发送特定的ICMP错误消息(类型3,代号1,2,3,9,10, 或者13)的端口,标记为 filtered(被过滤的)。

nmap -n -P0 -sA -p80 --max-retries=0 --packet-trace -v 150.1.1.1
# 150.1.1.1的80端口明明是开放的
# 扫描结果
Host is up (0.24s latency).
PORT   STATE      SERVICE
80/tcp unfiltered http

-sW (TCP窗口扫描)

窗口扫描与-sA扫描完全相同除了利用特定系统的实现细节来区分开放端口和关闭端口,当收到RST时不总是打印unfiltered, 窗口扫描和ACK扫描完全一样。 它通过检查返回的RST报文的TCP窗口字段做到这一点。 在某些系统上,开放端口用正数表示窗口大小(甚至对于RST报文) 而关闭端口的窗口大小为0。因此,当收到RST时,窗口扫描不总是把端口标记为 unfiltered, 而是根据TCP窗口值是正数还是0,分别把端口标记为open或者 closed

该扫描依赖于互联网上少数系统的实现细节, 因此您不能永远相信它。不支持它的系统会通常返回所有端口closed。 当然,一台机器没有开放端口也是有可能的。 如果大部分被扫描的端口是 closed,而一些常见的端口 (如 22, 25,53) 是 filtered,该系统就非常可疑了。 偶尔地,系统甚至会显示恰恰相反的行为。 如果您的扫描显示1000个开放的端口和3个关闭的或者被过滤的端口, 那么那3个很可能也是开放的端口。

关于TCP窗口:win = 16616表示这台机器的TCP窗口为16616,可以明显的看到beta.search.microsoft.com有两台机器做均衡负载,因为有两个TCP窗口win = 16616和win = 0。

关于ipid:一个ipid分别为id = 57645和id = 18574也能表示这是两台机器。ipid是-sI扫描用到的主要原理。

更多详情见:
Detecting Packet Forgery by Firewall and Intrusion Detection Systems | Nmap Network Scanning
TCP Idle Scan (-sI) | Nmap Network Scanning

# -c 10发送是十个数据,-i 1间隔1秒,-p 80 目的是80端口,-S应该是发送带有SYN标志位的TCP报文
# hping2 -c 10 -i 1 -p 80 -S beta.search.microsoft.com
HPING beta.search.microsoft.com。(eth0 207.46.197.115):S设置,40个标题
来自207.46.197.115的46个字节:flags = SA seq = 0 ttl = 56 id = 57645 win = 16616
来自207.46.197.115的46个字节:flags = SA seq = 1 ttl = 56 id = 57650 win = 16616
来自207.46.197.115的46个字节:flags = RA seq = 2 ttl = 56 id = 18574 win = 0
来自207.46.197.115的46个字节:flags = RA seq = 3 ttl = 56 id = 18587 win = 0
来自207.46.197.115的46个字节:flags = RA seq = 4 ttl = 56 id = 18588 win = 0
来自207.46.197.115的46个字节:flags = SA seq = 5 ttl = 56 id = 57741 win = 16616
来自207.46.197.115的46个字节:flags = RA seq = 6 ttl = 56 id = 18589 win = 0
来自207.46.197.115的46个字节:标志= SA seq = 7 ttl = 56 id = 57742 win = 16616
来自207.46.197.115的46个字节:标志= SA seq = 8 ttl = 56 id = 57743 win = 16616
来自207.46.197.115的46个字节:标志= SA seq = 9 ttl = 56 id = 57744 win = 16616
nmap -n -P0 -sW--max-retries=0 --packet-trace -v 150.1.1.1
# 150.1.1.1的80端口明明是开放的
# 扫描结果
Host is up (0.24s latency).
All 1000 scanned ports on 150.1.1.1 are filtered (679) or closed (321)

-sM (TCP Maimon扫描)

Maimon扫描是用它的发现者Uriel Maimon命名的。他在 Phrack Magazine issue #49 (November 1996)中描述了这一技术。 Nmap在两期后加入了这一技术。 这项技术和Null,FIN,以及Xmas扫描完全一样,除了探测报文是FIN/ACK。 根据RFC 793 (TCP),无论端口开放或者关闭,都应该对这样的探测响应RST报文。 然而,Uriel注意到如果端口开放,许多基于BSD的系统只是丢弃该探测报文。

nmap -n -P0 -sM --max-retries=0 -p80 --packet-trace -v 150.1.1.1
# 150.1.1.1的80端口明明是开放的
# 扫描结果
Host is up (0.24s latency).
PORT   STATE  SERVICE
80/tcp closed http

--scanflags (定制的TCP扫描)

真正的Nmap高级用户不需要被这些现成的扫描类型束缚。 --scanflags选项允许您通过指定任意TCP标志位来设计您自己的扫描。 让您的创造力流动,躲开那些仅靠本手册添加规则的入侵检测系统!

--scanflags选项可以是一个数字标记值如9 (PSH和FIN), 但使用字符名更容易些。 只要是URG, ACK,PSH, RST,SYN,and FIN的任何组合就行。例如,--scanflags URGACKPSHRSTSYNFIN设置了所有标志位,但是这对扫描没有太大用处。 标志位的顺序不重要。

除了设置需要的标志位,您也可以设置 TCP扫描类型(如-sA或者-sF)。 那个基本类型告诉Nmap怎样解释响应。例如, SYN扫描认为没有响应意味着 filtered端口,而FIN扫描则认为是 open|filtered。 除了使用您指定的TCP标记位,Nmap会和基本扫描类型一样工作。 如果您不指定基本类型,就使用SYN扫描。

-sZ (SCTP COOKIE ECHO扫描)

SCTP COOKIE ECHO扫描是更高级的SCTP扫描。利用以下事实:SCTP实现应在打开的端口上静默丢弃包含COOKIE ECHO块的数据包,但在端口关闭时发送ABORT。这种扫描类型的优点在于,端口扫描不像INIT扫描那样明显。同样,可能有非状态防火墙规则集阻止INIT块,但不会阻止COOKIE ECHO块。不要上当以为这将使端口扫描不可见。一个好的IDS也将能够检测SCTP COOKIE ECHO扫描。缺点是SCTP COOKIE ECHO扫描无法区分open和filtered 端口,open|filtered 在两种情况下都处于状态。

nmap -n -P0 -sZ -p80 --max-retries=0 --packet-trace -v 150.1.1.1
# 全是open|filtered状态,估计是协议不支持,并且好多防火墙只有放开TCP或者UDP选项。
# 150.1.1.1的80端口明明是开放的
# 扫描结果
Host is up.
PORT    STATE         SERVICE
80/sctp open|filtered http

-sI <zombie host[:probeport]> (Idlescan)

这种高级的扫描方法允许对目标进行真正的TCP端口盲扫描 (意味着没有报文从您的真实IP地址发送到目标)。相反,side-channel攻击 利用zombie主机上已知的IP分段ID序列生成算法来窥探目标上开放端口的信息。 IDS系统将显示扫描来自您指定的zombie机(必须运行并且符合一定的标准)。 这种奇妙的扫描类型太复杂了,不能在此完全描述,所以我写一篇非正式的论文, 发布在https://nmap.org/book/idlescan.html

除了极端隐蔽(由于它不从真实IP地址发送任何报文), 该扫描类型可以建立机器间的基于IP的信任关系。 端口列表从zombie 主机的角度。显示开放的端口。 因此您可以尝试用您认为(通过路由器/包过滤规则)可能被信任的 zombies扫描目标。

如果您由于IPID改变希望探测zombie上的特定端口, 您可以在zombie 主机后加上一个冒号和端口号。 否则Nmap会使用默认端口(80)。

关于ipid:ipid就是下图中的id,两个个ipid分别为id = 57645和id = 18574表示这是两台机器,因为通常ipid应该是顺序增加的。ipid是-sI扫描用到的主要原理。

# -c 10发送是十个数据,-i 1间隔1秒,-p 80 目的是80端口,-S应该是发送带有SYN标志位的TCP报文
# hping2 -c 10 -i 1 -p 80 -S beta.search.microsoft.com
HPING beta.search.microsoft.com。(eth0 207.46.197.115):S设置,40个标题
来自207.46.197.115的46个字节:flags = SA seq = 0 ttl = 56 id = 57645 win = 16616
来自207.46.197.115的46个字节:flags = SA seq = 1 ttl = 56 id = 57650 win = 16616
来自207.46.197.115的46个字节:flags = RA seq = 2 ttl = 56 id = 18574 win = 0
来自207.46.197.115的46个字节:flags = RA seq = 3 ttl = 56 id = 18587 win = 0
来自207.46.197.115的46个字节:flags = RA seq = 4 ttl = 56 id = 18588 win = 0
来自207.46.197.115的46个字节:flags = SA seq = 5 ttl = 56 id = 57741 win = 16616
来自207.46.197.115的46个字节:flags = RA seq = 6 ttl = 56 id = 18589 win = 0
来自207.46.197.115的46个字节:标志= SA seq = 7 ttl = 56 id = 57742 win = 16616
来自207.46.197.115的46个字节:标志= SA seq = 8 ttl = 56 id = 57743 win = 16616
来自207.46.197.115的46个字节:标志= SA seq = 9 ttl = 56 id = 57744 win = 16616

更多详情见:
Detecting Packet Forgery by Firewall and Intrusion Detection Systems | Nmap Network Scanning
TCP Idle Scan (-sI) | Nmap Network Scanning

nmap -sI 47.3.1.1:443 -Pn -p80 -r --packet-trace --max-rate 1 -v 150.1.1.1
# 我试了很多遍都得不到想要的结果
# 150.1.1.1的80端口明明是开放的
# 爆错如下:
Idle scan is unable to obtain meaningful results from proxy 47.3.1.1 (47.3.1.1).  
I'm sorry it didn't work out.
QUITTING!

-sO (IP协议扫描)

IP 协议扫描可以让您确定目标机支持哪些IP协议 (TCP,ICMP,IGMP,等等)。从技术上说,这不是端口扫描 ,既然它遍历的是IP协议号而不是TCP或者UDP端口号。 但是它仍使用 -p选项选择要扫描的协议号, 用正常的端口表格式报告结果,甚至用和真正的端口扫描一样 的扫描引擎。因此它和端口扫描非常接近,也被放在这里讨论。

除了本身很有用,协议扫描还显示了开源软件的力量。 尽管基本想法非常简单,我过去从没想过增加这一功能也没收到任何对它的请求。 在2000年夏天,Gerhard Rieger孕育了这个想法,写了一个很棒的补丁程序,发送到nmap-hackers邮件列表。 我把那个补丁加入了Nmap,第二天发布了新版本。 几乎没有商业软件会有用户有足够的热情设计并贡献他们的改进。

协议扫描以和UDP扫描类似的方式工作。它不是在UDP报文的端口域上循环, 而是在IP协议域的8位上循环,发送IP报文头。 报文头通常是空的,不包含数据,甚至不包含所申明的协议的正确报文头 TCP,UDP,和ICMP是三个例外。它们三个会使用正常的协议头,因为否则某些系 统拒绝发送,而且Nmap有函数创建它们。协议扫描不是注意ICMP端口不可到达消息, 而是ICMP 协议不可到达消息。如果Nmap从目标主机收到 任何协议的任何响应,Nmap就把那个协议标记为open。 ICMP协议不可到达 错误(类型 3,代号 2) 导致协议被标记为 closed。其它ICMP不可到达协议(类型 3,代号 1,3,9,10,或者13) 导致协议被标记为 filtered (虽然同时他们证明ICMP是 open )。如果重试之后仍没有收到响应, 该协议就被标记为open|filtered

nmap -sO -Pn 150.1.1.1
# -sO必须单独使用,不能和-sSz之类连用

连用报错如下:
root@racknerd-3a522c:~# nmap -sS -sO -Pn 150.1.1.1
Sorry, the IPProtoscan (-sO) must currently be used alone rather than combined with other scan types.
QUITTING!

-b <ftp relay host> (FTP弹跳扫描)

FTP协议的一个有趣特征(RFC 959) 是支持所谓代理ftp连接。它允许用户连接到一台FTP服务器,然后要求文件送到一台第三方服务器。 这个特性在很多层次上被滥用,所以许多服务器已经停止支持它了。其中一种就是导致FTP服务器对其它主机端口扫描。 只要请求FTP服务器轮流发送一个文件到目标主机上的所感兴趣的端口。 错误消息会描述端口是开放还是关闭的。 这是绕过防火墙的好方法,因为FTP服务器常常被置于可以访问比Web主机更多其它内部主机的位置。 Nmap用-b选项支持ftp弹跳扫描。参数格式是 <username>:<password>@<server>:<port>。 <Server> 是某个脆弱的FTP服务器的名字或者IP地址。 您也许可以省略<username>:<password>, 如果服务器上开放了匿名用户(user:anonymous password:-wwwuser@)。 端口号(以及前面的冒号) 也可以省略,如果<server>使用默认的FTP端口(21)。

这个漏洞在1997年Nmap发布的时候很普遍,但基本上已经被修复了。有漏洞的服务器仍然存在,所以当所有其他方法都失败时,值得一试。如果绕过防火墙是您的目标,扫描目标网络的21端口(如果您用版本检测扫描所有端口,甚至扫描任何FTP服务),然后使用ftp-bounce NSE脚本。Nmap会告诉你主机是否有漏洞。如果您只是想掩盖您的踪迹,您不需要(事实上,也不应该)把自己限制在目标网络的主机上。在您去扫描随机的互联网地址寻找易受攻击的FTP服务器之前,考虑到系统管理员可能不喜欢您以这种方式滥用他们的服务器。


步骤说明和扫描顺序

除了前面讨论的所有扫描方法之外,Nmap还提供用于指定要扫描哪些端口以及扫描顺序是随机的还是顺序的选项。默认情况下,Nmap为每个协议扫描最常见的1,000个端口。

-p <端口范围> (只扫描指定的端口)

此选项指定您要扫描的端口,并覆盖默认值。单个端口号可以,用连字符分隔的范围也可以(如1-1023)。一个范围的开始和/或结束值可以省略,使Nmap分别使用1和65535。所以您可以指定-p-来扫描1到65535的端口。如果您明确指定,允许扫描0端口。对于IP协议扫描(-sO),这个选项指定您希望扫描的协议号(0-255)。

当扫描协议的组合时(如TCP和UDP),您可以在端口号前用T:代表TCP,U:代表UDP,S:代表SCTP,或P:代表IP协议来指定特定协议。这个限定符一直持续到你指定另一个限定符为止。例如,参数-p U:53,111,137,T:21-25,80,139,8080将扫描UDP端口53,111,和137,以及列出的TCP端口。注意,如果要同时扫描UDP和TCP,必须指定-sU和至少一种TCP扫描类型(如-sS、-sF或-sT)。如果没有给出协议限定符,则端口号会被添加到所有协议列表中。

也可以根据nmap-services中端口的名称来指定端口。您甚至可以在名称中使用通配符和? 例如,要扫描FTP和所有名字以 "http "开头的端口,使用-p ftp,http。要注意shell的扩展,如果不确定的话,可以在-p的参数中加上引号。

端口的范围可以用方括号包围,以表示在nmap-services中出现的该范围内的端口。例如,以下将扫描 nmap-services 中等于或低于 1024 的所有端口: -p [-1024]。小心使用shell扩展,如果不确定的话,请在-p的参数中加上引号。

# 下面三条命令等效
nmap -n -P0 -sS -p "80" --packet-trace 150.1.1.1
nmap -n -P0 -sS -p80 --packet-trace 150.1.1.1
nmap -n -P0 -sS -p 80 --packet-trace 150.1.1.1

# 扫描80以及443端口
nmap -n -P0 -sS -p80,443 --packet-trace 150.1.1.1
nmap -n -P0 -sS -p 80,443 --packet-trace 150.1.1.1

# 扫描默认的1000个端口,-T4表示加快扫描速度,后面会详细说
nmap -n -P0 -sS -T4 150.1.1.1
# 扫描结果
Host is up (0.24s latency).
Not shown: 990 closed ports
PORT     STATE    SERVICE
22/tcp   open     ssh
80/tcp   open     http
135/tcp  filtered msrpc
139/tcp  filtered netbios-ssn
445/tcp  filtered microsoft-ds
593/tcp  filtered http-rpc-epmap
3306/tcp open     mysql
4444/tcp filtered krb524
8090/tcp open     unknown
9080/tcp open     glrpc

--exclud-ports <端口范围> (将指定的端口排除在扫描范围之外)

这个选项指定您希望Nmap从扫描中排除哪些端口。<端口范围>的指定与-p类似。对于IP协议扫描(-sO),这个选项指定您希望排除的协议号(0-255)。

当要求排除端口时,它们将被排除在所有类型的扫描之外(即在任何情况下都不会对它们进行扫描)。这也包括发现阶段。

# 排除80和443端口
nmap -n -P0 -sS -T4 --exclude-ports 80,443 150.1.1.1

-F(快速(有限端口)扫描)。

指定您希望扫描的端口比默认值少。通常Nmap对每个扫描的协议扫描最常见的1000个端口。使用-F,这个数字会减少到100。

Nmap需要一个包含频率信息的nmap-services文件来知道哪些端口是最常见的(更多关于端口频率的信息请看 "Well Known Port List: nmap-services "一节)。如果没有端口频率信息,也许是因为使用了自定义的nmap-services文件,Nmap扫描所有命名的端口加上端口1-1024。在这种情况下,-F表示只扫描服务文件中命名的端口。

nmap -n -P0  -F -sS -T4 --exclude-ports 80 150.1.1.1

-r (不使用随机端口)

默认情况下,Nmap随机扫描端口顺序(除了某些常用的端口出于效率的原因被移到开头)。这种随机化通常是可取的,但您可以指定-r来代替顺序扫描(从低到高排序)端口。

nmap -n -P0  -r -sS -T4 --exclude-ports 80 --packet-trace 150.1.1.1

--port-ratio <ratio><小数,介于0和1之间>。

扫描 nmap-services 文件中所有端口的比率大于给定的比率。<ratio>必须在0.0和1.0之间。

nmap -n -P0  -r -sS -T4 --port-ratio 0.484142 150.1.1.1

/usr/share/nmap/nmap-services文件如下:

步骤说明和扫描顺序1.png

后面的数字表示常用端口出现的概率

--top-ports <n>。

排除所有由--exclud-ports指定的端口后,从nmap-services文件提取最高概率的前几个端口进行扫描。<n>必须是1或更大。

nmap -n -P0  -r -sS -T4 --top-ports 2 150.1.1.1

服务和版本检测

将Nmap指向一台远程机器,它可能会告诉您25/tcp、80/tcp和53/udp端口是开放的。使用nmap-services数据库中大约2200个著名的服务,Nmap会报告这些端口可能分别对应邮件服务器(SMTP)、网络服务器(HTTP)和名称服务器(DNS)。这种查询通常是准确的--绝大多数在TCP端口25上监听的守护进程事实上是邮件服务器。然而,你不应该把你的安全赌注押在这上面!人们可以而且确实在奇怪的端口上运行服务。人们可以而且确实在奇怪的端口上运行服务。

即使Nmap是正确的,上面的假设服务器正在运行SMTP、HTTP和DNS服务器,那也不是很多信息。当对您的公司或客户进行漏洞评估(甚至是简单的网络清查)时,您真的想知道哪些邮件和DNS服务器和版本在运行。拥有一个准确的版本号对确定服务器容易受到哪些漏洞的攻击有很大的帮助。版本检测可以帮助你获得这些信息。

在使用其他扫描方法之一发现TCP和/或UDP端口后,版本检测会询问这些端口,以确定更多关于实际运行的内容。nmap-service-probes数据库包含用于查询各种服务的探针,以及用于识别和解析响应的匹配表达式。Nmap试图确定服务协议(如FTP、SSH、Telnet、HTTP)、应用程序名称(如ISC BIND、Apache httpd、Solaris telnetd)、版本号、主机名、设备类型(如打印机、路由器)、操作系统系列(如Windows、Linux)。在可能的情况下,Nmap也会得到这些信息的通用平台枚举(CPE)表示。有时也会得到一些杂项细节,如服务器是否开放连接,SSH协议版本,或KaZaA用户名。当然,大多数服务不提供所有这些信息。如果Nmap在编译时支持OpenSSL,它将连接SSL服务器来推断该加密层后面的监听服务。有些UDP端口在UDP端口扫描后,无法判断该端口是开放的还是过滤的状态。版本检测将尝试从这些端口中引出响应(就像它对开放端口所做的那样),如果成功的话,就将状态改为开放,开放|过滤的TCP端口也会以同样的方式处理。请注意,Nmap -A选项启用了版本检测等功能。版本检测在第7章 "服务和应用程序版本检测 "中有详细介绍。

当发现RPC服务时,Nmap RPC grinder自动用来确定RPC程序和版本号。它把所有检测到的TCP/UDP端口作为RPC端口,并用SunRPC程序NULL命令向它们发送请求,试图确定它们是否是RPC端口,如果是,它们提供的是什么程序和版本号。因此,即使目标的端口映射程序位于防火墙后面(或受 TCP 封装保护),您也可以有效地获得与 rpcinfo -p 相同的信息。-D目前不能和RPC扫描一起工作。

当Nmap接收到一个服务的响应但不能将它们与数据库匹配时,如果您确定端口上运行的是什么,它就会打印出一个特殊的指纹和一个URL供您提交。请花几分钟时间提交,这样您的发现就能让大家受益。由于这些提交,Nmap有大约6500个模式匹配,涉及650多个协议,如SMTP,FTP,HTTP等。

版本检测用以下选项启用和控制。

-sV (版本检测)

启用版本检测,如上所述。或者,你也可以使用-A,它可以启用版本检测和操作系统检测以及其他很多功能。

-sR是-sV的别称。在2011年3月之前,它被用来单独激活RPC grinder和版本检测,但现在这些选项总是结合在一起。

--allports (不要将任何端口排除在版本检测之外)

默认情况下,Nmap版本检测跳过TCP端口9100,因为有些打印机只是打印发送到该端口的任何东西,导致几十页的HTTP GET请求、二进制SSL会话请求等。这种行为可以通过修改或删除nmap-service-probes中的Exclude指令来改变,或者您可以指定--allports来扫描所有端口,而不考虑任何Exclude指令。

--version-intensity <intensity> (设置版本扫描强度)

当执行版本扫描(-sV)时,Nmap发送一系列探测器,每个探测器被分配一个1到9的稀有度值。编号较低的探测对各种常见服务有效,而编号较高的探测很少有用。强度等级规定了应该应用哪些探针。编号越高,正确识别服务的可能性越大。然而,高强度扫描需要更长的时间。强度必须介于0和9之间,默认为7。当通过 nmap-service-probes ports 指令将探针注册到目标端口时,无论强度水平如何,都会尝试该探针。这确保了DNS探针将始终针对任何开放的53端口进行尝试,SSL探针将针对443端口进行,等等。

--version-light (启用轻模式)

这是--version-intensity 2的方便别名。这种轻型模式使版本扫描速度更快,但它识别服务的可能性略低。

--version-all (尝试每一个探针)

--version-intensity 9 的别名,确保每一个端口都会尝试进行探测。

--version-trace (跟踪版本扫描活动)

这使Nmap打印出关于版本扫描正在做的大量调试信息。它是你用-packet-trace得到的信息的一个子集。


操作系统检测

Nmap最著名的功能之一是用TCP/IP协议栈fingerprinting进行远程操作系统探测。 Nmap发送一系列TCP和UDP报文到远程主机,检查响应中的每一个比特。在执行了几十项测试,如TCP ISN取样、TCP选项支持和排序、IP ID取样和初始窗口大小检查后,Nmap将结果与它的nmap-os-db数据库中的2600多个已知操作系统指纹进行比较,如果有匹配的,就打印出操作系统的细节。每个指纹包括一个自由格式的关于OS的描述文本, 和一个分类信息,它提供提供厂商名称(如Sun)、底层操作系统(如Solaris)、OS版本(如10)和设备类型(通用、路由器、交换机、游戏控制台等)的分类。大多数指纹也有一个通用平台枚举(CPE)表示,比如cpe:/o:linux:linux_kernel:2.6。

如果Nmap无法猜测一台机器的操作系统,而且条件良好(例如至少找到一个开放端口和一个封闭端口),Nmap会提供一个URL,如果您知道(确定)这台机器上运行的操作系统,您可以用来提交指纹。通过这样做,您为Nmap已知的操作系统池做出了贡献,因此它对每个人来说都会更准确。

操作系统检测可以进行其它一些测试,这些测试使用了在测试过程中收集到的信息。其中之一是TCP序列号预测分类。这大约衡量了针对远程主机建立一个伪造的TCP连接的难度。它对于利用基于源-IP的信任关系(rlogin、防火墙过滤器等)或隐藏攻击源很有用。这种欺骗行为已经很少进行了,但很多机器仍然容易受到它的影响。实际的难度数字是根据统计抽样得出的,可能会有波动。通常采用英国的分类较好,如“worthy challenge”或者 “trivial joke”。只在verbose模式(-v)下打印。
,如果同时使用-O,还报告IPID序列产生号。 很多主机的序列号是“增加”类别,即在每个发送包的IP头中 增加ID域值, 这对一些先进的信息收集和哄骗攻击来说是个漏洞。

OS检测启用的另一点额外信息是猜测目标的正常运行时间。这使用TCP时间戳选项(RFC 1323)来猜测机器最后一次重启的时间。由于时间戳计数器没有初始化为零,或者计数器溢出并绕过,所以猜测可能不准确,所以它只在verbose模式(-v)下打印。

OS检测在第8章远程OS检测中有所介绍。

OS检测可以通过以下选项启用和控制。

-O (启用操作系统检测)

启用OS检测,如上所述。另外,你也可以使用-A来启用OS检测和其他功能。

--osscan-limit (针对指定的目标进行操作系统检测)

如果发现一个打开和关闭的TCP端口时,操作系统检测会更有效。 采用这个选项,Nmap只对满足这个条件的主机进行操作系统检测,这样可以 节约时间,特别在使用-P0扫描多个主机时。这个选项仅在使用 -O或-A 进行操作系统检测时起作用。

--osscan-guess; --fuzzy (推测操作系统检测结果)

当Nmap不能检测到一个完美的操作系统匹配时,它有时会提供接近匹配的可能性。匹配必须非常接近,Nmap才会默认这样做。这些(等效)选项中的任何一个都会使Nmap更积极地猜测。当一个不完全匹配被打印出来时,Nmap仍然会告诉您,并显示每次猜测的置信度(百分比)。

--max-os-tries (设置对一个目标的最大OS检测次数)

当Nmap对一个目标进行OS检测,但没有找到完美的匹配,它通常重复尝试。默认情况下,如果条件对OS指纹提交有利,Nmap尝试5次,条件不好时尝试两次。指定一个较低的--max-os-tries值(比如1)可以加快Nmap的速度,尽管您会错过可能识别操作系统的重试。另外,当条件有利时,可以设置一个高值允许更多的重试。这很少做,除非是为了生成更好的指纹以便提交和整合到Nmap OS数据库。


NSE脚本引擎

Nmap脚本引擎(NSE)是Nmap最强大,最灵活的功能之一。它允许用户编写(和共享)简单的脚本(使用Lua编程语言 )以自动执行各种联网任务。这些脚本与您期望的Nmap的速度和效率并行执行。用户可以依靠随Nmap分发的不断增长的脚本集,也可以编写自己的脚本来满足定制需求。

在创建系统时,我们想到的任务包括网络发现,更复杂的版本检测,漏洞检测。NSE甚至可以用于漏洞利用。

为了反映这些不同的用途并简化对要运行的脚本的选择,每个脚本都包含一个将其与一个或多个类别相关联的字段。当前定义的类别 auth, broadcast, default。 discovery, dos, exploit, external, fuzzer, intrusive, malware, safe, version,和 vuln。这些都在"脚本类别"一节中进行了描述。

脚本不在沙盒中运行,因此可能会意外或恶意破坏您的系统或侵犯您的隐私。除非您信任作者或自己仔细审核过脚本,否则切勿运行第三方脚本。

Nmap脚本引擎中详细描述在第9章,Nmap的脚本引擎

由以下选项控制:

-sC

使用默认脚本集执行脚本扫描。等同于--script=default。此类别中的某些脚本被认为是侵入性的,未经允许不得在目标网络上运行。

--script <filename>|<category>|<directory>/|<expression>[,...]

使用逗号分割参数。列表中的每个元素也可以是布尔表达式,用于描述更复杂的脚本集。每个元素首先解释为表达式,然后解释为类别,最后解释为文件或目录名称。

nmap --script-help ftp-anon,auth
# ftp-anon被解释为脚本名称
# auth被解释为脚本的类别

仅高级用户有两个特殊功能。一种是给脚本名称和表达式加上前缀, +以强制它们正常运行,即使它们通常不会运行(例如,在目标端口上未检测到相关服务)。另一个是该参数all可用于指定Nmap数据库中的每个脚本。注意这一点,因为NSE包含危险脚本,例如漏洞利用,蛮力身份验证破解程序和拒绝服务攻击。

寻找脚本时按照以下顺序:

文件和目录名称可以是相对或绝对的。绝对名称直接使用。scripts在以下每个位置中寻找相对路径, 直到找到为止:

首先在--datadir选项说明的目录中查找这些文件
$NMAPDIR
~/.nmap (仅linux上)
<APPDATA>\nmap (仅在Windows上)
包含nmap 可执行文件的目录
包含nmap 可执行文件的目录,后跟../share/nmap(仅linux上)
NMAPDATADIR (在linux上)
当前目录。

当给出以/结尾的目录名称时,Nmap会加载目录中以.nse结尾的每个文件。所有其他文件都将被忽略,并且不会递归搜索目录。给定文件名时,它不必具有.nse扩展名。如有必要,它将自动添加。

scripts 默认情况下,Nmap脚本存储在Nmap数据目录的子目录中(请参见第14章,了解和自定义Nmap数据文件)。为了提高效率,脚本在存储的数据库中建立了索引scripts/script.db, 其中列出了每个脚本所属的一个或多个类别。

script.db通过名称 引用脚本时,可以使用shell样式的'*'通配符。

nmap --script "http- *"

加载名称以开头的所有脚本 http-,例如 http-auth和 http-open-proxy。--script的参数必须用引号引起来,以保护通配符不受shell的影响。

更复杂的脚本选择 可以使用 and,or以及 not建立布尔表达式。运算符的优先级 与Lua中的优先级相同 :not是最高,然后是 and,然后是or。您可以使用括号来更改优先级。由于表达式包含空格字符,因此必须用引号引起来。

nmap --script "not intrusive"

加载除intrusive类别中的脚本以外的所有脚本 。

nmap --script "default or safe"

这在功能上等效于 nmap --script "default,safe"。它加载default类别或safe类别或同时属于两个类别的脚本。

nmap --script "default and safe"

加载同时属于default和safe类别的脚本。

nmap --script "(default or safe or intrusive) and not http-*"

加载属于default, safe或intrusive 类别,但是名字开头不是 http- 的脚本

--script-args <n1>=<v1>,<n2>={<n3>=<v3>},<n4>={<v4>,<v5>}

使您可以为NSE脚本提供参数。参数是一name=value对以逗号分隔的列表。名称和值必须是不包含空格或字符"{","}","="或","的字符串。要将这些字符之一包含在字符串中,请将该字符串用单引号或双引号引起来。在带引号的字符串中,使用'\'转义引号,在这种特殊情况下,反斜线仅用于转义引号;值也可以是包含在中的表{},就像Lua中一样。一个表可能包含简单的字符串值或更多的名称/值对,包括嵌套表。许多脚本使用脚本名称来限定其自变量,例如xmpp-info.server_name。您可以使用完全限定的版本来仅影响指定的脚本,或者可以传递非限定版本(在这种情况下使用server_name)以使用该参数名称来影响所有脚本。脚本在接受不合格的参数名称之前,将首先检查其完全限定的参数名称(在其文档中指定的名称)。脚本参数的一个复杂示例是--script-args 'user=foo,pass=",{}=bar",whois={whodb=nofollow+ripe},xmpp-info.server_name=localhost'。NSE在线文档门户列出了每个脚本可接受的参数。

--script-args-file <filename>

使您可以从文件将参数加载到NSE脚本。命令行上的所有参数都将取代文件中的参数。该文件可以是绝对路径,也可以是相对于Nmap常规搜索路径的路径(NMAPDIR等)。参数可以用逗号分隔或换行符分隔,但是可以遵循与for相同的规则--script-args,而无需特殊的引号和转义,因为它们不是由shell解析的。

--script-help <filename>|<category>|<directory>|<expression>|all[,...]

显示有关脚本的帮助。对于与给定规范匹配的每个脚本,Nmap将打印脚本名称,其类别和说明。参数格式和--script相同; 因此,例如,如果您需要有关ftp-anon脚本的帮助,则可以运行 nmap --script-help ftp-anon。除了获得单个脚本的帮助之外,您还可以打印属于某个类别的脚本,例如,使用nmap --script-help default。

--script-trace

此选项和--packet-trace一样,仅仅比--packet-trace在ISO模型中高一层。如果指定了此选项,则将打印脚本执行的所有传入和传出通信。显示的信息包括通信协议,源,目标和发送的数据。如果所有传输数据的5%以上不可打印,则跟踪输出为十六进制转储格式。使用--packet-trace也会启用--packet-trace。

-script-updatedb

此选项更新脚本数据库scripts/script.db,Nmap使用该数据库来确定可用的默认脚本和类别。仅当您从默认scripts目录中添加或删除了NSE脚本或更改了任何脚本的类别时,才需要更新数据库。此选项通常单独使用:nmap --script-updatedb。


时间和性能

Nmap开发的最高优先级是性能。在本地网络对一个主机的默认扫描(nmap <hostname>)需要1/5秒。这个时间几乎不够眨眼的,但当您扫描数百或数千台主机时,时间就会增加。此外,某些扫描选项,如UDP扫描和版本检测会大幅增加扫描时间。某些防火墙配置也是如此,特别是响应速度限制。虽然Nmap利用并行和许多高级算法来加速这些扫描,但用户对Nmap如何运行有最终的控制权。专家级用户精心设计Nmap命令,只获取他们关心的信息,同时满足他们的时间限制。

改善扫描时间的技术包括省略非关键测试,升级到最新版本的Nmap(经常进行性能改进)。优化时序参数也可以产生实质性的差别。这些选项列在下面。

一些选项接受一个时间参数。默认情况下是以秒为单位的,尽管您可以在值后面加上'ms'、's'、'm'或'h'来指定毫秒、秒、分钟或小时。所以 --host-timeout 参数 900000ms、900、900s 和 15m 都是一样的。

--min-hostgroup <size>; --max-hostgroup <size> (调整并行扫描组的大小)

Nmap有能力并行扫描多个主机的端口或版本扫描。Nmap通过将目标IP空间划分成组,然后一次扫描一个组来实现。一般来说,较大的组更有效率。缺点是在整个组完成之前不能提供主机结果。因此,如果Nmap一开始的组大小是50个,用户不会收到任何报告(除了在verbose模式下提供的更新),直到前50个主机完成。

默认情况下,Nmap对这个冲突采取了一个折中的方法。它一开始的组大小只有5个,所以第一个结果很快就出来了,然后把组大小增加到1024个。确切的默认数字取决于给定的选项。出于效率的原因,Nmap对UDP或少数端口的TCP扫描使用较大的组大小。

当用--max-hostgroup指定一个最大的组大小时,Nmap永远不会超过这个大小。用--min-hostgroup指定一个最小的组,Nmap会尽量保持组的大小高于这个水平。如果给定接口上没有足够的目标主机来满足指定的最小值,Nmap可能不得不使用比您指定的更小的组。两者都可以设置为将组的大小保持在一个特定的范围内,尽管这很少被需要。

这些选项在扫描的主机发现阶段不会产生影响。这包括普通的ping扫描(-sn)。主机发现总是在大组主机中工作,以提高速度和准确性。

这些选项的主要用途是指定一个最小组的大小,以便使完整的扫描更快地运行。一个常见的选择是256,以便在/24大小的块中扫描网络。对于有许多端口的扫描,超过这个数字不太可能有什么帮助。对于只有几个端口号的扫描,主机组大小为2048或更多可能会有帮助。

--min-parallelism <numprobes>; --max-parallelism <numprobes> (调整探测报文的并行度)

这些选项控制用于主机组的探测报文数量,用于端口扫描和主机发现。它们用于端口扫描和主机发现。默认情况下,Nmap根据网络性能计算一个不断变化的理想并行度。如果数据包被丢弃,Nmap就会减慢速度,探测报文数量减少。随着网络性能的改善,理想的探测报文数量慢慢上升。这些选项对该变量设置了最小或最大界限。默认情况下,如果网络被证明不可靠,理想的并行度可以降到1,在完美的条件下可以上升到几百。

最常见的用法是将--min-parallelism设置为一个高于1的数字,以加快对性能不佳的主机或网络的扫描。这是个有风险的选项,因为设置太高可能会影响准确性。设置这个也会降低Nmap根据网络条件动态控制并行度的能力。这个值设为10较为合适, 这个值的调整往往作为最后的手段。

--max-parallelism选项有时被设置为1,以防止Nmap一次向主机发送多个探测报文,和选择--scan-delay同时使用非常有用,虽然 这个选项本身的用途已经很好。

--min-rtt-timeout <milliseconds>, --max-rtt-timeout <milliseconds>, --initial-rtt-timeout <milliseconds> (调整探测报文超时)

Nmap使用一个运行超时值来确定等待探测报文响应的时间,随后会放弃或重新 发送探测报文。Nmap基于上一个探测报文的响应时间来计算超时值,如果网络延迟比较显著和不定,这个超时值会增加几秒。具体公式在 "the section called “Scan Code and Algorithms"一节中给出。如果网络延迟显示出自己是显著的和可变的,这个超时可以增长到几秒钟。它也从一个保守的(高)水平开始,当Nmap扫描无响应的主机时,可能会保持一段时间。

指定比默认值更低的--max-rtt-timeout和--initial-rtt-timeout可以显著缩短扫描时间。这对于无ping(-Pn)扫描和对重度过滤网络的扫描尤其如此。但不要太过激进。如果你指定的值太低,特别是对不能ping通的扫描(-P0)以及具有严格过滤的网络。如果使用太小的值,使得很多探测报文超时从而重新发送,而此时可能响应消息正在发送,这使得整个扫描的时 间会增加。

如果所有的主机都在本地网络上,100毫秒(--max-rtt-timeout 100ms)是一个合理的激进值。如果涉及到路由,先用ICMP ping工具ping网络上的主机,或者用Nping等更有可能通过防火墙的自定义数据包破解器来ping。看看十个数据包左右的最大往返时间。你可能想把--initial-rtt-timeout翻倍,把--max-rtt-timeout翻三倍或四倍。不管 ping 的时间是多少,最大的 rtt 值不得小于 100ms,不能超过 1000ms 。

--min-rtt-timeout是一个很少使用的选项,当一个网络非常不可靠,甚至Nmap的默认值太过激进时,这个选项可能会有用。因为Nmap只在网络看起来可靠的时候把超时减少到最小,这种需求是不寻常的,应该作为一个bug报告给nmap-dev邮件列表。

# initial-rtt-timeout初始值为200ms,然后nmap会自动在min-rtt-timeout和max-rtt-timeout之间进行调整
nmap -sS -T4 -Pn --initial-rtt-timeout 200ms --min-rtt-timeout 150ms --max-rtt-timeout 300ms 150.1.1.1

--max-retries <numtries> (指定端口扫描探针重传的最大次数)

当Nmap没有收到端口扫描探针的响应时,可能意味着端口被过滤了。或者响应在网络上丢失了。也可能是目标主机启用了速率限制,暂时阻止了响应。所以Nmap通过重新发送初始探测来再次尝试。如果Nmap检测到网络可靠性差,它可能在放弃一个端口之前再试很多次。虽然这有利于提高准确性,但也延长了扫描时间。当性能很重要时,可以通过限制允许的重传次数来加快扫描速度。您甚至可以指定 --max-retries 0 来防止任何重传, 不过这只推荐用于非正式调查等情况, 在这些情况下, 偶尔漏掉的端口和主机是可以接受的。

默认情况下(不使用-T模板)是允许10次重传。如果一个网络看起来很可靠,而且目标主机没有速率限制,Nmap通常只做一次重传。所以大多数目标扫描甚至不会因为把--max-retries降到一个低值如3而受到影响。这样的值可以大大加快慢速(速率限制)主机的扫描速度。当Nmap提前放弃端口时,您通常会丢失一些信息,尽管这可能比让--host-timeout过期而丢失所有目标信息要好。

nmap -n -T4 -sS -p80 150.1.1.1 --max-retries=0 

--host-timeout <time> (放弃低速目标主机)

由于性能较差或不可靠的网络硬件或软件、带宽限制、严格的防火墙等原因, 一些主机需要很长的时间扫描。这些极少数的主机扫描往往占 据了大部分的扫描时间。因此,最好的办法是减少时间消耗并且忽略这些主机,使用 --host-timeout选项来说明等待的时间(毫秒)。例如,指定30m以保证Nmap不会在一个主机上浪费超过半小时。注意Nmap可能在这半个小时内同时扫描其他主机,所以并不是完全损失。超时的主机会被跳过。不会打印该主机的端口表、操作系统检测或版本检测结果。

--script-timeout <time>

虽然有些脚本以几分之一秒的速度完成,但有些脚本可能需要几个小时或更多的时间,这取决于脚本的性质、传递进来的参数、网络和应用程序的条件等等。--script-timeout选项设置了脚本执行时间的上限。任何超过该时间的脚本实例将被终止,并且不会显示任何输出。如果启用调试(-d),Nmap将报告每次超时。对于主机和服务脚本,一个脚本实例只扫描一个目标主机或端口,超时时间将在下一个实例中重置。

--scan-delay <time>; --max-scan-delay <time> (调整探测报文的时间间隔)

这个选项使Nmap在每次发送探测到给定主机之间至少等待给定的时间。这在速率限制的情况下特别有用。Solaris机器(和其他许多机器)通常每秒只响应一个ICMP报文的UDP扫描探测报文。任何超过Nmap发送的信息都是浪费的。--scan-delay为1s将使Nmap保持在这个慢的速率。Nmap试图检测速率限制并相应地调整扫描延迟,但如果您已经知道哪种速率最好,明确地指定它也无妨。

当Nmap向上调整扫描延迟以应付速率限制时,扫描会显著地减慢。--max-scan-delay选项指定Nmap允许的最大延迟。一个低的--max-scan-delay可以加速Nmap,但它是有风险的。当目标实现严格的速率限制时,把这个值设置得太低会导致浪费的数据包重传和可能错过的端口。

--scan-delay的另一个用途是逃避基于阈值的入侵检测和预防系统(IDS/IPS)。在名为 "the section called A practical example: bypassing default Snort 2.2.0 rules"一节中使用了这种技术,以击败Snort IDS中的默认端口扫描检测器。大多数其他的入侵检测系统也可以用同样的方法来击败。

--min-rate <number>; --max-rate <number> (直接控制扫描速率)

Nmap的动态定时能很好地找到一个合适的扫描速度,但有时您可能碰巧知道一个网络的合适的扫描速度,或者您可能保证扫描在一定时间内完成。然而,有时您可能碰巧知道一个网络的合适的扫描速度,或者您可能必须保证一个扫描在某一时间完成。或者您必须防止Nmap扫描过快。--min-rate和--max-rate选项是为这些情况设计的。

当给定--min-rate选项时,Nmap将尽最大努力发送数据包,速度和给定的速率一样快或更快。参数是一个正的实数,代表每秒的数据包速率。例如,指定--min-rate 300意味着Nmap将尽力保持发送速率在每秒300个包或以上。除非条件允许,指定一个最小速率并不会使Nmap速度更快。

同样,--max-rate将扫描的发送速率限制在一个给定的最大值。例如,使用--max-rate 100,在快速网络上限制每秒发送100个数据包。使用--max-rate 0.1来进行每十秒一个数据包的慢速扫描。同时使用--min-rate和--max-rate可以将速率控制在一定范围内。

这两个选项是全局的,影响整个扫描,而不是单个主机。它们只影响端口扫描和主机发现扫描。其他功能,如操作系统检测,则实现自己的定时。

有两种情况下,实际扫描速率可能会低于要求的最小值。第一种是如果最小值比Nmap可以发送的最快速率快,这取决于硬件。在这种情况下,Nmap会尽可能快地发送数据包,但要注意如此高的速率可能会导致准确性的损失。第二种情况是当Nmap没有东西可发时,例如在扫描结束时,最后一个探头已被发送,Nmap在等待它们超时或被响应。在扫描结束时或在主机组之间看到扫描速率下降是正常的。发送速率可能会暂时超过最大值,以弥补不可预测的延迟,但平均而言,速率将保持在最大值或以下。

指定最低速率时应谨慎行事。扫描速度快于网络所能支持的速度,可能会导致准确性的损失。在某些情况下,使用较快的速率会使扫描时间比使用较慢的速率长。这是因为Nmap的自适应重传算法会检测到过高的扫描速率造成的网络拥堵,并增加重传次数以提高准确性。所以即使数据包以较高的速率发送,但总体上还是发送了更多的数据包。如果需要设置总扫描时间的上限,可以用--max-retries选项来限制重传次数。

--defeat-rst-ratelimit

许多主机长期以来一直使用速率限制来减少它们发送的ICMP错误信息(如端口不可达错误)的数量。一些系统现在对它们产生的RST(复位)报文应用类似的速率限制。当Nmap调整它的速度来等待这些报文时,这会使Nmap的速度大大减慢。您可以通过指定--defeat-rst-ratelimit告诉Nmap不等待这些报文。

在SYN扫描中,无响应的结果是端口被标记为过滤,收到RST报文端口被标记关闭状态。一旦使用了此选项,Nmap如果没有等待足够长的时间等待RST响应,直接将该端口标记为过滤。当您只关心开放的端口时,这个选项是很有用的,因为区分封闭和过滤的端口不值得花费额外的时间。

nmap -sS -T4 150.1.1.1 --defeat-rst-ratelimit

--defeat-icmp-ratelimit(默认)

类似于--defeat-rst-ratelimit,--defeat-icmp-ratelimit选项以准确度换取速度,提高UDP扫描速度以对付限制ICMP错误信息的主机。因为这个选项使Nmap不会为了接收端口不可达报文而等待,一个非响应的端口将被标记为closed|filtered而不是默认的open|filtered。这样做的效果是只将实际通过UDP响应的端口视为开放。由于许多 UDP 服务并不是以这种方式响应的,因此使用这个选项比使用 --defeat-rst-ratelimit 更容易出现不准确的情况。

--nsock-engine epoll|kqueue|poll|select

强制使用指定的 nsock IO 多路复用引擎。只有基于select(2)的后备引擎才能保证在您的系统上可用。引擎以它们所利用的 IO 管理设施的名称命名。目前实现的引擎有 epoll、kqueue、poll 和 select,但并不是所有的引擎都会出现在任何平台上。使用 nmap -V 来查看哪些引擎被支持。这个我推测应该是涉及到系统的异步I/O之类的,懒得查了,先放这。

-T <Paranoid|Sneaky|Polite|Normal|Aggressive|Insane> (设置时间模板)

上述优化时间控制选项的功能很强大也很有效,但有些用户会被迷惑。此外, 往往选择合适参数的时间超过了所需优化的扫描时间。因此,Nmap提供了一些简单的 方法,使用6个时间模板,使用时采用-T选项及数字(0 - 5) 或名称。模板名称有paranoid (0)、sneaky (1)、polite (2)、normal(3)、 aggressive (4)和insane (5)。前两种模式用于IDS躲避,Polite模式降低了扫描 速度以使用更少的带宽和目标主机资源。默认模式为Normal,因此-T3 实际上是未做任何优化。Aggressive模式假设用户具有合适及可靠的网络从而加速 扫描。Insane模式假设用户具有特别快的网络或者愿意为获得速度而牺牲准确性。

用户可以根据自己的需要选择不同的模板,由Nmap负责选择实际的时间值。 模板也会针对其它的优化控制选项进行速度微调。例如,-T4 针对TCP端口禁止动态扫描延迟超过10ms,-T5对应的值为5ms。 模板可以和优化调整控制选项组合使用,但时间模板必须首先指定(-T4 放在命令行的开始),否则模板的标准值 会覆盖用户指定的值。建议在扫描可靠的网络时使用 -T4,即使 在自定义优化控制选项时也使用,从而从这些额外的较小的优化 中获益。

如果用于有足够的带宽或以太网连接,仍然建议使用-T4选项。 有些用户喜欢-T5选项,但这个过于强烈。有时用户考虑到避免使主机 崩溃或者希望更礼貌一些会采用-T2选项。他们并没意识到-T Polite选项是如何的慢,这种模式的扫描比默认方式实际上要多花10倍的时间。默认时间 选项(-T3)很少有主机崩溃和带宽问题,比较适合于谨慎的用户。不进行 版本检测比进行时间调整能更有效地解决这些问题。

虽然-T0和-T1选项可能有助于避免IDS告警,但 在进行上千个主机或端口扫描时,会显著增加时间。对于这种长时间的扫描,宁可设定确切的时间 值,而不要去依赖封装的-T0和-T1选项。

T0选项的主要影响是对于连续扫描,在一个时间只能扫描一个端口, 每个探测报文的发送间隔为5分钟。T1和T2选项比较类似, 探测报文间隔分别为15秒和0.4秒。T3是Nmap的默认选项,包含了并行扫描。 T4选项与 --max-rtt-timeout 1250ms --min-rtt-timeout 100ms --initial-rtt-timeout 500ms --max-retries 6 等价,最大TCP扫描延迟为10ms。T5等价于 --max-rtt-timeout 300ms --min-rtt-timeout 50ms --initial-rtt-timeout 250ms --max-retries 2 --host-timeout 15m --script-timeout 10m,最大TCP扫描延迟为5ms。


防火墙/IDS躲避和哄骗

许多互联网先驱者设想了一个全球开放的网络,它有一个通用的IP地址空间,允许任何两个节点之间的虚拟连接。这使得主机可以作为真正的对等体,互相服务和检索信息。人们可以从工作中访问他们所有的家庭系统,改变气候控制设置或为早起的客人开锁。这种普遍连接的愿景被地址空间短缺和安全问题所扼杀。在20世纪90年代初,组织开始部署防火墙,其明确目的是减少连接。庞大的网络被应用代理、网络地址转换和数据包过滤器与未经过滤的互联网隔离开来。不受限的信息流被严格控制的可信通信通道信息流所替代。

防火墙等网络障碍物会使网络映射变得异常困难。它不会变得更容易,因为扼制随意侦察往往是实施设备的一个关键目标。尽管如此,Nmap提供了许多功能来帮助理解这些复杂的网络,并验证过滤器是否按预期工作。它甚至支持绕过实施不良的防御的机制。了解您的网络安全态势的最好方法之一是尝试击败它。将自己置于攻击者的心态中,并针对你的网络部署本节的技术。启动FTP反弹扫描、空闲扫描、碎片攻击,或者尝试通过自己的代理服务器进行隧道。

除了限制网络活动外,公司还越来越多地使用入侵检测系统(IDS)来监控流量。由于Nmap 常用于攻击前期的扫描,因此所有主流的IDS都包含了检测Nmap扫描的规则。 现在,这些产品变形为入侵预防系统(IPS),可以主动地阻止可疑的恶意行为。不幸的是,网络管理员和IDS厂商通过分析报文来检测恶意行为是一个艰苦的工作,有耐心和技术的攻击者,在特定Nmap选项 的帮助下,常常可以不被IDS检测到。同时,管理员必须应付大量的误报结果, 正常的行为被误判而被改变或阻止。

有时,人们建议Nmap不应该提供躲闭防火墙规则或哄骗IDS的功能。他们认为,这些功能被攻击者滥用的可能性和管理员用来提高安全性的可能性一样大。 种逻辑的问题是,这些方法仍然会被攻击者使用,他们只会找到其他工具或将功能修补到Nmap中。同时,管理员发现攻击者的工作更加困难,相比较采取措施来预防执行FTP Bounce攻击的工具而言,部署先进的、打过补丁的FTP服务器更 加有效。

对于检测和颠覆防火墙和IDS系统来说,没有什么灵丹妙药(或Nmap选项)。它需要技巧和经验。教程超出了本参考指南的范围,本指南只列出了相关选项并描述了它们的作用。

-f (报文分段); --mtu (使用指定的MTU)

-f选项要求扫描时(包挺ping扫描)使用 小的IP包分段。其思路是将TCP头分段在几个包中,使得包过滤器、 IDS以及其它工具的检测更加困难。必须小心使用这个选项,有些系统在处理这些小包时存在问题,例如旧的网络嗅探器Sniffit在接收 到第一个分段时会立刻出现分段错误。该选项使用一次,Nmap在IP头后将包分成8个字节或更小。因此,一个20字节的TCP头会被分成3个 包,其中2个包分别有TCP头的8个字节,另1个包有TCP头的剩下4个字 节。当然,每个包都有一个IP头。再次使用-f可使用 16字节的分段(减少分段数量)。使用--mtu选项可 以自定义偏移的大小,使用时不需要-f,偏移量必须 是8的倍数。虽然碎片化的数据包不会被数据包过滤器和排队处理所有 IP 碎片的防火墙(如 Linux 内核中的 CONFIG_IP_ALWAYS_DEFRAG 选项)捕获,但有些网络无法承受由此带来的性能冲击,因此将其禁用。其它禁止的原因有分段包会通过不同的路由进入网络。一些源系统在内核中对传出的数据包进行碎片整理。Linux的iptables连接跟踪模块就是这样一个例子。在Wireshark等嗅探器运行时进行扫描,以确保发送的数据包是碎片化的。如果你的主机操作系统有问题,请尝试使用-send-eth选项来绕过IP层并发送原始以太网帧。

-f只支持Nmap的原始数据包功能,包括TCP和UDP端口扫描(除了TCP connect()扫描和FTP反弹扫描)和操作系统检测。像版本检测和Nmap脚本引擎这样的功能一般不支持碎片,因为它们依靠您主机的TCP协议栈与目标服务通信。

一个包8个字节
nmap -PU -f -sn 150.1.1.1 --max-retries=0 --data-string "Scan conducted by Security Ops, extension 7192"

一个包16个字节
nmap -PU -f -f -sn 150.1.1.1 --max-retries=0 --data-string "Scan conducted by Security Ops, extension 7192"

# 使用tcpdump抓包时必须在nmap运行的这个主机上抓
# 因为150.1.1.1收到分段的数据包后会整合成一个大的数据包,然后才会传递给tcpdump

-D <decoy1 ,decoy2,...> (使用诱饵隐蔽扫描)

为使诱饵扫描起作用,需要使远程主机认为是诱饵在扫描目标网络。 IDS可能会报个某个IP的5-10个端口扫描,但并不知道哪个IP在扫描以及 哪些不是诱饵。但这种方式可以通过路由跟踪、响应丢弃以及其它主动机制在解决。这是一种常用的隐藏自身IP地址的有效技术。

使用逗号分隔每个诱饵主机,也可用自己的真实IP作为诱饵,这时可使用 ME选项说明。如果在第6个位置或 更后的位置使用ME选项,一些常用端口扫描检测器(如Solar Designer's excellent scanlogd)就不会报告这个真实IP。如果不使用ME选项,Nmap 将真实IP放在一个随机的位置。你也可以使用RND来生成一个随机的、非保留的IP地址,或者使用RND:<number>来生成<number>地址。(随机IP地址的生成只支持IPv4)

注意,作为诱饵的主机须在工作状态,否则会导致目标主机被SYN洪水攻击。 如果在网络中只有一个主机在工作,那就很容易确定哪个主机在扫描。也可使用IP地址代替主机名(被诱骗的网络就不可能在DNS服务器日志中发现你查询过主机名)。

诱饵可用在初始的ping扫描(ICMP、SYN、ACK等)阶段或真正的端口扫描阶段。诱饵也可以用于远程操作系统检测(-O)。在进行版本检测或TCP连接扫描时,诱饵无效。

使用过多的诱饵没有任何价值,反而导致扫描变慢并且结果不准确。 此外,有些ISP会过滤掉你的欺骗数据包(ps:很多都会过滤这样的报文),但很多ISP根本不限制欺骗的IP数据包。

# 相当于syn Flood攻击
# 会同时放出一个源地址47.3.1.1到150.1.1.1 的以及
# nmap运行机器的ip到150.1.1.1 的ICMP报文
nmap -PP -D 47.3.1.1 -p6379 150.1.1.1 --max-retries=0

-S <IP_Address> (源地址哄骗)

在某些情况下,Nmap可能无法确定你的源地址(如果这样,Nmap会给出 提示)。此时,使用-S选项并说明所需发送包的接口IP地址。

这个标志的另一个用处是哄骗性的扫描,使得目标认为是另 一个地址在进行扫描。可以想象某一个竞争对手在不断扫描某个公司! 通常需要和 -e 选项以及-Pn选项连用。注意,您通常不会收到回复包(它们会被发送到您欺骗的IP),所以Nmap不会产生有用的报告。

nmap -n -P0 -sS -S 47.3.1.1 -e eth0 -p6379 --packet-trace 104.194.247.168
# -e eth0 指定从linux的eth0网卡发包
# -S 47.3.1.1 会模仿 47.3.1.1 向 104.194.247.168发出SYN报文
# 只有在局域网里有点用,公网会被ISP过滤
-D和-S只在局域网里有点用,公网会被ISP过滤

-e <interface> (使用指定的接口)

告诉Nmap使用哪个接口发送和接收报文,Nmap可以进行自动检测, 如果检测不出会给出提示。

--source-port <portnumber>; -g <portnumber> (源端口哄骗)

仅依赖于源端口号就信任数据流是一种常见的错误配置,这个问题非常 好理解。例如一个管理员部署了一个新的防火墙,但招来了很多用户的不满,因为 他们的应用停止工作了。可能是由于外部的UDP DNS服务器响应无法进入网络,而导致 DNS的崩溃。FTP是另一个常见的例子,在FTP传输时,远程服务器尝试和内部用 建立连接以传输数据。

对这些问题有安全解决方案,通常是应用级代理或协议分析防火墙模块。 但也存在一些不安全的方案。注意到DNS响应来自于53端口,FTP连接 来自于20端口,很多管理员会掉入一个陷阱,即允许来自于这些端口的数据进入网络。他们认为这些端口里不会有值得注意的攻击和漏洞利用。此外,管理员 或许认为这是一个短期的措施,直至他们采取更安全的方案。但他们忽视了安全的 升级。

不仅仅是工作量过多的网络管理员掉入这种陷阱,很多产品本身也会有这类 不安全的隐患,甚至是微软的产品。Windows 2000和Windows XP中包含的IPsec过滤 器也包含了一些隐含规则,允许所有来自88端口(Kerberos)的TCP和UDP数据流。另 一个常见的例子是Zone Alarm个人防火墙到2.1.25版本仍然允许源端口53(DNS)或 67(DHCP)的UDP包进入。

Nmap提供了-g和--source-port选项(它们是 等价的),用于利用上述弱点。只需要提供一个端口号,Nmap就可以从这些 端口发送数据。为使特定的操作系统正常工作,Nmap必须使用不同的端口号。 DNS请求会忽略--source-port选项,这是因为Nmap依靠系 统库来处理。大部分TCP扫描,包括SYN扫描,可以完全支持这些选项,UDP扫描同样如此。

nmap -sS -T4 -Pn -p6379 -g 80 150.1.1.1 --max-retries=0
# nmap会使用本地80端口去扫描目的机的6379端口

--data <十六进制字符串> (在发送的报文中附加自定义二进制数据)

这个选项可以让你在发送的数据包中包含二进制数据作为有效载荷。<十六进制字符串>可以用以下任何一种格式指定。0xAABBCCDDEEFF<...>, AABBCCDDEEFF<...> 或 \xAA\xBB\xCC\xDD\xEE\xFF<...>。使用的例子有--data 0xdeadbeef and --data \xCA\xFE\x09。请注意,不会进行字节大小端转换。确保你以接收者期望的字节顺序指定信息。

nmap -sU -n -P0 -p80 150.1.1.1 --max-retries=0 --data 0x5363616E
# 发送一个"Scan"字符串到150.1.1.1主机

防火墙IDS躲避和哄骗1.png

nmap -sU -n -P0 -p80 150.1.1.1 --max-retries=0 --data 0x0053
# 发送一个"\x00S"字符串到150.1.1.1主机

防火墙IDS躲避和哄骗2.png

--data-string <string> (在发送的数据包中添加自定义字符串)

这个选项可以让你在发送的数据包中包含一个常规的字符串作为有效载荷。<string>可以包含任何字符串。然而,请注意,一些字符可能取决于你的系统的本地语言,接收器可能不会看到相同的信息。另外,请确保你用双引号将字符串括起来,并在shell中转义任何特殊字符。例子。--data-string "Scan conducted by Security Ops, extension 7192" 或者 --data-string "Ph34r my l33t skills". 请记住,没有人可能真正看到这个选项留下的任何字符串信息,除非他们使用嗅探器或自定义IDS规则仔细监控网络。

nmap -PU -f -f -sn 150.1.1.1 --max-retries=0 --data-string "Scan conducted by Security Ops, extension 7192"

--data-length <number> (发送报文时 附加随机数据)

正常情况下,Nmap发送最少的报文,只含一个包头。因此TCP包通常 是40字节,ICMP ECHO请求只有28字节。这个选项告诉Nmap在发送的报文上 附加指定数量的随机字节。操作系统检测(-O)包不受影响, 但大部分ping和端口扫描包受影响,这会使处理变慢,但对扫描的影响较小。

--ip-options <S|R [route]|L [route]|T|U ... >; --ip-options <hex string> (Send packets with specified ip options)

IP协议提供了几个选项,可以放在包头中。与无处不在的TCP选项不同,由于实用性和安全问题,IP选项很少出现。事实上,许多互联网路由器会阻止最危险的选项,如源路由。然而,在某些情况下,选项对于确定和操纵通往目标机器的网络路由仍然是有用的。例如,即使在传统的跟踪路由方式失败时,你也可以使用记录路由选项来确定通往目标机的路径。或者,如果你的数据包被某个防火墙丢弃,你可以使用严格或宽松的源路由选项来指定不同的路由从而绕过防火墙。

指定IP选项的最强大的方法是简单地传递值作为--ip-options的参数。在每个十六进制数字前加上x,然后再加上两个数字。你可以在某些字符后面加上星号,然后再加上你希望重复的次数。例如, x01x07x04x00*36x01是一个包含36个NUL字节的十六进制字符串。

Nmap还提供了一个指定选项的快捷机制。简单地通过字母R、T或U分别请求记录-路由、记录-时间戳或两个选项一起使用。松散或严格的源路由可以用L或S指定,后面是空格,然后是一个以空格分隔的IP地址列表。

如果你想在发送和接收的数据包中看到这些选项,可以指定 --packet-trace。更多关于使用Nmap的IP选项的信息和例子,见http://seclists.org/nmap-dev/2006/q3/52

--ttl <value> (设置IP time-to-live域)

设置IPv4报文的time-to-live域为指定的值。

--randomize-hosts (对目标主机的顺序随机排列)

告诉Nmap在扫描主机前对每个组中的主机随机排列,每一组最多可达16384个主机。这会使得扫描针对不同的网络监控系统来说变得不是很 明显,特别是配合值较小的时间选项时更有效。如果需要对一个较大 的组进行随机排列,需要增大nmap.h文件中 PING-GROUP-SZ的值,并重新编译。另一种方法是使用列表扫描 (-sL -n -oN <filename>),产生目标IP的列表, 使用Perl脚本进行随机化,然后使用-iL提供给Nmap。

--spoof-mac <mac address,prefix,or vendor name> (MAC地址哄骗)

要求Nmap在发送原以太网帧时使用指定的MAC地址,这个选项隐含了--send-eth选项,以保证Nmap真正发送以太网包。MAC地址有几 种格式。如果简单地使用字符串"0",Nmap选择一个完全随机的MAC 地址。如果给定的字符品是一个16进制偶数(使用:分隔),Nmap将使用这个MAC地址。 如果是小于12的16进制数字,Nmap会随机填充剩下的6个字节。如果参数不是0或16进 制字符串,Nmap将通过nmap-mac-prefixes查找 厂商的名称(大小写区分),如果找到匹配,Nmap将使用厂商的OUI(3字节前缀),然后 随机填充剩余的3个节字。正确的--spoof-mac参数有:Apple、 0、01:02:03:04:05:06 、deadbeefcafe、 0020F2 和Cisco。

nmap -sS -T4 -Pn -p6379 --spoof-mac  Apple 150.1.1.1 --max-retries=0
nmap -sS -T4 -Pn -p6379 --spoof-mac Cisco 150.1.1.1 --max-retries=0
nmap -sS -T4 -Pn -p6379 --spoof-mac 0 150.1.1.1 --max-retries=0

#  要在nmap运行的机器上抓包,应该也是有过滤。

--proxies <Comma-separated list of proxy URLs>

要求Nmap通过提供的一个或多个HTTP或SOCKS4代理链与最终目标建立TCP连接。代理可以帮助隐藏扫描的真正来源或逃避某些防火墙的限制,但它们会因为增加延迟而影响扫描性能。用户可能需要相应调整Nmap超时和其他扫描参数。特别是,较低的--max-parallelism可能有帮助,因为一些代理拒绝处理与Nmap默认打开的并发连接数一样多的连接。
这个选项接收一个代理列表作为参数,用URL表示,格式是 proto://host:port。使用逗号来分隔链中的节点URL。目前还不支持认证。有效的协议是HTTP和SOCKS4。

警告:此功能仍在开发中,有一定的局限性。它是在nsock库中实现的,因此对扫描的ping、端口扫描和操作系统发现阶段没有影响。到目前为止,只有NSE和版本扫描受益于这个选项--其他功能可能会泄露你的真实地址。目前还不支持SSL连接,也不支持代理端DNS解析(主机名总是由Nmap解析)。

--badsum (Send packets with bogus TCP/UDP checksums)

要求Nmap对发送到目标主机的数据包使用无效的TCP、UDP或SCTP校验和。由于几乎所有的主机IP栈都会正确地丢弃这些数据包,任何收到的响应很可能来自于没有去验证校验和的防火墙或IDS。有些防火墙不验证校验和直接假装返回RST,所以这种方法可以用来探测防火墙的存在。有关该技术的更多细节,请参见https://nmap.org/p60-12.html

# 仅仅适用于那些不管收到什么一律返回RST报文的防火墙
# 有些防火墙直接丢弃报文就不能拿来探测防火墙了
nmap -sS -p 80 -Pn --badsum 150.1.1.1

--adler32 (Use deprecated Adler32 instead of CRC32C for SCTP checksums)

要求Nmap使用过时的Adler32算法来计算SCTP校验和。如果没有给定--adler32,则使用CRC-32C(Castagnoli)。RFC 2960最初定义Adler32作为SCTP的校验和算法;RFC 4960后来重新定义SCTP校验和使用CRC-32C。当前的SCTP实现应该使用CRC-32C,但为了从旧的、传统的SCTP实现中获得响应,可能最好使用Adler32。


输出

任何安全工具只有在输出结果时才是有价值的,如果没有通过组织和 易于理解的方式来表达,复杂的测试和算法几乎没有意义。Nmap提供了一些 方式供用户和其它软件使用,实际上,没有一种方式可以使所有人满意。 因此Nmap提供了一些格式,包含了方便直接查看的交互方式和方便软件处理 的XML格式。

除了提供输出格式外,Nmap还提供了选项来控制输出的细节以及调试 信息。输出内容可发送给标准输出或命名文件,可以追加或覆盖。输出文件还可 被用于继续中断的扫描。

Nmap提供5种不同的输出格式。默认的方式是interactive output, 发送给标准输出(stdout)。normal output方式类似于 interactive,但显示较少的运行时间信息 和告警信息,因为它是在扫描完成后分析的。

XML输出是最重要的输出类型,可被转换成HTML,对于程序处理非常方便, 如用于Nmap图形用户接口或导入数据库。

另两种输出类型比较简单,grepable output格式,在一行中包含目标主机最多的信息;sCRiPt KiDDi3 0utPUt 格式,用于考虑自己的用户 |<-r4d。

nteractive output是默认方式,没有相应的命令行选项,其它四种格式选项 使用相同的语法,采用一个参数,即存放结果的文件名。多种格式可同时 使用,但一种格式只能使用一次。例如,在标准输出用于查看的同时,可将结果保存到XML文件用于程序分析,这时可以使用选项-oX myscan.xml -oN myscan.nmap。 为便于描述的简化,本章使用类似于myscan.xml的简单文件名, 建议采用更具有描述性的文件名。文件名的选择与个人喜好有关,建议增加 扫描日期以及一到两个单词来描述,并放置于一个目录中。

在将结果输出到文件的同时,Nmap仍将结果发送给标准输出。例如, 命令nmap -oX myscan.xml target将 输出XML至myscan.xml,并在stdout 上打印相同的交互式结果。可以 使用连字符作为选项来改变,这使得Nmap禁止交互式输出,而是将结果打印到 所指定的标准输出流中。因此,命令nmap -oX - target 只输出结果到xml。严重错误仍然是输出到标准错误流stderr中。

nmap -sS -T4 -p80-85 -oX - oxx.txt 150.1.1.1 --max-retries=0

与其它Nmap参数不同,日志文件选项标志(如-oX)和文件名或连字符之间的空格是必须的。如果您省略这些标志并给出-oG-或-oXscan.xml这样的参数,Nmap的一个向后兼容特性将导致创建分别命名为G-和Xscan.xml的普通格式输出文件。
Nmap还提供了控制扫描细节以及输出文件的添加或覆盖的选项,这些选项 如下所述。

所有这些参数都支持文件名中类似strftime的转换。%H、%M、%S、%m、%d、%y和%Y都和strftime中的参数完全一样。%T 与 %H%M%S 相同, %R 与 %H%M 相同, %D 与 %m%d%y 相同。在任何其他字符后面的%只是产生该字符 (%% 给你一个百分号)。所以-oX 'scan-%T-%D.xml'将使用一个XML文件,文件名是scan-144840-121307.xml。

nmap -sS -T4 -p80-85 150.1.1.1 --max-retries=0 -oX "%Y-%m-%d.xml"
# 输出一个类似"2020-11-04.xml"的文件

Nmap输出格式

-oN <filespec> (normal output)

要求将标准输出直接写入指定 的文件。如上所述,这个格式与交互式输出 略有不同。

nmap -sS -T4 -p80-85 150.1.1.1 --max-retries=0 -oN onn.txt

Nmap输出格式1.png

-oX <filespec> (XML output)

要求XML输出直接写入指定 的文件。Nmap包含了一个文档类型定义(DTD),使XML解析器有效地 进行XML输出。这主要是为了程序应用,同时也可以协助人工解释 Nmap的XML输出。DTD定义了合法的格式元素,列举可使用的属性和 值。最新的版本可在 https://nmap.org/data/nmap.dtd获取

XML提供了可供软件解析的稳定格式输出,主要的计算机 语言都提供了免费的XML解析器,如C/C++,Perl,Python和Java。 针对这些语言有一些捆绑代码用于处理Nmap的输出和特定的执行程序。 例如perl CPAN中的Nmap::ScannerNmap::Parser。 对几乎所有与Nmap有接口的主要应用来说,XML是首选的格式。

XML输出引用了一个XSL样式表,用于格式化输出结果,类似于 HTML。最方便的方法是将XML输出加载到一个Web浏览器,如Firefox 或IE。由于nmap.xsl文件的绝对 路径,因此通常只能在运行了Nmap的机器上工作(或类似配置的机器)。 类似于任何支持Web机器的HTML文件,--stylesheet 选项可用于建立可移植的XML文件。

nmap -sS -T4 -p80-85 150.1.1.1 --max-retries=0 -oX oxx.txt

Nmap输出格式2.png

-oS <filespec> (ScRipT KIdd|3 oUTpuT)

脚本小子输出类似于交互工具输出,这是一个事后处理,适合于 'l33t HaXXorZ, 由于原来全都是大写的Nmap输出。这个选项和脚本小子开了玩笑,看上去似乎是为了 “帮助他们”。

nmap -sS -T4 -p80-85 150.1.1.1 --max-retries=0 -oS oss.txt

Nmap输出格式3.png

-oG <filespec> (grepable output)

这种方式最后介绍,因为不建议使用。XML输格式很强大,便于有经验 的用户使用。XML是一种标准,由许多解析器构成,而Grep输届更简化。XML 是可扩展的,以支持新发布的Nmap特点。使用Grep输出的目的是忽略这些 特点,因为没有足够的空间。

然面,Grep输出仍然很常使用。它是一种简单格式,每行一个主机,可以 通过UNIX工具(如grep、awk、cut、sed、diff)和Perl方便地查找和分解。常可 用于在命令行上进行一次性测式。查找ssh端口打开或运行Sloaris的主机,只需 要一个简单的grep主机说明,使用通道并通过awk或cut命令打印所需的域。

Grep输出可以包含注释(每行由#号开始)。每行由6个标记的域组成,由制表符及 冒号分隔。这些域有主机,端口, 协议,忽略状态, 操作系统,序列号, IPID和状态。

这些域中最重要的是Ports,它提供 了所关注的端口的细节,端口项由逗号分隔。每个端口项代表一个所关注的端口, 每个子域由/分隔。这些子域有:端口号, 状态,协议, 拥有者,服务, SunRPCinfo和版本信息。

对于XML输出,本手册无法列举所有的格式,有关Nmap Grep输出的更详细信息可 查阅http://www.unspecific.com/nmap-oG-output

nmap -sS -T4 -p80-85 150.1.1.1 --max-retries=0 -oG oGG.txt

Nmap输出格式4.png

-oA <basename> (输出至所有格式)

为使用方便,利用-oA <basename>选项 可将扫描结果以标准格式、XML格式和Grep格式一次性输出。分别存放在 <basename>.nmap,<basename>.xml和 <basename>.gnmap文件中。也可以在文件名前 指定目录名,如在UNIX中,使用~/nmaplogs/foocorp/, 在Window中,使用c:hackingsco on Windows。

细节和调试选项

-v (提高输出信息的详细度)

通过提高详细度,Nmap可以输出扫描过程的更多信息。 输出发现的打开端口,若Nmap认为扫描需要更多时间会显示估计 的结束时间。这个选项使用两次,会提供更详细的信息。这个选项使用两次以上不起作用。

大部分的变化仅影响交互式输出,也有一些影响标准和脚本小子输出。其它输出类型由机器处理,此时Nmap默认提供详细的信息,不需要人工干预。然而,其它模式也会有一些变化,省略一些 细节可以减小输出大小。例如,Grep输出中的注释行提供所有扫描 端口列表,但由于这些信息过长,因此只能在细节模式中输出。

-d [level] (提高或设置调试级别)

当详细模式也不能为用户提供足够的数据时,使用调试可以得到更 多的信息。使用细节选项(-v)时,可启用命令行参数 (-d),多次使用可提高调试级别。也可在-d 后面使用参数设置调试级别。例如,-d9设定级别9。这是 最高的级别,将会产生上千行的输出,除非只对很少的端口和目标进行简单扫描。

如果Nmap因为Bug而挂起或者对Nmap的工作及原理有疑问,调试输出 非常有效。主要是开发人员用这个选项,调试行不具备自我解释的特点。 例如,Timeoutvals: srtt: -1 rttvar: -1 to: 1000000 delta 14987 ==> srtt: 14987 rttvar: 14987 to: 100000。如果对某行输出不明白, 可以忽略、查看源代码或向开发列表(nmap-dev)求助。有些输出行会有自 我解释的特点,但随着调试级别的升高,会越来越含糊。

--reason (Host and port state reasons)

显示每个端口被设置为特定状态的原因,以及每个主机上升或下降的原因。这个选项显示决定端口或主机状态的数据包的类型。例如,来自一个关闭端口的RST报文或来自一个活着的主机的回波回复。Nmap能提供的信息由扫描或ping的类型决定。SYN扫描和SYN ping(-sS和-PS)非常详细,但是TCP连接扫描(-sT)受限于连接系统调用的实现。这个功能会被调试选项(-d)自动启用,即使没有指定这个选项,结果也会存储在XML日志文件中。

--stats-every <time> (Print periodic timing stats)

在每次间隔<time>后定期打印一条定时状态信息。时间是 "定时和性能 "一节中描述的那种规格;因此,例如,使用-stats-every 10s来获得每10秒的状态更新。更新会被打印到交互式输出(屏幕)和 XML 输出。

--packet-trace (跟踪发送和接收的报文)

要求Nmap打印发送和接收的每个报文的摘要,通常用于 调试,有助于新用户更好地理解Nmap的真正工作。为避免输出过 多的行,可以限制扫描的端口数,如-p20-30。 如果只需进行版本检测,使用--version-trace。

--open (Show only open (or possibly open) ports)

有时您只关心开放的端口,而不希望结果被封闭的、过滤的、封闭的|过滤的端口所杂乱。输出的自定义通常是在扫描后使用grep、awk和Perl等工具来完成的,但由于请求过多,所以增加了这个功能。指定--open可以只看到至少有一个open、open|filtered 或者unfiltered 的主机,并且只看到这些状态的端口。这三种状态和通常的状态一样,这意味着如果open|filtered和unfiltered的数量太多,它们可能会被压缩成计数。

从Nmap 7.40开始,--open选项意味着--defeat-rst-ratelimit,因为这个选项只影响closed的和filtered的端口,它们被--open隐藏了。

--iflist (列举接口和路由)

输出Nmap检测到的接口列表和系统路由,用于调试路由 问题或设备描述失误(如Nmap把PPP连接当作以太网对待)。

其它输出选项

--append-output (在输出文件中添加)

当使用文件作为输出格式,如-oX或-oN, 默认该文件被覆盖。如果希望文件保留现有内容,将结果添加在现 有文件后面,使用--append-output选项。所有指 定的输出文件都被添加。但对于XML(-oX)扫描输出 文件无效,无法正常解析,需要手工修改。

--resume <filename> (继续中断的扫描)

一些扩展的Nmap运行需要很长的时间 -- 以天计算,这类扫描 往往不会结束。可以进行一些限制,禁止Nmap在工作时间运行,导致 网络中断、运行Nmap的主机计划或非计划地重启、或者Nmap自己中断。 运行Nmap的管理员可以因其它原因取消运行,按下ctrl-C 即可。从头开始启动扫描可能令人不快,幸运的是,如果标准扫描 (-oN)或Grep扫描(-oG)日志 被保留,用户可以要求Nmap恢复终止的扫描,只需要简单地使用选项 --resume并说明标准/Grep扫描输出文件,不允许 使用其它参数,Nmap会解析输出文件并使用原来的格式输出。使用方式 如nmap --resume <logfilename>。 Nmap将把新地结果添加到文件中,这种方式不支持XML输出格式,原因是 将两次运行结果合并至一个XML文件比较困难。

--stylesheet <path or URL> (设置XSL样式表,转换XML输出)

Nmap提从了XSL样式表nmap.xsl,用于查看 或转换XML输出至HTML。XML输出包含了一个xml-stylesheet, 直接指向nmap.xml文件, 该文件由Nmap安装(或位于Windows当前工作目录)。在Web浏览器 中打开Nmap的XML输出时,将会在文件系统中寻找nmap.xsl文件, 并使用它输出结果。如果希望使用不同的样式表,将它作为 --stylesheet的参数,必段指明完整的路 径或URL,常见的调用方式是--stylesheet https://nmap.org/data/nmap.xsl。 这告诉浏览器从Insecire.Org中加载最新的样式表。这使得 没安装Nmap(和nmap.xsl) 的机器中可以方便地查看结果。因此,URL更方便使用,本地文件系统 的nmap.xsl用于默认方式。

--webxml (Load stylesheet from Nmap.Org)

--webxml是--stylesheet https://nmap.org/svn/docs/nmap.xsl的简写

--no-stylesheet (忽略XML声明的XSL样式表)

使用该选项禁止Nmap的XML输出关联任何XSL样式表。 xml-stylesheet指示被忽略。


其他选项

节描述一些重要的(和并不重要)的选项,这些选项 不适合其它任何地方。

-6 (启用IPv6扫描)

从2002年起,Nmap提供对IPv6的一些主要特征的支持。ping扫描(TCP-only)、 连接扫描以及版本检测都支持IPv6。除增加-6选项外, 其它命令语法相同。当然,必须使用IPv6地址来替换主机名,如 3ffe:7501:4819:2000:210:f3ff:fe03:14d0。 除“所关注的端口”行的地址部分为IPv6地址。

虽然IPv6还没有完全风靡全球,但它在一些国家(通常是亚洲国家)得到了大量的使用,而且大多数现代操作系统都支持它。要在IPv6下使用Nmap,扫描的源和目标都必须配置为IPv6。如果您的ISP(像大多数ISP一样)没有给您分配IPv6地址,免费的隧道代理广泛存在,并且可以和Nmap一起使用。我使用免费的IPv6隧道代理服务,网址是http://www.tunnelbroker.net。其他的隧道代理服务可以在维基百科上找到。6to4隧道是另一种流行的免费方法。

在Windows上,raw-socket IPv6扫描只支持在以太网设备上(不是隧道),而且只在Windows Vista和更高版本上。在其他情况下,请使用--unprivileged选项。

-A (激烈扫描模式选项)

这个选项启用额外的高级和高强度选项,目前还未确定代表 的内容。目前,这个选项启用了操作系统检测(-O) 和版本扫描(-sV),以后会增加更多的功能。 目的是启用一个全面的扫描选项集合,不需要用户记忆大量的 选项。这个选项仅仅启用功能,不包含用于可能所需要的 时间选项(如-T4)或细节选项(-v)。

--datadir <directoryname> (说明用户Nmap数据文件位置)

Nmap在运行时从文件中获得特殊的数据,这些文件有 nmap-service-probes, nmap-services, nmap-protocols, nmap-rpc, nmap-mac-prefixes和 nmap-os-fingerprints。

Nmap查找文件的路径

首先在--datadir选项说明的目录中查找这些文件
$NMAPDIR
~/.nmap (仅linux上)
<APPDATA>\nmap (仅在Windows上)
包含nmap 可执行文件的目录
包含nmap 可执行文件的目录,后跟../share/nmap(仅linux上)
NMAPDATADIR (在linux上)
当前目录。

--servicedb <services file> (Specify custom services file)

要求Nmap使用指定的服务文件而不是Nmap自带的nmap-services数据文件。使用这个选项也会导致使用快速扫描(-F),请看--datadir对Nmap数据文件更多信息的描述。参见--datadir的描述以获得更多关于Nmap数据文件的信息。

--versiondb <service probes file> (Specify custom service probes file)

要求Nmap使用指定的服务探测文件,而不是Nmap自带的nmap-service-probes数据文件。关于Nmap数据文件的更多信息,请看--datadir的描述。

--send-eth (使用原以太网帧发送)

要求Nmap在以太网(数据链路)层而不是IP(网络层)发送 报文。默认方式下,Nmap选择最适合其运行平台的方式,原套接 字(IP层)是UNIX主机最有效的方式,而以太网帧最适合Windows操作 系统,因为Microsoft禁用了原套接字支持。在UNIX中,如果没有其 它选择(如无以太网连接),不管是否有该选项,Nmap都使用原IP包。

--send-ip (在原IP层发送)

要求Nmap通过原IP套接字发送报文,而不是低层的以 太网帧。这是--send-eth选项的补充。

--privileged (假定用户具有全部权限)

指示Nmap简单地假设它有足够的特权来执行原始套接字发送、数据包嗅探和类似的操作,这些操作在Unix系统上通常需要root权限。默认情况下,如果请求这些操作但geteuid不为零,Nmap就会退出。--privileged对于Linux内核功能和类似的系统很有用,这些系统可能被配置为允许非特权用户执行原始包扫描。请确保在任何需要特权的选项(SYN扫描、OS检测等)的标志之前提供这个选项标志。NMAP_PRIVILEGED 环境变量 设置等价于--privileged选项。

--release-memory (退出前释放内存)

此选项仅对内存泄漏调试有用。这会导致Nmap在退出之前释放分配的内存,以便更容易发现实际的内存泄漏。通常Nmap会跳过此操作,因为OS在进程终止时仍会这样做。

-V; --version (打印版本信息)

打印Nmap版本号并退出。

-h; --help (打印帮助摘要面)

打印一个短的帮助屏幕,列出大部分常用的 命令选项,这个功能与不带参数运行Nmap是相同的。

绕过防火墙

详情在:https://nmap.org/book/firewalls.html

An attacker can avoid flagging this by omitting the -O flag. If he really wishes to do OS detection, that single test can be commented out in osscan2.cc. The OS detection will still be quite accurate, but the IDS alert will not flag.大概意思就是不能使用OS版本检测。https://nmap.org/book/subvert-ids.html

备注

关于nmap更详细的使用可以在https://nmap.org/book/toc.html中查看