扫描器原理总结

我们分以下几种类型来分析扫描器原理:

  • 端口扫描
  • 服务检测
  • 操作系统检测

端口扫描

一般我们使用以下协议进行端口扫描:

  • TCP
  • UDP
  • ICMP

TCP 端口扫描

  1. TCP connect 扫描
  2. TCP SYN 扫描
  3. TCP Xmas Tree 扫描
  4. TCP null 扫描
  5. TCP ACK 扫描
# TCP connect 扫描

与目标端口建立3次握手,如果成功建立则为open,收到RST则为close

TCP connect 扫描
# TCP SYN 扫描

也称为TCP半连接扫描,只发送三次握手的第一次SYN报文段,如果收到ACK+SYN则为open,收到RST则为close,这种好处是不必等待三次握手完全完成,速度快且不容易被防火墙记录进日志。

TCP SYN 扫描
# TCP Xmas Tree 扫描

客户端向服务端发送带有 PSHFINURG 标识的数据包(即不含有ACK SYN RST),被称为TCP Xmas Tree扫描。其利用的是RFC的规定:

1
如果不设置SYN,RST,或者ACK位的报文发送到开放端口,理论上,这不应该发生,如果您确实收到了,丢弃该报文,返回。

那么有以下规则:

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

空扫描即flag位全0,如果没有回复则为open,收到RST则为close

TCP null 扫描
# TCP ACK 扫描

这种扫描无法得知端口的开放状态,只能探知端口是否被过滤,因为无论端口开放与否都会返回RST报文段。

TCP ACK 扫描

UDP 扫描

UDP扫描比较简单,一般如果返回ICMP port unreachable说明端口是关闭的,而如果没有回应或有回应(有些UDP服务是有回应的但不常见)则认为是open,但由于UDP的不可靠性,无法判断报文段是丢了还是没有回应,所以一般扫描器会发送多次,然后根据结果再判断。这也是为什么UDP扫描这么慢的原因。

UDP 扫描

ICMP 扫描

ICMP结构
  • 类型字段:指明该数据包属于什么大分类
  • 代码字段:指明数据包属于大类里面的哪个小类
  • 校验和 : 指明该数据包的校验和

除了正常的ICMP echo(发送回显Type=8,返回Type=0,或不可达Type=3),高级ICMP扫描技术采用的是ICMP数据报错误处理。

根据网络协议,如果按照协议出现了错误,那么接收端将产生一个icmp的错误报文。这些错误报文并不是主动发送的,而是由于错误,根据协议自动产生。

所有Type类型如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
0 响应应答(ECHO-REPLY)
3 不可到达
4 源抑制
5 重定向
8 响应请求(ECHO-REQUEST)
11 超时
12 参数失灵
13 时间戳请求
14 时间戳应答
15 信息请求(*已作废)
16 信息应答(*已作废)
17 地址掩码请求
18 地址掩码应答

常见错误利用如下:

ICMP错误利用

服务版本检测

我们以nmap的版本检测为例,观察nmap-service-probes文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# This is the NULL probe that just compares any banners given to us
##############################NEXT PROBE##############################
Probe TCP NULL q||
# Wait for at least 6 seconds for data. It used to be 5, but some
# smtp services have lately been instituting an artificial pause (see
# FEATURE('greet_pause') in Sendmail, for example)
totalwaitms 6000
# If the service closes the connection before 3 seconds, it's probably
# tcpwrapped. Adjust up or down depending on your false-positive rate.
tcpwrappedms 3000
match 1c-server m|^S\xf5\xc6\x1a{| p/1C:Enterprise business management server/
match 4d-server m|^\0\0\0H\0\0\0\x02.[^\0]*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0$|s p/4th Dimension database server/ cpe:/a:4d_sas:4d/
match aastra-pbx m|^BUSY$| p|Aastra/Mitel 400-series PBX service port|
match acap m|^\* ACAP \(IMPLEMENTATION \"CommuniGate Pro ACAP (\d[-.\w]+)\"\) | p/CommuniGate Pro ACAP server/ v/$1/ i/for mail client preference sharing/ cpe:/a:stalker:communigate_pro:$1/
match acarsd m|^g\0\0\0\x1b\0\0\0\0\0\0\0acarsd\t([\w._-]+)\tAPI-([\w._-]+)\)\0\0\0\x06\x05\0\0\0\0\0\0<\?xml | p/acarsd/ v/$1/ i/API $2/ cpe:/a:acarsd:acarsd:$1/
match acmp m|^ACMP Server Version ([\w._-]+)\r\n| p/Aagon ACMP Inventory/ v/$1/
match apachemq m|^\0\0..\x01ActiveMQ\0\0\0.\x01\0\0.*\x0cProviderName\t\0\x08ActiveMQ.*\x0fPlatformDetails\t..JVM: (\d[^,]*), [^,]*, Oracle Corporation, OS: Linux, (\d\.[\d.]+)[^,]*, ([\w_-]+).*\x0fProviderVersion\t..(\d[\w._-]*)|s p/ActiveMQ OpenWire transport/ v/$4/ i/Java $1; arch: $3/ o/Linux $2/ cpe:/a:apache:activemq:$4/ cpe:/o:linux:linux_kernel:$2/a
softmatch apachemq m|^\0\0..\x01ActiveMQ\0| p/ActiveMQ OpenWire transport/

我们可以看到,发送了一个NULL探针,正则匹配相应的banner内容来确定服务

操作系统检测

查看nmap-os-db,内容如下,截取了一段,好像….有点难读:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Acorp-W422G, wireless ADSL router.
# Linux 2.4.17_mvl21-malta-mips_fp_le (root@home1.homework) (gcc version 2.95.3 20010315 (release/MontaVista)) #1 Sat Sep 8 00:03:33 MSD 2007, Acorp-W400G ADSL and Wi-Fi router,
Fingerprint Acorp W400G or W422G wireless ADSL modem (MontaVista embedded Linux 2.4.17)
Class Acorp | embedded || WAP
SEQ(SP=C2-CC%GCD=1-6%ISR=C7-D1%TI=Z%II=I%TS=7)
OPS(O1=M5B4ST11%O2=M5B4ST11%O3=M5B4NNT11%O4=M5B4ST11%O5=M5B4ST11%O6=M5B4ST11)
WIN(W1=16A0%W2=16A0%W3=16A0%W4=16A0%W5=16A0%W6=16A0)
ECN(R=Y%DF=Y%T=3B-45%TG=40%W=16D0%O=M5B4NNS%CC=N%Q=)
T1(R=Y%DF=Y%T=3B-45%TG=40%S=O%A=S+%F=AS%RD=0%Q=)
T2(R=N)
T3(R=N)
T4(R=N)
T5(R=Y%DF=Y%T=FA-104%TG=FF%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)
T6(R=N)
T7(R=N)
U1(DF=N%T=FA-104%TG=FF%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)
IE(DFI=N%T=FA-104%TG=FF%CD=S)
# This is a GT701, which is issued by QWEST.
Fingerprint Actiontec GT701 DSL modem
Class Actiontec | embedded || broadband router
CPE cpe:/h:actiontec:gt701 auto
SEQ(SP=C8-D2%GCD=1-6%ISR=CC-D6%TI=Z%II=I%TS=7)
OPS(O1=M5B4ST11NW0%O2=M5B4ST11NW0%O3=M5B4NNT11NW0%O4=M5B4ST11NW0%O5=M5B4ST11NW0%O6=M5B4ST11)
WIN(W1=16A0%W2=16A0%W3=16A0%W4=16A0%W5=16A0%W6=16A0)
ECN(R=Y%DF=Y%T=3B-45%TG=40%W=16D0%O=M5B4NNSNW0%CC=Y%Q=)
T1(R=Y%DF=Y%T=3B-45%TG=40%S=O%A=S+%F=AS%RD=0%Q=)
T2(R=N)
T3(R=N)
T4(R=N)
T5(R=Y%DF=Y%T=FA-104%TG=FF%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)
T6(R=N)
T7(R=N)
U1(DF=N%T=FA-104%TG=FF%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)
IE(DFI=N%T=FA-104%TG=FF%CD=S)

根据注释可以看到第一个是linux以及一些分类信息,下面的就是特征数据.

每一行都是一项测试的结果,其中 XXX() 中的 XXX 是测试的名字(例如SEQOPS测试)。括号内以 % 分隔的各项是测试中的各种指标。每项指标的值都是key-value形式.

所有的测试分成五组,

1
2
3
4
5
第一组测试包含 SEQ、OPS、WIN、T1。这项测试会发送六个 TCP 包,然后检查响应的各种细节。
第二组测试是 IE,会发送两个不同的 ICMP echo 请求,检测其响应特征。
第三组测试是 U1,发送一个 UDP 包给一个关闭的端口,然后看下 ICMP 的 port unreachable 回复。
第四组测试是 ECN,全称是 Explicit Congestion Notification,即“显式拥塞通知”。该测试会发送带 ECN 位的 TCP 请求,比较其响应。
最后一组是发送六个不同的 TCP 包,这六个 TCP 包的响应结果将对应T2T7的各项指标,其中 T2-T4 会发给打开的 TCP 端口,T5-T7 会发给关闭的 TCP 端口。