你真的明白Nmap的参数在干什么吗?-Nmap-Tutorial-2024
一、Nmap介绍
Nmap (“Network Mapper(网络映射器)”) 是一款开放源代码的 网络探测和安全审核的工具。
参考文章:Nmap参考指南(Man Page)
一个非常好的消息是Nmap有官网,并且有非常详细的使用手册,以及中文译本,这对大家的学习来说简直如虎添翼,它们自己也说到很多开源软件的说明书做的一团糟,于是它们准备改变这个环境。

nmap被用到许多电影中,《黑客帝国之重装上阵》,《我是谁:没有绝对安全的系统》,这都是我大爱的影片,可见nmap知名度之高。

最棒的是,nmap为我们提供了一个在线的靶场供我们测试nmap的功能,免去了自己搭建靶场之辛劳,这简直是开源软件的神,让我们高举双手,大喊,神!!!
网站地址:Go ahead and ScanMe! (nmap.org)

废话不多说,这些都能在官网看到,我们直接开始学习吧。
二、Nmap使用
1、本地Centos7环境下的实验
(一)、靶场环境
系统环境信息。
系统版本:"CentOS Linux release 7.6.1810 (Core)" #cat /etc/redhat-release
IP地址:"192.168.225.60" #ifconfig
Lampp版本:"XAMPP for Linux 5.6.40-1" #/opt/lampp/lampp status
服务器上开放的端口如下。
如何查看linux上端口的开放情况参考这篇文章:检查 Linux 上开放端口的 5 种简单方法 (linux-console.net)
使用的命令如下。
ss -tuln
#-t 显示 TCP 端口。
#-u 显示 UDP 端口。
#-l 显示监听端口。如果您想查看所有端口(无论其状态如何),请将其替换为a。
#-n 显示端口的数值,而不是解析为服务名称。例如,显示端口 21 而不是 FTP,即该端口上运行的服务。
可以看到我们就是开放了这些服务。

使用netstat -tulnp可以看到对应的进程号和服务名。

以下是在这个网络中存活的主机,一台kali,一台centos靶机(192.168.225.60),一台我的宿主机(192.168.225.1)
(二)、网段扫描
我们按照实战的思路来捋一捋,当我们来到一个局域网环境时,我们可能首先会想着这个网段里有多少台主机存活。
所以我们需要对整个网段进行扫描。
于是我们使用以下命令来扫描一个网段。我们使用-PR选项,也就是arp扫描,根据我学的知识,arp是最可靠的,因为使用ping可能会被防火墙阻挡。
nmap -PR 192.168.225.0/24 #nmap -PR {目标网段/子网掩码位数}
扫描结果如下,我们发现除了网络中存在的其他两台主机,还多了225.2和225.254,这两个可能是vmware的虚拟网关或者dns啥的,暂不理会,起码说明我们的扫描是很成功的,比我们自己知道的信息还多。

我们注意到在nmap中的一些描述如,open,filtered之类的,以下是官方文档的说明。
具体参考这篇文章:端口扫描基础 | Nmap参考指南(Man Page)
Nmap输出的是扫描目标的列表,以及每个目标的补充信息,至于是哪些信息则依赖于所使用的选项。 “所感兴趣的端口表格”是其中的关键。
那张表列出端口号,协议,服务名称和状态。状态可能是 open(开放的),filtered(被过滤的), closed(关闭的),或者unfiltered(未被过滤的)。
Open(开放的)意味着目标机器上的应用程序正在该端口监听连接/报文。
filtered(被过滤的) 意味着防火墙,过滤器或者其它网络障碍阻止了该端口被访问,Nmap无法得知 它是 open(开放的) 还是 closed(关闭的)。
closed(关闭的) 端口没有应用程序在它上面监听,但是他们随时可能开放。
当端口对Nmap的探测做出响应,但是Nmap无法确定它们是关闭还是开放时,这些端口就被认为是 unfiltered(未被过滤的) 如果Nmap报告状态组合 open|filtered 和 closed|filtered时,那说明Nmap无法确定该端口处于两个状态中的哪一个状态。
当要求进行版本探测时,端口表也可以包含软件的版本信息。当要求进行IP协议扫描时 (-sO),Nmap提供关于所支持的IP协议而不是正在监听的端口的信息。
那么nmap是如何完成这个工作的呢?
首先它向网段内所有主机发送arp报文,如果有arp的回复,那么证明该主机存在,如果有同学不懂什么是arp,可以移步小林coding的网络原理讲解学习,他讲的还不错。

而后又向有回应的主机上的高频端口发送syn请求。
高频端口指的就是常用的端口,比如53-dns,80-http,443-https,3306-mysql这些。
如果没有回应,就认为没开放这个端口,如果有第二次握手包,像下面的80端口就有回应,那么nmap就会发送一个rst来断开连接,RST:该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接。
有关的网络资料在这里参考:4.1 TCP 三次握手与四次挥手面试题 | 小林coding (xiaolincoding.com)
笔者在这里就不深挖了,因为和我们这个nmap使用没太大关系了。

包括被发现的22和3306号端口


或者我们直接在wireshark过滤器中寻找被rst的流量,我们就可以发现这些端口和nmap告诉我们的端口是相同的。

(三)、主机扫描
当我们确定这个局域网内存在哪些主机之后,下一步我们需要确认这个主机开放了哪些端口,以及服务。
之前的网段扫描或许以及告诉了我们一些信息,但这还不够,我们想要扫描出这台主机的所有信息。引用霸总们的一句话:“三分钟,我要它所有的信息!”
最简单的,我们使用下面的命令得到下面的信息。
┌──(root㉿kali)-[/home/kali]
└─# nmap 192.168.225.60
Starting Nmap 7.94 ( https://nmap.org ) at 2024-06-04 22:36 EDT
Nmap scan report for 192.168.225.60
Host is up (0.00059s latency).
Not shown: 983 filtered tcp ports (no-response), 14 filtered tcp ports (host-prohibited)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
3306/tcp open mysql
MAC Address: 00:0C:29:9D:6C:4C (VMware)
Nmap done: 1 IP address (1 host up) scanned in 8.70 seconds
我们来看看在流量层面它是怎么做的。
首先它还是发了一个arp报文来确认225.60是否存在。

之后开始向各个高频端口发送syn请求,有相应的是青绿色,没有响应的就是黑色,有些被拦截的端口回回应一个icmp报文,说管理员禁止了。

我们使用过滤器查看所有被禁止的icmp回包,发现他的数量和nmap告诉我们被filtered的数量是相同的。
Not shown: 983 filtered tcp ports (no-response), 14 filtered tcp ports (host-prohibited)

什么参数都不带的话,nmap默认只扫描一千个端口,按照上面的信息显示,有983个包无回应,还有14个包被防火墙拦截,剩下三个包就是扫描出来的结果。
但是我们的主机上还监听了21,25,443这些端口,为什么这些端口都没有回应呢?笔者暂时没有找到答案,但是这些服务,确实笔者没有开过,我也不知道为什么它就监听了。443我使用https://192.168.225.60是访问不了的,可能就是没有开吧,但是为什么系统会在监听呢?21和25号端口我更是没有使用过,不是很明白。

(四)、全端口扫描
有时我们的服务器会开放一些奇怪的端口,所以我们要确保扫描到每一个端口,使用-p-参数会扫描该主机从1-65535的全端口。
nmap 192.168.225.60 -p-
我们随便抽查一个18885的端口,可以看到它是有发送了的。

(五)、主机发现和端口扫描
在刚刚看nmap的说明书时,我有些疑惑,就是-PA和-sA有什么区别?它们都是在发送ack请求,但是后来我捋过来了,主机发现就是
当我使用-PS来进行主机发现,它还是会先发送arp报文来探测网段内的存货主机,而后发送syn请求探测每个存活主机开放的高危端口。


当我使用-PA来进行主机发现时,发现流量和上面的完全一样,我意识到一些不对,后面在网上翻阅资料时好像说这是旧版本的参数了,我紧忙查看我的版本,原来是7.94。

而说明书呢,只有4.50,好吧,怪我不够细心。

好的,我们在新的数据手册中找到了相关的描述,让我们重新来解释一下。
(1)、主机发现
[1]、局域网环境
首先是在局域网环境下的主机发现,无论如何nmap都会默认使用arp来完成这项工作。无论你使用-PS还是-PA,在主机发现时发送的都是arp包,如果你实在想要发送ip请求包,可以把命令写成这样。

即便这样,效果也只是在arp报文有回应的基础上多发送一个ack包,而不是给每个ip都发送这个请求。

[2]、外网环境
如果我们将扫描范围锁定在外网,那么我们的参数就会显示出它的作用。
比如我们的参数是这样设置的。
sudo nmap -PA 47.113.106.111-113 #-PA 发送ack请求包 47.113.106.111-113 指定了三台主机
sudo namp -PA 47.113.106.111,112,113 #这也和前面的一样效果

流量方面是这样的,先向三台主机的80端口发送ack包,接收到它们的rst包之后,就确认主机存活,而后再对各个主机的高危端口进行syn扫描,最后得出这样的结论。
那么为什么要分为syn请求和ack请求呢,说法是有些防火墙会屏蔽syn或ack,所以设置不同的请求来让结果更准确,不过这里我没有用防火墙验证。


很多时候我们不需要对所有主机进行端口扫描,只需要判断它是否存活,我们使用-sn参数,以下是对sn参数的解释。
-sn(不扫描端口)
该选项告诉Nmap在发现主机后不要进行端口扫描,而只打印响应主机发现探测的可用主机。这通常被称为“ping扫描”,但是您也可以请求运行traceroute和NSE主机脚本。默认情况下,这比列表扫描更具侵入性,并且通常可以用于相同的目的。它允许在不引起太多注意的情况下对目标网络进行轻型侦察。对于攻击者来说,知道有多少台主机在运行,比通过逐个IP和主机名的列表扫描提供的列表更有价值。
系统管理员经常发现这个选项也很有价值。它可以很容易地用于计算网络上可用的计算机或监视服务器的可用性。这通常被称为ping扫描,并且比ping广播地址更可靠,因为许多主机不回复广播查询。
使用-sn完成的默认主机发现包括ICMP回显请求、到端口443的TCP SYN、到端口80的TCP ACK和默认的ICMP时间戳请求。当由非特权用户执行时,只有SYN包被发送(使用connect调用)到目标的端口80和443。当特权用户试图扫描本地以太网上的目标时,除非指定了——send-ip,否则将使用ARP请求。可以将-sn选项与任何发现探测类型(-P*选项)结合使用,以获得更大的灵活性。如果使用了这些探测类型和端口号选项中的任何一个,则会覆盖默认探测。当运行Nmap的源主机和目标网络之间存在严格的防火墙时,建议使用这些高级技术。否则,当防火墙丢弃探测或它们的响应时,可能会错过主机。
在以前的Nmap版本中,-sn被称为-sP。
它的命令执行结果是这样的,这个命令仅仅告诉我们这些主机是否存活,而没有进一步扫描它们的端口。

它的流量是这样的,像它解释的一样,发送icmp,443,80的tcp,以及icmp时间戳请求。

我们可以将-sn结合-PA或-PS来替换它默认发送的请求,以此来绕过一些防火墙检测。
下面这个命令会同时向目标主机的80发送syn请求以及目标主机的88来发送ack请求,并且只做探测,不做端口扫描。


(2)、端口扫描
那么-PA和-sA的区到底是什么呢?
我们使用下面命令来测试。

在主机发现阶段,也就是确认这个ip是否存活,nmap分别发送了syn->80的包和ack->88的包来进行探测,这就是-PA88和-PS80的作用。

而在端口扫描阶段,由于我们指定了-sA,所以发送的是ack请求来测试每个端口是否开放,否则默认状态下应该是使用syn请求来扫描的,这点我们在之前见到过。

我们本打算使用多种方式来进行端口扫描的,但是好像不行。

下面这条命令禁用主机发现并且使用ack请求来探测端口是否开放,不过这条命令让我们的扫描什么结果也没有,不知道是不是因为使用ack来探测端口的原因。

禁用主机发现意味着在一开始nmap不会向目标主机发送一个syn包来确认该主机是否存活,就直接对它进行扫描,但-Pn在最开始会发送一些dns请求,和-sL一样,但是我不知道这些dns请求有什么用,因为它没解析出什么东西来。

我们使用相同命令,但是端口扫描使用-sS,也就是syn请求试一下,确实是ack造成的,看来ack也不是万能的,有时候我们需要换着用。

当然端口扫描还有-sT选项,用来实现一个完整的tcp三次握手,这样可能会增加一些扫描结果的可靠性,但是会在目标主机的日志上留下你的ip,这可能会被用于溯源。但是syn请求就不会被记录吗?这个我也没尝试过。
(六)、扫描操作系统和版本
(1)、使用
使用下面的命令就可以扫描出系统的版本以及,各个端口的服务信息,但是这里它没能识别出我的系统是什么版本,只是给了个猜测,说就是linux的,具体命令如下。
sudo nmap -sV -O 192.168.225.60 #-sV扫描端口版本 -O扫描操作系统信息

具体的解释是这样的。


(2)、流量
我们当然想要知道nmap是如何进行流量探测的,所以我们用下面的命令来做一个实验,在这里我们的靶机关闭了lampp服务,只有ssh开着。
nmap -sV 192.168.225.60 -p22,80,3306 #-sV扫描端口版本 {目标ip} -p{需要扫描的端口}
结果显示80,3306关闭,而22号端口开启,且版本为7.4,协议使用2.0,那么nmap是如何知道这些信息的呢?

从流量中我们可以发现端倪,详细解释在图中说明。

我们将lampp服务打开,然后使用-sA去探测,结果是这样的,每个端口都是unfiltered。

流量是这样的,所有端口都返回rst,因为莫名其妙的接收到一个ack包,大家都会rst它。

于是我不得不重新看一下-sA是干嘛用的,因为它什么也扫描不出来,大概是说只有用ack报文探测的端口才被定义成unfiltered状态,也就是没被防火墙拦截,但是我不知道有什么用,这和我直接用syn扫描有什么其他的区别吗,官方的说法是为了发现防火墙的规则,因为我对防火墙还没有很深的研究,暂时不解释。


接下来我们来看看识别操作系统在流量层面上是如何实现的。
命令以及结果如下。

在它如何判断操作系统这件事上,我没什么头绪,nmap先是发了一些icmp请求,然后是一些udp请求,然后是一些tcp请求,当然,我没发现什么规律,或许它只是从ttl值什么的来判断吧。
关于通过ttl判断操作系统参考这里:不同操作系统的默认TTL(生存时间)值_不同系统的ttl-CSDN博客

(七)、时间参数设置
通常我们会设置扫描器的发送报文间隔时间,来躲避一些防火墙的规则,因为扫描太快会被发现,在nmap中,我们使用scan-delay来完成这一项工作,需要注意的是,2010年4月之后,--scan-delay的单位由毫秒修改为秒了,如果我们要指定毫秒间隔的化,需要在数字后面加上ms。
如下图,我们的扫描间隔为一秒钟。


当然nmap还有一堆时间参数可调,但是我们可能不会去看这些,因为有点麻烦,nmap提供了一些默认的时间参数模板,使用-T参数,总共有0-6个选项,但是根据它自己官方网站的描述,0和1和2太慢,3是默认选项,5又太快,可能不准确,最多想快一点就选-T4,想慢一点就自己配参数会更好,这里就不实验了。
参考文章:时间和性能 | Nmap参考指南(Man Page)
(八)、防火墙,IDS绕过
(1)、诱饵使用(混淆)
使用-D参数可以添加诱饵来帮助掩护自己,简单说来,当只有一个人在超市里时,偷东西很容易被发现。当有十个人在超市里时,东西被偷了,商家可能就很难发现真正的小偷了。
nmap 192.168.225.60 -p22 -D RND:3,ME # nmap {目标主机} -p{需要扫描的端口} -D RND:3{随机生成三个混淆ip},ME{我自己的ip}


这样会给蓝方造成困扰,因为它会看到很多告警,然后一个个封禁它,而且我们还可以伪造一些内部的ip地址作为源地址,这样会让他更摸不着头脑,因为许多安全设备好像是根据ip地址来区分内外网流量的,这似乎是个不错的想法。
例如某公司内网ip段为10.0.0.0/24,并且有外网服务器32.45.66.76,假设我从外网访问该公司外网服务器,并且混淆选项中设置一个10.0.0.2,安全设备可能会认为这是一个内对内的攻击,那么蓝队就会慌了,可能是这样的,不过还没实验过,不确定。
(2)、源端口伪造
更换源端口的目的是,有些安全设备会允许来自特定源端口的流量进入,但这也是nmap说的,我没有实验。

使用下面命令可将nmap请求的源端口修改为53。
nmap 192.168.225.60 -p22 -g53 #-g用于指定源端口

流量如下。

还有一些其他的参数详见这里:防火墙/IDS躲避和哄骗 | Nmap参考指南(Man Page)
(九)、漏洞扫描
使用附加脚本可以顺带扫描这些端口上有没有漏洞。
什么是nse以及脚本利用:使用Nmap脚本检测CVE漏洞-腾讯云开发者社区-腾讯云 (tencent.com)
如何安装vulscan:nmap 扩展漏洞扫描模块 - 西二旗老实人 - 博客园 (cnblogs.com)
使用nse(Nmap Scripting Engine)脚本,可以配合端口版本扫描来做一个简单的漏洞检测。它这个漏洞检测并不是发送poc请求去扫描这个端口,而是仅仅匹配端口版本在本地的漏洞库中是否被记录有漏洞。
举个例子:我们知道永恒之蓝漏洞存在于win7系统上,然后nmap扫描到这个系统是win7,就去自己的漏洞数据库里面找,发现win7存在永恒之蓝漏洞,于是就显示在输出端。
为什么说它没有发送poc去检测呢?我们看执行下面这一条命令产生的流量和我们不带nse脚本执行该命令的流量是一样的。
nmap -sV --script=/home/kali/scipag_vulscan/vulscan.nse 192.168.225.60 -p22

nmap -sV 192.168.225.60 -p22

带nse脚本的代码执行结果是这样的。

我们开启一台win7虚拟机,使用nmap的nse脚本探测是否存在永恒之蓝。
扫描的效果不是很好,什么都没有扫描出来。
由于我们的靶场环境还没有构建好,这章节留到之后再测试。
[1]、Vulscan
参考文章:https://mp.weixin.qq.com/s/mGOgSP0GzysASvjEB-X4Aw
后面我又把vulscan配置好了,扫描的结果如下。

可以去网上搜索扫描出来的相关漏洞看能否利用。
但是这些乱七八糟的属实看不太懂,后面结合msf看看有没有利用工具吧。

[2]、Vulners
vulners是使用在线模块进行漏洞扫描的,结果如下,后面有exploit的是可以利用的。

可以从其后面的链接找到可以利用的脚本。

这个比较复杂,暂时不弄。
[3]、Vuln
使用自带的vuln脚本就什么都扫描不出来了。

(十)、输出结果
使用-oN <filespec>` (标准输出)就可以输出结果到指定文件。当然还有其他输出的款式,在这里不多解释。
使用下面的命令就可以输出一个文本文件形式的结果。

我们也可添加-v参数来使得输出更详细,这里使用-v,我们能够看到nmap在每个阶段干的事,对比我们之前用wireshark抓到的流量,工作原理这就很清晰了。

三、Nmap的流量特征
nmap很出名了,所以它的流量特征我们也应该注意一下。
其中一个是nmap的窗口大小为1024,而正常的窗口大小会变化,8,6,4489等等,而nmap是固定的。

正常的流量如下。

笔者认为做这些流量分析和防火墙绕过最好还是先安装一个防火墙来做实验,由于现在还没有弄,这一部分滞后。
流量分析和绕过防火墙:Nmap流量分析和入侵检测绕过_nmap流量特征-CSDN博客
四、总结
在实战场景下,我们如何使用nmap呢?
首先是对一整个目标网段进行扫描,发现存活主机,命令如下。当然我们可使用-PS,-PA,-PR来指定主机发现发送的请求包格式。
nmap -sn 192.168.225.0/24 #-sn表示不进行端口扫描,只进行主机发现

发现存活的主机之后,我们开始对该主机进行端口扫描,命令如下。当然我们可使用-sF,-sT来发送其他格式的请求包。也可也使用-p-对主机所有端口进行探测
nmap -sS 192.168.225.60 #-sS表示使用syn请求进行端口探测

发现了端口之后,我们指定端口进行详细的版本探测,并且使用-O进行系统版本探测。当然我们可以使用-A完成相同操作,-A包含了-sV和-O。
nmap -sV -O 192.168.225.60 -p #-sV扫描端口版本,-O扫描操作系统
如果遇到防火墙,我们还可以使用一些混淆技术,源端口变化,以及时间调整,这里不展开,因为没有实验过。

其他的一些使用实例在nmap官网可以发现:实例 | Nmap参考指南(Man Page)。
我们甚至可以使用script脚本来对开放端口进行一些已知漏洞的扫描。
并且nmap还有它的gui版本,zenmap,我们可能会在以后讲到。


浙公网安备 33010602011771号