端口扫描
网络端口
何为端口
在网络技术中,端口(Port)大致有两种意思:一是物理意义上的端口,比如,ADSL Modem、集线器、交换机、路由器用于连接其他网络设备的接口,如RJ-45端口、SC端口等等;二是逻辑意义上的端口,一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。
端口分类
按端口号可分为3大类:
- 公认端口(Well Known Ports):从0到1023,它们紧密绑定(binding)于一些服务。通常这些端口的通讯明确表明了某种服务的协议。例如:80端口实际上总是HTTP通讯。
- 注册端口(Registered Ports):从1024到49151。它们松散地绑定于一些服务。也就是说有许多服务绑定于这些端口,这些端口同样用于许多其它目的。例如:许多系统处理动态端口从1024左右开始。
- 动态和/或私有端口(Dynamic and/or Private Ports):从49152到65535。理论上,不应为服务分配这些端口。实际上,机器通常从1024起分配动态端口。但也有例外:SUN的RPC端口从32768开始。
常用端口
21端口:FTP 文件传输服务
22端口:SSH 远程连接服务
23端口:TELNET 终端仿真服务
3389端口:Windows远程登录服务
5938端口:TeamViewer 远程服务管理工具
139端口:NetBIOS 文件与打印共享
445端口:SMB 文件共享
25端口:SMTP 简单邮件传输协议
53端口:DNS 域名解析协议
161端口:SNMP 简单网络管理协议
80端口:HTTP 超文本传输协议
443端口:HTTPS SSL加密的超文本传输协议
3306端口:MYSQL数据库端口
5432端口:PostgreSQL数据库端口
1433端口:SQLServer数据库端口
1521端口:Oracle数据库默认端口
6379端口:Redis数据库端口
27017端口:mongoDB数据库默认端口
8080端口:WWW代理服务端口(Tomcat、JBoss等)
9200端口:Elasticsearch服务器端口
Nmap
Nmap的介绍
Nmap (“Network Mapper(网络映射器)”) 是一款开放源代码的网络探测和安全审核的工具。它的设计目标是快速地扫描大型网络,当然用它扫描单个主机也没有问题。Nmap以新颖的方式使用原始IP报文来发现网络上有哪些主机,那些主机提供什么服务(应用程序名和版本),那些服务运行在什么操作系统(包括版本信息), 它们使用什么类型的报文过滤器/防火墙,以及一堆其它功能。虽然Nmap通常用于安全审核,许多系统管理员和网络管理员也用它来做一些日常的工作,比如查看整个网络的信息, 管理服务升级计划,以及监视主机和服务的运行。
Nmap的作用
- 检测活动在网络上的主机(主机发现)
- 检测主机上的开放端口(端口发现或枚举)
- 检测到相应的端口(服务发现)的软件或版本
- 检测操作系统,硬件地址,以及软件版本
- 检测脆弱性的漏洞(Nmap的脚本)
Nmap扫描类型

Connect()扫描
此扫描试图与每一个TCP端口进行“三次握手”通信。如果能够成功建立接连,则证明端口开发,否则为关闭。准确度很高,但是最容易被防火墙和IDS检测到,并且在目标主机的日志中会记录大量的连接请求以及错误信息。
TCP connect端口扫描服务端与客户端建立连接成功(目标端口开放)的过程:
① Client端发送SYN;
② Server端返回SYN/ACK,表明端口开放;
③ Client端返回ACK,表明连接已建立;
④ Client端主动断开连接。
建立连接成功(目标端口开放)

TCP connect端口扫描服务端与客户端未建立连接成功(目标端口关闭)过程:
① Client端发送SYN;
② Server端返回RST/ACK,表明端口未开放。
未建立连接成功(目标端口关闭)
优点:实现简单,对操作者的权限没有严格要求(有些类型的端口扫描需要操作者具有root权限),系统中的任何用户都有权力使用这个调用,而且如果想要得到从目标端口返回banners信息,也只能采用这一方法。
另一优点是扫描速度快。如果对每个目标端口以线性的方式,使用单独的connect()调用,可以通过同时打开多个套接字,从而加速扫描。
缺点:是会在目标主机的日志记录中留下痕迹,易被发现,并且数据包会被过滤掉。目标主机的logs文件会显示一连串的连接和连接出错的服务信息,并且能很快地使它关闭。
SYN扫描
扫描器向目标主机的一个端口发送请求连接的SYN包,扫描器在收到SYN/ACK后,不是发送的ACK应答而是发送RST包请求断开连接。这样,三次握手就没有完成,无法建立正常的TCP连接,因此,这次扫描就不会被记录到系统日志中。这种扫描技术一般不会在目标主机上留下扫描痕迹。但是,这种扫描需要有root权限。

端口开放:1、Client发送SYN 2、Server端发送SYN/ACK 3、Client发送RST断开(只需要前两步就可以判断端口开放)
端口关闭:1、Client发送SYN 2、Server端回复RST(表示端口关闭)
优点:SYN扫描要比TCP Connect()扫描隐蔽一些,SYN仅仅需要发送初始的SYN数据包给目标主机,如果端口开放,则相应SYN-ACK数据包;如果关闭,则响应RST数据包
秘密扫描
秘密扫描是一种不被审计工具所检测的扫描技术。
它通常用于在通过普通的防火墙或路由器的筛选(filtering)时隐藏自己。
秘密扫描能躲避IDS、防火墙、包过滤器和日志审计,从而获取目标端口的开放或关闭的信息。由于没有包含TCP 3次握手协议的任何部分,所以无法被记录下来,比半连接扫描更为隐蔽。
但是这种扫描的缺点是扫描结果的不可靠性会增加,而且扫描主机也需要自己构造IP包。现有的秘密扫描有TCP FIN扫描、TCP ACK扫描、NULL扫描、XMAS扫描和SYN/ACK扫描等。
NULL扫描
反向扫描——原理是将一个没有设置任何标志位的数据包发送给TCP端口,在正常的通信中至少要设置一个标志位,根据FRC 793的要求,在端口关闭的情况下,若收到一个没有设置标志位的数据字段,那么主机应该舍弃这个分段,并发送一个RST数据包,否则不会响应发起扫描的客户端计算机。也就是说,如果TCP端口处于关闭则响应一个RST数据包,若处于开放则无相应。但是应该知道理由NULL扫描要求所有的主机都符合RFC 793规定,但是windows系统主机不遵从RFC 793标准,且只要收到没有设置任何标志位的数据包时,不管端口是处于开放还是关闭都响应一个RST数据包。但是基于Unix(如Linux)遵从RFC 793标准,所以可以用NULL扫描。 经过上面的分析,我们知道NULL可以辨别某台主机运行的操作系统是什么操作系统。
端口开放:Client发送Null,Server没有响应

端口关闭:1、Client发送NUll 2、Server回复RST

说明:Null扫描和前面的TCP Connect()和SYN的判断条件正好相反。在前两种扫描中,有响应数据包的表示端口开放,但在NUll扫描中,收到响应数据包表示端口关闭。反向扫描比前两种隐蔽性高些,但精确度也相对低一些。
FIN扫描
与NULL有点类似,只是FIN为指示TCP会话结束,在FIN扫描中一个设置了FIN位的数据包被发送后,若响应RST数据包,则表示端口关闭,没有响应则表示开放。此类扫描同样不能准确判断windows系统上端口开发情况。
端口开放:发送FIN,没有响应
端口关闭:1、发送FIN 2、回复RST
ACK扫描
扫描主机向目标主机发送ACK数据包。根据返回的RST数据包有两种方法可以得到端口的信息。方法一是: 若返回的RST数据包的TTL值小于或等于64,则端口开放,反之端口关闭,如图所示。

Xmas-Tree扫描
通过发送带有下列标志位的tcp数据包
URG:指示数据时紧急数据,应立即处理。
PSH:强制将数据压入缓冲区。
FIN:在结束TCP会话时使用。
正常情况下,三个标志位不能被同时设置,但在此种扫描中可以用来判断哪些端口关闭还是开放,与上面的反向扫描情况相同,依然不能判断windows平台上的端口。
端口开放:发送URG/PSH/FIN, 没有响应

端口关闭:1、发送URG/PSH/FIN,没有响应 2、响应RST

XMAS扫描原理和NULL扫描的类似,将TCP数据包中的ACK、FIN、RST、SYN、URG、PSH标志位置1后发送给目标主机。在目标端口开放的情况下,目标主机将不返回任何信息。
Dump扫描
也被称为Idle扫描或反向扫描,在扫描主机时应用了第三方僵尸计算机扫描。由僵尸主机向目标主机发送SYN包。目标主机端口开发时回应SYN|ACK,关闭时返回RST,僵尸主机对SYN|ACK回应RST,对RST不做回应。从僵尸主机上进行扫描时,进行的是一个从本地计算机到僵尸主机的、连续的ping操作。查看僵尸主机返回的Echo响应的ID字段,能确定目标主机上哪些端口是开放的还是关闭的。

常用命令选项
执行命令:nmap [扫描类型] [扫描选项]
- 扫描类型
| 类型 | 说明 |
|---|---|
| -sT | TCP connect()扫描:最基本的扫描方式 |
| -sS | TCP 同步扫描(TCP SYN) |
| -sA | ACK 扫描 |
| -sN; -sF; -sX | TCP Null,FIN,Xmas-Tree扫描 |
| -sI <zombie host[:probeport]> | Idle扫描 |
| -sO | 对远程主机所支持的IP协议进行扫描 |
| -sU | 使用UDP扫描 |
| -sP | 使用Ping扫描 |
| -sW | 对滑动窗口的扫描 |
| -sM | TCP Maimon扫描 |
| -b <ftp relay host> | FTP弹跳扫描(FTP bounce scan) |
| —scanflags | 定制的TCP扫描 例如,—scanflags URGACKPSHRSTSYNFIN设置了所有标志位 |
- 扫描选项
| 通用选项 | 说明 |
|---|---|
| -P0 | 在扫描之前,不必ping主机 |
| -PT | 在扫描之前使用TCP ping确定哪些主机正在运行 |
| -PS | 对于root用户,这个选项使用SYN包而不是ACK包来对目标主机进行扫描 |
| -PI | 设置这个选项,让nmap使用真正的ping(ICMP echo请求)来扫描目标主机是否正在运行 |
| -PB | 这是默认的ping扫描选项。它使用ACK(-PT)和ICMP(-PI)两种扫描选项并行扫描 |
| -O | 扫描主机的操作系统 |
| -sV | 打开版本探测 |
| —allports | 不为版本探测排除任何端口 |
| -A | 全面扫描 |
| -v | 显示扫描过程 |
| -p <IP范围> | 只扫描指定的端口 |
| -F | 快速 (有限的端口) 扫描 |
| -r | 不要按随机顺序扫描端口 |
| -T <0-5> | 设置调速模板,级别越高扫描速度越快 |
| -S <IP_Address> | 源地址欺骗 |
| -e <interface> | 使用指定的网络接口发送和接收报文 |
| -g <portnumber> | 源端口欺骗 |
| —data-length <number> | 发送报文时 附加随机数据 |
| —randomize-hosts | 对目标主机的顺序随机排列 |
| -oN <filespec> | 标准输出 |
| -oX <filespec> | XML输出 |
| -iL <inputfilename> | 从文件列表中输入 |
| -iR <hostnum> | 随机选择目标 |
Nmap扫描状态
- open :应用程序在该端口接收 TCP连接和 UDP报文。
- closed :关闭的端口对于nmap也是可访问的,它接收nmap探测报文并作出响应。但没有应用程序在其上监听。
- filtered :由于包过滤阻止探测报文到达端口,nmap无法确定该端口是否开放。过滤可能来自专业的防火墙设备,路由规则 或者主机上的软件防火墙。
- unfiltered :未被过滤状态意味着端口可访问,但是 nmap无法确定它是开放还是关闭。只有用于映射防火墙规则集的 ACK扫描才会把端口分类到这个状态。
- open | filtered :(开放或者被过滤的):无法确定端口是开放还是被过滤的,开放的端口不响应就是个例子。没有响应也可能意味着报文过滤器丢弃了探测报文或者它引发的任何反应。UDP,IP协议,FIN,Null 等扫描会引起。
- closed | filtered :(关闭或者被过滤的):无法确定端口是关闭还是被过滤的。
常用扫描方案
1、对单个主机进行全面扫描
1 | nmap -A 192.168.1.2 |
2、使用SYN扫描整个网段
1 | nmap -sS 192.168.1.0/24 |
3、扫描指定主机的指定端口
1 | nmap -sV -p 0-1024,3389 192.168.1.1-127 |
4、随机选择100000台主机扫描是否运行Web服务器(80端口)
1 | nmap -v -iR 100000 -p 80 |
Nmap脚本
脚本参数
1 | SCRIPT SCAN: |
上面这部分是Nmap关于脚本的参数,下面一个一个来介绍:
-sC 是指的是采用默认配置扫描,与—script=default参数等价
—script=脚本名称,脚本一般都在Nmap的安装目录下的scripts目录中
那么Linux下可以查看脚本数量:
1 | ls /usr/share/nmap/scripts | wc -l |

那么我当前的Nmap是有602个很使用的漏洞利用、工具脚本。也可以使用下面一条命令导出
1 | ls /usr/share/nmap/scripts/ | sed 's/.nse//' > scripts.list |
那么所有的脚本名称都在scripts.list中了,这样做的原因是因为我们传递脚本名称的时候,不能写脚本的文件扩展名(.nse)。
—script-args=key1=value1,key2=value2… 该参数是用来传递脚本里面的参数的,key1是参数名,该参数对应value1这个值,那么有更多的参数,使用逗号连接,后面例子中会给大家讲解。
–script-args-file=filename,使用文件来为脚本提供参数。
—script-trace 如果设置该参数,则所有的脚本收发请求过程。
—script-updatedb 在Nmap的scripts目录里有一个script.db,该文件中保存了当前Nmap可用的脚本,类似于一个小型数据库,如果我们开启nmap并且调用了此参数,则nmap会自行扫描scripts目录中的扩展脚本,进行数据库更新。
—script-help=脚本名称,调用该参数后,Nmap会输出该脚本名称对应的脚本使用参数,以及详细介绍信息。
实战
现在我们用一个很简单的脚本,telnet爆破脚本,我们搜索一下:
1 | ls /usr/share/nmap/scripts/ | grep telnet |

那么可以看到,返回了两个nse脚本名称,那么第一个就是telnet爆破的脚本了,如果不清楚的话,可以使用上面刚介绍过的—script-help参数。

可以看到 有一个Nmap的文档地址,正是我们现在想要使用的脚本的详细信息。

最后那个 target指的是我们的目标地址。userdb是用户名字典,passdb是密码字典,timeout是每次连接之间的等待超时时间。
当然了,我们也可以直接查看脚本源文件:
1 | --- |
上方这块,可以看到有一个例子,还有常规的扫描结果。那么加粗的这行是笔者故意为之,因为在某些情况下,管理员可能会更改telnet服务的端口(这里不只是光指Telnet),那么我们就无法使用这个脚本了。聪明的你一定想到了更改上方的23端口吧!但是这还不够灵活~ 我们可以将端口号自制成一个变量,通过我们的脚本参数传递进去。这里不再过多赘述。
下面我们来实战一下,先扫描一下靶机。
1 | nmap -sT -Pn -F 192.168.123.188 |

发现开启了23号端口(telnet服务)
我把字典放到了 /usr/share/nmap/nselib/data,因为这个目录中是专门存放Nmap默认字典的。
扫描命令如下:
1 | nmap -p 23 -Pn --script=telnet-brute --script-args=userdb=admins.lst,passdb=passwords.lst,telnet-brute.timeout=3s --script-trace 192.168.123.188 |
在这我用—script-trace开启了数据的收发开关,扫描结果如下:

试试使用Telnet登录

登录成功!
脚本分类
【vuln】漏洞检测方面:vuln NSE Category
【auth】权限验证方面:auth NSE Category
【brute】暴力破解方面:brute NSE Category
【discovery】服务信息发现:discovery NSE Category
【dos】DOS攻击方面:dos NSE Category
【exploit】漏洞利用方面:exploit NSE Category
【external】外部扩展方面:external NSE Category (集成了shodanAPI)
【fuzzer】FUZZ测试方面:fuzzer NSE Category
【intrusive】一些针对的服务入侵模块:intrusive NSE Category
【malware】恶意后门方面:malware NSE Category
【version】版本识别:version NSE Category
以上参数都可以作为—script的通配参数,例如:—script=vuln
--script=all 调用所有脚本扫描
Nmap流量特征修改
现在主流的流量分析设备也将其流量加入了特征库,为了防止在探测阶段IP就被封掉,对其的流量特征做一些简单的修改有点用的。
Win值修改
通过观察可以发现nmap在使用SYN扫描时Windows的窗口值值固定是1024。
(PS :window 关键字用于检查特定的TCP窗口大小)

下面是正常连接3389时,发送的数据包。可以看到win值明显不一样。

修改tcpip.cc文件中tcp->th_win的值,查询TCP中win这个值的信息发现,默认最大为65535。所以应该在此范围内都可以。
但是要考虑已公开的规则,如之前大佬写的bypass emergingthreats这篇,这个就过滤了2048 1024 3072 4096。

关键词修改
根据规则,一个一个去修改文件即可。
nmap,nm,nm@p,OR sqlspider等等,主要的就是SIP文件和一些常用的脚本文件。
这些个就是从emergingthreats的规则中提取的。


UDP探测时填充值修改
修改osscan2.cc
也可通过-O参数修改
1 | static u8 patternbyte = 0x43; /* character 'C' */ 替换为 static u8 patternbyte = 0x46; /* character 'F' */ |
重新编译后再去扫描,内容已经换了,长度应该也是可以调整。
1 | u8 packet[328]; /* 20 IP hdr + 8 UDP hdr + 300 data */ |
这里还没测试,感兴趣可以自己去定义,看会不会有什么问题。

修改脚本中的值
- nselib/http.lua
USERAGENT = stdnse.getscript_args(‘http.useragent’)
- nselib/mssql.lua
搜索Nmap NSE然后替换
- nselib/sip.lua
搜索Nmap NSE然后替换
- scripts/http-sql-injection.nse
搜索sqlspider然后替换
- scripts/ssl-heartbleed.nse
搜索Nmap ssl-heartbleed替换
- nselib/rdp.lua
local cookie = “mstshash=nmap”
Nmap衍生
Zenmap
Zenmap是Nmap的官方GUI(图形界面)版本。

DNmap
dnmap是使用客户端/服务器体系结构的分布式nmap框架。 服务器从文件中读取命令,并将其发送给每个客户端。 客户端执行nmap命令并将结果发送回去。
下载地址:https://sourceforge.net/projects/dnmap/
有关DNmap的使用可以参考:https://www.bilibili.com/read/cv5791617/

MasScan
MasScan的介绍
Masscan 作为一个端口扫描工具,具备优秀的性能,能够在短时间内对大量的IP和端口进行是否开放的扫描,使用简单,相比于NMAP等工具来说更容易上手,是网络安全领域的优秀工具。Masscan使用C语言编写,核心部分使用C90编写,包含了大量TCP协议相关,以及操作系统相关的底层代码,代码注释完善,十分详尽,结构清晰,是十分值得学习的C语言网络项目。
常用选项
1 | -p <ports,–ports <ports>> 指定端口进行扫描 |
常用扫描方案
- 简单使用
1 | masscan 192.168.123.0/24 -p445 |
- 单ip多端口
1 | masscan 192.168.123.188 -p1-1024,8080,3306 |
- 多ip单端口
1 | masscan 192.168.123.1-192.168.123.100,192.168.123.188 -p80 |
- 快速扫描
1 | masscan 192.168.123.0/24 -p1-1024 --rate 10000 |
- 把当前命令的配置保存下来,然后在其他masscan命令直接引用
1 | masscan 192.168.123.188 -p80,8080 --echo > scan.conf |
- 将扫描结果导出到XML文件
1 | masscan 192.168.123.188 -p0-65535 -oX scan.xml |