服务与系统探测也是渗透测试最关键的一个步骤。端口扫描发现目标主机开放的端口后,就可以基于这些端口探测对应的服务和操作系统。通过探测服务与操作系统,可以获取目标主机更多的敏感信息。这些信息有助于漏洞探测和漏洞利用。
服务探测的原理
使用-sV选项开启服务探测
服务探测是通过对比服务指纹,寻找出匹配的服务类型。大部分服务在响应客户端请求时都会发送一些规范的数据包。这些数据包往往有一些格式信息,这部分信息被收集起来用于服务识别,因此称为服务指纹。Nmap收集了几千条服务指纹信息,保存在nmap-service-probes数据库文件中。Nmap默认读取该文件进行指纹匹配。当实施服务探测时,Nmap与目标端口进行通信,获取当前端口的响应包。通过与指纹数据库对比,以找出匹配的服务类型。
服务探测的流程一般如下
- Nmap先进行端口扫描,然后把状态为open或open|openfiltered的TCP或UDP端口传递给服务识别模块,这些端口将会并行地做服务探测。
- Nmap检查端口是否在排除端口列表内。如果在排除列表中,则不进行探测。
- 如果是TCP端口,将尝试建立TCP连接。如果连接成功,端口状态会由open|filtered转换成open。该措施适用于使用隐蔽扫描(如TCP FIN)方式识别出端口状态为open|filtered的端口。
- 一旦上面的连接建立,Nmap尝试等待6s。一些常见的服务(如FTP、SSH、SMTP和Telnet等)将会对建立的连接发送一些欢迎信息(Welcome banner),这个过程称为空探针(NULL Probe)探测。该探测仅仅是和目标端口建立连接,并没有发送任何数据。在等待的时间内,如果收到了数据,Nmap会将收到的信息和NULL Probe的服务指纹进行匹配。如果匹配到服务类型和版本信息,则该端口的服务识别就结束了。如果只匹配了服务类型而没有匹配版本信息,则Nmap将会继续进行扫描。
- 如果是UDP端口,或者NULL Probe匹配失败且NULL Probe没有探测出版本号,将会顺序使用nmap-service-probes文件中的探针(Probe)。每一个探针包含一个探针字符串(Probestring)。在服务探测的时候,该字符串会被发送给目标端口。目标返回的数据和这个探针对应的指纹进行匹配。如果匹配成功,则服务识别结束。如果没有检查到版本号,则Nmap将尝试下一个探针。如果探针和指纹匹配成功,则查看是否有fallback指令。如果有,则执行fallback指令继续扫描。
服务探测文件
如果用户不想使用默认的服务探测文件,则可以自己创建文件,并使用--versiondb选项指定。语法格式如下:
nmap --versiondb < service probes file > <target>
从官网上截取了一部分nmap-service-probes文件
# The Exclude directive takes a comma separated list of ports.
# The format is exactly the same as the -p switch.
Exclude T:9100-9107
# This is the NULL probe that just compares any banners given to us
##############################NEXT PROBE##############################
Probe TCP NULL q||
# Wait for at least 5 seconds for data. Otherwise an Nmap default is used.
totalwaitms 5000
# Windows 2003
match ftp m/^220[ -]Microsoft FTP Service\r\n/ p/Microsoft ftpd/
match ftp m/^220 ProFTPD (\d\S+) Server/ p/ProFTPD/ v/$1/
softmatch ftp m/^220 [-.\w ]+ftp.*\r\n$/i
match ident m|^flock\(\) on closed filehandle .*midentd| p/midentd/ i/broken/
match imap m|^\* OK Welcome to Binc IMAP v(\d[-.\w]+)| p/Binc IMAPd/ v$1/
softmatch imap m/^\* OK [-.\w ]+imap[-.\w ]+\r\n$/i
match lucent-fwadm m|^0001;2$| p/Lucent Secure Management Server/
match meetingmaker m/^\xc1,$/ p/Meeting Maker calendaring/
# lopster 1.2.0.1 on Linux 1.1
match napster m|^1$| p/Lopster Napster P2P client/
Probe UDP Help q|help\r\n\r\n|
rarity 3
ports 7,13,37
match chargen m|@ABCDEFGHIJKLMNOPQRSTUVWXYZ|
match echo m|^help\r\n\r\n$|
文件中#表示注释,格式如下
- Exclude <port>
-
排除指令,用于指定探测服务时排除的端口。该指令只能使用一次,一般放在文件的头部,即所有的探针之前。nmap-service-probes文件默认排除了TCP 9100~9107之间的端口。这些端口一般用于打印机中,如果向这些端口发送数据,则监听的端口会将这些数据打印出来。该指令的语法格式如下:
例如,指定排除TCP/UDP的53号端口、TCP的9100端口和UDP的30000~40000端口,编写的指令如下:Exclude 53,T:9100,U:30000-40000
-
-
Probe <pattern>
-
探测指令,告诉Nmap发送哪种字符串来识别服务,即定义了一个探测包。Probe指令的语法格式如下:Probe protocol probename probestring
-
protocol:指定探针的协议。这里只能指定TCP或UDP,因为Nmap只会对这两种协议的服务进行探测。
-
probename:设置探针的名称。如果用户为某个服务设置了fallback(回退指令),则会使用这个探针的名称。
-
probestring:指定Nmap探测服务发送的字符串,格式为q|......|。发送的字符格式类似于C和Perl的字符格式,而且支持转义字符,如\0、\a、\n、\r等。如果是空探针,则分隔符之间的字符串为空,即Probe TCP NULL q||。
例如,设置一个TCP的探针用来识别HTTP服务。执行命令如下:Probe TCP GetRequest q|GET / HTTP/1.0\r\n\r\n|
-
-
- totalwaitms <value>
-
探针探测的超时等待时间。在Nmap中,默认值为6000ms。
-
- tcpwrappedms <value>
- 一个计时器时间,仅用于空探针。如果服务器在计时器结束之前关闭了TCP连接,则该服务标记为tcpwrapped。在Nmap中,默认值为3000ms。
- match <pattern>
-
匹配指令,告诉Nmap如何从目标主机返回的字符串中识别出服务。该指令的语法格式如下:match service pattern [versioninfo]
-
service:与pattern匹配成功的服务名称,如FTP、SSH和HTTP等。
-
pattern:用于识别返回的字符串是否匹配对应的服务。pattern的格式和Perl类似,语法为m/[regex]/[opts]。其中:m表示字符串的开始;/是分隔符,这个分隔符可以是其他可打印的字符,只要和接下来的分隔符相匹配即可;[regex]部分是一个Perl格式的表达式,目前仅支持i和s两个选项。i表示匹配不区分大小写;s表示在“.”字符后面有新行。另外,[regex]还支持分组。
-
versioninfo:该部分包含几个可选的字段,每个字段都由一个标识符开始(如h表示hostname),接着是分隔符,建议使用斜线,最后是字段值。
-
识别FTP服务的匹配指纹信息,执行命令如下:
match ftp m/^220.*Welcome to .*Pure-?FTPd (\d\S+\s*)/ p/Pure-FTPd/ v/$1/
cpe:/a:pureftpd:pure-ftpd:$1/
-
-
- softmatch <pattern>
- match指令类似。不同的是,softmatch指令只用来匹配服务类型,而不提供服务版本信息。
- ports和sslports
- 令指定Nmap探针所要发送数据的端口。该指令仅使用一次,放在每个探针的后面
- rarity<0-9>
- 表示该探针被调用的优先级。数值越高表示被调用的优先级越低,也就是说该探针的准确性越低,或者识别的服务不常见。
-
fallback <comma separated list of probes>
-
回滚指令。如果当前定义的指纹信息匹配失败,但是指定了fallback指令,将会退到指定的探针再次进行匹配。该指令是可选指令。如果TCP Probe没有定义fallback指令,则Nmap会首先和当前定义的探针进行匹配。如果匹配失败,将自动回滚(fallback)到空探针进行匹配。如果定义了fallback指令,那么当前探针匹配失败后,将回滚到fallback定义的探针再进行匹配。如果继续匹配失败,则回退到空探针进行匹配。
-
服务探测模式
- 探测所有端口
- 默认情况下,Nmap服务探测文件nmap-service-probes使用Exclude指令指定排除的端口。如果想要探测所有端口,则可以修改或删除Exclude指令,也可以使用--allports选项指定扫描所有端口。--allports选项的语法格式如下:
nmap -sV --allports <target>
- 默认情况下,Nmap服务探测文件nmap-service-probes使用Exclude指令指定排除的端口。如果想要探测所有端口,则可以修改或删除Exclude指令,也可以使用--allports选项指定扫描所有端口。--allports选项的语法格式如下:
-
探测强度
-
探测强度不同,使用的探针也不同。设置强度越高,使用的探针越多,服务越有可能被正确识别。但是高强度扫描需要花费更多的时间。如果在服务探测文件中使用ports指令指定端口,无论设置何种强度,探针都会被使用一遍,用来探测服务类型。Nmap提供了几个设置探测强度的选项
-
version-intensity:设置版本扫描强度值,范围为0~9。其中,默认值为7
-
version-light:打开轻量级模式。该选项相当于--version-intensity 2的别名。这种模式扫描速度非常快,但是识别服务的可能性也略微小一点。
-
version-all:尝试使用所有的探针进行探测。该选项相当于--version-intensity 9的别名。该选项可以保证对所有端口发送每个探测报文。
-
-
显示调试信息 --version-trace
-
RPC扫描
nmap -sR <target>,远程过程调用(Remote Procedure Call,简称RPC)也叫作远程程序调用,是一个计算机通信协议。RPC扫描可以和Nmap的许多端口扫描方法结合使用。RPC扫描方式通过向所有处于开放状态的TCP/UDP端口发送SunRPC程序NULL命令,来确定它们是否是RPC端口。如果是,则进一步判断程序和版本信息。其中,动态分配给应用程序的端口称为RPC端口。使用这种扫描方式,可以获取和rpcinfo -p命令一样的信息,即RPC服务的详细信息。使用-sV选项实施扫描,探测到的RPC扫描内容更全面,因此RPC扫描方式很少使用。