目录

Nmap端口扫描技术

Nmap端口扫描技术

Nmap支持很多种类型的端口扫描, 配置扫描类型的参数是 -sC, 其中 C 是扫描类型名称中的一个重要字母, 通常是首字母. 只有一种例外, 就是FTP弹跳扫描, 使用参数 -b . 默认情况下, Nmap执行SYN扫描 (在非特权用户下, 不能使用raw socket时, 会使用connect扫描代替). 在所有的Nmap端口扫描类型中, 只有connect和FTP弹跳扫描可以在非特权用户下执行

TCP SYN扫描

参数 : -sS

SYN扫描是最流行的一种扫描方式, 他有以下优点

  • 执行速度快, 如果没有被防火墙限制, 扫描数千个端口只需要几秒钟.
  • 相对比较隐蔽, 因为SYN扫描不需要完成TCP连接的全部过程.
  • 兼容性好, 不像 FIN/NULL/Xmas, Maimon和空闲扫描 依赖于特定平台的协议栈实现, SYN扫描比较通用
  • 区分度高, 可以很明确的区分open, closedfiltered几种端口状态
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
@startuml
Nmap -> Target: SYN
alt open
Target -> Nmap: SYN/ACK
Nmap -> Target: RST
else closed
Target -> Nmap: RST
else filtered
	opt timeout
	Nmap -> Target: SYN (Retransmission)
	else ICMP unreachable
	Target -> Nmap: ICMP unreachable error\n(type=3, code 0,1,2,3,9,10,13)
	end
end
@enduml

TCP connect扫描

参数: -sT

当SYN扫描不可用(非特权用户不能发送裸报文) 时, connect扫描会作为默认的扫描方式. 因为需要完整的创建TCP连接, 所以相比于SYN扫描:

  • 耗时长, 因为需要发送更多的包
  • 隐蔽性差, 目标机器很有可能会记录连接. 入侵检测系统IDS会检测到这种行为, 这种创建连接不发送任何数据直接关闭连接的行为,很多服务也会记录系统日志

UDP扫描

参数: -sU

UDP服务在网络中也被广泛使用, 如DNS, SNMP, DHCP. UDP扫描一般比TCP扫描更慢也更困难

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
@startuml
Nmap -> Target: UDP Packet
note right
1. 对于一些常用著名的服务端口如53,161
   Nmap默认携带payload, 增加收到响应的概率
2. 对于其他大多数端口
   nmap不会自动携带任何payload
   除非使用--data,--data-string,--data-length参数指定
end note

alt closed
Target -> Nmap: ICMP port unreachable error \n (type 3, code 3)
else filtered
Target -> Nmap: ICMP unreachable error \n (type 3, code 0,1,2,9,10,13)
else open
Target -> Nmap: UDP Packet (Response)
else open|filtered
Nmap -> Target: UDP Packet (retransmission)
note right: 可以使用-sV参数帮助区分open和filtered状态
end
@enduml

UDP扫描最大的问题是慢, openfiltered的端口通常都很少回复响应, Nmap必须要等待直到超时. closed状态的端口问题更大, 通常它应该回复 ICMP port unreachable error. 但是跟TCP扫描中SYN扫描不一样的是, SYN扫描中RST包可以随便发, 但是ICMP port unreachable消息通常是受限的. linux和Solaris限制的尤其严格. 例如, 在Linux 2.4.20内核版本中, 限制目的不可达消息每秒最多发送1个

Nmap检测到频率限制后会减缓发送UDP的频率, 因为发送也没有用. 所以, 在一个频率限制在每秒最多1个的Linux系统扫描65536个端口需要花费超过18个小时. 提升速度的方式有:

  • 并发扫描多个机器
  • 尽量扫描常用的端口
  • 使用--host-timeout参数来跳过慢的机器

TCP NULL/FIN/Xmas扫描

参数: -sN/-sF/-sX

这三种扫描方式使用RFC793中的一个巧妙的方法来区分openclosed状态

如果端口是关闭状态…发送一个未设置RST标志的包应该返回一个RST响应 如果端口是开放状态, 发送一个没有设置SYN, RSTACK标志的包, 理论上不应该收到这种包, 如果收到了, 那就直接忽略

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@startuml
Nmap -> Target: TCP Package(without SYN,RST,ACK)
alt closed
Target -> Nmap: RST
else open|filtered
Nmap -> Target: TCP Retransmission
else filtered
Target -> Nmap: ICMP unreachable error (type 3, code 0,1,2,3,9,10,13)
end
@enduml
  • Null扫描(-sN): TCP flag全部为0

  • FIN扫描(-sF): 只设置FIN 标记

  • Xmas扫描(-sX): 设置FIN, PSH, URG, 就像点亮圣诞树 这三种扫描的行为模式都是一样的

  • 隐蔽性好: 可以绕过一些无状态防火墙和报文过滤路由器. 比SYN扫描更隐秘, 但是现在大多数的IDS仍然可以发现.

  • 兼容性差: 并非所有系统都严格遵守RFC793, 很多系统不管端口是开放还是关闭都会回复RST. 这种情况下所有的端口都会返回closed, 比如Windows, 很多Cisco设备, BSDI, IBM OS/400. 这种扫描类型主要用于很多Unix系统的扫描.

  • 区分度差: 不能区分openfiltered的端口, 只能判断成open|filtered

TCP Maimon扫描

Maimon扫描是用它的发现者Uriel Maimon命名的. 这项技术和Null/FIN/Xmas扫描完全一样, 除了探测报文是FIN/ACK. 根据RFC793, 无论端口是开放或者关闭的, 都应该对这样的报文响应RST. 但是Uriel发现如果端口开放, 很多基于BSD的系统只会丢弃这种报文

TCP ACK扫描

参数: -sA

这种扫描类型是用于发现防火墙规则的, 判断防火墙是有状态的还是无状态的, 那些端口是被过滤的. 不能区分open或者open|filtered端口,

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@startuml
Nmap -> Target: ACK
alt unfiltered
Target -> Nmap: RST
else filtered
	opt timeout
	Nmap -> Target: ACK(Retransmission)
	else
	Target -> Nmap: ICMP unreachable error(type3, code 0,1,2,3,9,10,13)
	end
end
@enduml

TCP 窗口扫描

TCP窗口扫描雨ACK扫描基本一样, 与ACK扫描不同的是, 它会根据一些特定系统的实现来区分openclosed状态. 当收到RST响应时, 它会根据RST报文的TCP窗口值来判断. 在特定的系统中, 开放端口用正数来表示窗口大小(甚至是RST报文), 而关闭端口的窗口大小是0.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
@startuml
Nmap -> Target: ACK
alt unfiltered
Target -> Nmap: RST
	alt open
	Nmap -> Nmap: TCP Window > 0
	else closed
	Nmap -> Nmap: TCP Window == 0
	end
else filtered
	alt timeout
	Target -> Nmap: ACK(Retransmission)
	else unreachable
	Target -> Nmap: ICMP unreachable error(type 3, code 0,1,2,3,9,10,13)
	end
end
@enduml

这种扫描依赖于互联网上少数系统的实现细节, 不总是可信的. 不支持的系统所有的端口都会返回clsoed. 当然也有可能是真的没有开放任何端口. 如果大多数的端口是closed, 只有少量端口是filtered(比如22, 25, 53), 那这个结果可信度就比较大了. 有时候, 系统甚至可能表现完全相反, 如果你扫描发现了1000个open状态的端口, 3个closed或者filtered的端口, 那有可能实际上那3个才是开放的端口

定制化TCP扫描

 --scanflags选项允许通过指定任意TCP标志位来设计自己的扫描。躲开那些仅靠Nmap手册添加规则的入侵检测系统

--scanflags选项可以是一个数字标记值如9 (PSH和FIN), 但使用字符名更容易些。 只要是URG, ACKPSH, RSTSYN,and FIN的任何组合就行。例如,--scanflags URGACKPSHRSTSYNFIN设置了所有标志位。 标志位的顺序不重要。

除了设置需要的标志位,也可以设置 TCP扫描类型(如-sA或者-sF)。 那个基本类型告诉Nmap怎样解释响应。例如, SYN扫描认为没有响应意味着 filtered端口,而FIN扫描则认为是 open|filtered。 除了使用您指定的TCP标记位,Nmap会和基本扫描类型一样工作。 如果不指定基本类型,就使用SYN扫描。

空闲扫描

空闲扫描是指某些特定的系统IP报文的ID是以此递增的, 每发送一个报文ID加一, 如果网络上存在一台这样的主机, 而且这个主机足够空闲, 那就可以利用这种主机对目标系统发起扫描

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
@startuml
Attacker -> Zombie: SYN/ACK
Zombie -> Attacker: RST**(IP ID=1)**
note over Attacker,Zombie: Step1 - Probe the zombie's IP ID
Attacker -> Target: SYN 'from' zombie
note right: Step2 - Forge a SYN package from the zombie
alt open
	Target -> Zombie: SYN/ACK
	Zombie -> Target: RST**(IP ID=2)**
else closed
	Target -> Zombie: RST
else filtered
end
Attacker -> Zombie: SYN/ACK
Zombie -> Attacker: RST(**IP ID=2 or 3**)
note right: adjust the port is open or closed|filtered
@enduml

空闲扫描的详细介绍参考: https://nmap.org/book/idlescan.html

IP协议扫描

IP 协议扫描可以让您确定目标机支持哪些IP协议 (TCP,ICMP,IGMP,等等)。从技术上说,这不是端口扫描 ,它遍历的是IP协议号而不是TCP或者UDP端口号。 但是它仍使用 -p选项选择要扫描的协议号, 甚至用和真正的端口扫描一样 的扫描引擎。因此它和端口扫描非常接近,也被放在这里讨论。

协议扫描以和UDP扫描类似的方式工作。它是在IP协议域的8位上循环,发送IP报文头。 报文头通常是空的,不包含数据,甚至不包含所申明的协议的正确报文头, TCP,UDP,和ICMP是三个例外。它们三个会使用正常的协议头,因为否则某些系统拒绝发送,协议扫描不是注意ICMP端口不可到达消息, 而是ICMP 协议不可到达消息。

  • 如果Nmap从目标主机收到任何协议的任何响应,Nmap就把那个协议标记为open
  • ICMP协议不可到达 错误(code 3,type 2) 导致协议被标记为 closed
  • 其它ICMP不可到达协议(code 3,type 1,3,9,10,13) 导致协议被标记为 filtered (虽然同时他们证明ICMP是 open )。
  • 如果重试之后仍没有收到响应, 该协议就被标记为open|filtered

FTP弹跳扫描

一种很老的扫描方式, 如果获取到一个内网的有漏洞的FTP服务器, 可以用FTP弹跳扫描的方式来获取到一些信息