nmap服务探测
全部参考自nmap服务探测文档,包括探测如何工作,数据库文件的语法,等等
nmap-service-probe数据库文件语法
nmap中服务探测的代码位于根目录下的nmap-service-probe文件中,共有136个探测包,对于每个探测包,通过分析其响应来确定所属服务。
文件采用行文本的形式,#开头的行是注释。####NEXT PROBE####之间间隔的是一个探测包,对应一个Probe。以LDAP的探测为例:
##############################NEXT PROBE##############################
Probe UDP LDAPSearchReqUDP q|\x30\x84\x00\x00\x00\x2d\x02\x01|
rarity 8
ports 389
match ldap m|^0\x84\0\0..\x02\x01.*dsServiceName1\x84\0\0\0.\x04.CN=NTDS\x20Settings|s p/Microsoft Windows Active Directory LDAP/ i/Domain: $3.$4, Site: $2/ o/Windows/
match ldap m|^0\x84\0\0..\x02\x01.*dsServiceName1\x84\0\0\0.\x04.CN=NTDS\x20Settings|s p/Microsoft Windows Active Directory LDAP/ i/Domain: $3.$4.$5, Site: $2/ o/Windows/
##############################NEXT PROBE##############################
所有非注释的行,都以一个指令开头。指令一共有9个,分别是:
- Probe
- match
- Exclude
- softmatch
- ports and sslports
- totalwaitms
- tcpwrappedms
- rarity
- fallback
最常用的显然是Probe和match指令。
Probe
语法 Probe <protocol> <probename> <probestring>
例子 Probe TCP GetRequest q|GET / HTTP/1.0\r\n\r\n|
Probe后的数据为探测包的内容,格式为 "TCP/UDP" + 探测方式名称 + 探测包表达式。
如例子中所示,探测包表达式(probestring)必须使用q开头,q之后的字符会被认为是界定符号,默认为 | 。如果探测包中含有 | 符号,那么需要更换一个界定符。
第一个探测包是特殊的,它的探测包为空: q|| ,这个探测包被称为null probe。null probe建立TCP连接后nmap不会发送任何消息,而是等待对方发送起始数据。null probe包含了3000行的match。
match
语法 Syntax: match <service> <pattern> [<versioninfo>]
例子 match ftp m/^220.*Welcome to .*Pure-?FTPd (\d\S+\s*)/ p/Pure-FTPd/ v/$1/ cpe:/a:pureftpd:pure-ftpd:$1/
match后面紧跟的是服务名称(<service>)。
服务名称的唯一特例:ssl/vmware-auth 。在探测vmware-auth服务的时候,可以免去建立ssl连接。
模式(pattern)使用正则表达式来判断是否符合规则,语法如下。采用了Perl风格的正则表达式,即以m开头,正则在两个界定符之间,后面附加一个option。
match模式的语法: m|[regex]|[opts]
Perl正则表达式,nmap使用了PCRE库
目前只支持2个option:i和s。如果模式后加了i,说明大小写不敏感。如果加了s,说明正则表达式中的.可以匹配换行符。
正则表达式中,被小括号包裹的模式会被匹配并提取出来,在后面的versioninfo给$1, $2等字段赋值。
[<versioninfo>]是可选的,一般使用/作为界定符。一共有7种versioninfo:
- p/vendorproductname/ 指出厂商或者服务的名称,例如“Apache httpd”
- v/version/ 指出运行的应用版本,可能是数字或者文本
- i/info/ 混杂的各种信息,例如SSH server的端口号
- h/hostname/ 服务提供的host名称。这对于SMTP或者POP3尤其有用,因为在内部网络或者反向DNS时,这些服务器需要互相区分。
- o/operatingsystem/ 服务运行的操作系统。不过,这里探测出的系统和nmap原生OS探测结果可能有出入。例如一个linux系统在接收到请求之后将数据包转发给windows server系统。此时原生探测认为是linux系统,而服务探测认为是windows系统。
- d/devicetype/ 设备类型,例如“print server”或者“webcam”。这个数据可能是设备主动透露的,也可能是推测的。推测的原理:例如HP-ChaiServer web server只在打印机上运行,所以肯定是printer。设备类型列表
- cpe:/cpename/[a] CPE(Common Platform Enumeration) 可以指出3种信息:a服务,h硬件平台,o操作系统。CPE的更多信息
cpe信息的语法:cpe:/<part>:<vendor>:<product>:<version>:<update>:<edition>:<language>
cpe例子: cpe:/o:linux:linux_kernel:2.6.39
<part>指字母a,h或o,指出这条信息的类型。冒号之间可以留空白,如果末尾信息全部空白可以省略。
除了$1, $2之外,还有三种$开头的helper function被用于versioninfo中,它们的用法都和普通$1用法一样,只不过提供了方便的功能:
i/$P(1)/
v/$SUBST(1,"_",".")/
v/9.00.$I(1,">")/
- $P() ,过滤了不可打印的字符.
- $SUBST(),和普通$1用法一样,用来将得到的版本号转换成好看的版本号。例如我们得到了版本号2_2_3_578. 上面的例子可以将其转换为用点分隔的版本号 2.2.3.578.
- $I(),用来将字节传输的数字转换为十进制数字,使用">"和"<"来区分大小端。
其他指令
Exclude是最特殊的一个指令,因为它被设置在文件最面前,而其他指令都从属于某个探测包。Exclude指出了不扫描的端口,默认为9100-9107,因为这些端口属于打印机,而有时候打印机会直接打印出探测包的内容,暴露扫描者。
Exclude T:9100-9107
softmatch是没那么准确的match,softmatch不带有任何后缀额外信息。和普通match不同的是,如果匹配到了softmatch,那么匹配也不会停止,直到遍历完该探测包所有的match——如果没有匹配到其它match,那么最终结果会是soft matched;如果匹配到了普通match,那么最终结果会是full matched。
softmatch ftp m/^220 [-.\w ]+ftp.*\r\n$/i
ports and sslports 用于指出服务扫描最常见的端口,显然,应该优先探测指出的端口。例如探测HTTP服务时,如果80端口开着,应该优先探测80端口。nmap并没有明确指出,nmap是否会在其它open的端口上进行探测。
ports 21,43,110
totalwaitms十分少见,其功能是指出nmap等待响应的时间。一般默认的就好。
totalwaitms 6000
tcpwrappedms更加少见,只在null probe(不发送数据的TCP探测)中使用,如果在设置的时间内服务器就关闭了TCP连接,那么就会将这次探测标记为TCP wrapped.
tcpwrappedms 3000
rarity指出这个探测包得到响应的几率。rarity是一个0-9的数字,rarity越高,那么越难出现。用户可以指定扫描时扫描哪些rarity的服务。例如用户指定只发送rarity为8及以下的探测包,那么就不会对标记为rarity为9的服务进行探测以加快速度。
rarity 6
fallback和探测顺序有关。某个探测包写明了fallback时,如果探测包自带的match一个都探测不到,那么应该尝试fallback中的探测。
这是因为,接收到的包不一定是该probe对应的包,而是之前发送的其它probe响应的。
一个简单的例子: 对于Apache server,GET HTTP得不到结果,但是HTTP OPTIONS可以得到结果,当OPTIONS的match不匹配时,应该查看GET中的match能否匹配。
fallback GetRequest,GenericLines
探测流程
可以利用上述指令描述nmap对一个主机进行TCP端口扫描的过程:
- 首先,查看哪些端口是打开的,排除Exclude指令指明的端口。
- 对能建立起TCP连接的端口进行null probe,即等待5秒左右查看有没有主动发包,如果匹配到了null probe的match,那么该端口扫描结束。
- 对于null probe失败的端口,nmap会搜索该端口被包含在哪些探测包的ports中,并发送这些probe进行扫描(按照数据库文件从上到下的顺序)。对于非指定rarity的probe不会发送探测包。
- 对于没有match的结果,在fallback列表中中进行匹配。
- 对于full match(而非soft match)的结果,提取版本号等serviceinfo信息。
nmap对服务识别的实现
具体实现位于根目录下的service_scan.cc文件中,处理数据库文件语法规则的是ServiceProbeMatch类。
其中 Initmatch() 函数负责处理并提取正则表达式,网络数据包的发送由nsock提供,在service_scan()函数中调用。
网友评论