共计 2619 个字符,预计需要花费 7 分钟才能阅读完成。
相比于 UDP 的端口扫描,基于 TCP 的扫描将会复杂很多。TCP 的扫描方式都是基于连接的三次握手的变化来判断目标端口的状态。TCP 可以进行隐蔽扫描,僵尸扫描(比隐蔽扫描更隐蔽的扫描方式),全连接扫描(基于完整的三次握手)
隐蔽扫描
不建立完整的连接,而是只发送 SYN 包,如果对方回复 ACK 表示目标端口是开放的,如果回复 RST 表示目标端口未开放,接下来不再发送第三次的 ACK 确认,由此也不会建立起正常的 TCP 连接,应用层日志不会有任何记录,但是网络层有迹象可循
僵尸扫描
极度隐蔽,但是实施条件苛刻,可伪造源地址。僵尸扫描的苛刻条件之一就是发起方必须伪造 IP 地址;二是选择的僵尸机必须是闲置状态的并且这些操作系统的 IPID(ip 包头里的 ip 字段)必须是递增的,IPID 不能是随机的或者永远是 0
隐蔽端口扫描
扫描环境:
Kali_64B:192.168.0.108
Kali_64B_Target: 192.168.0.110
win10: 192.168.0.107
用 Kali_64B 来扫描 Kali_64B_Target 和 win10 的端口:
首先在 Kali_64B 中利用 scapy 制作一个基于 TCP 的 SYN 包(不指定端口的情况下扫描的是 80 端口):
res=sr1(IP(dst="192.168.0.103")/TCP(flags="S"),timeout=1,verbos=0)
flags=RA(RST+ACK),即端口关闭
指定目标端口进行扫描:
res=sr1(IP(dst="192.168.0.103")/TCP(flags="S",dport=22),timeout=1)
22 端口也没开
scapy 脚本扫描:
#!/usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
if len(sys.argv) != 4:
print "Usage - ./udp_port.py [Target - TP] [First port] [Last port]"
print "Usage - ./udp-port.py 128.13.34.13 1 100"
sys.exit()
ip = sys.argv[1]
start = int(sys.argv[2])
end = int(sys.argv[3])
for port in range(start, end):
a = sr1(IP(dst=ip)/TCP(dport=port),timeout=1,verbose=0)
if a == None:
pass
else:
if int(a[TCP].flags) == 18:
print port
else:
pass
目标机如果开了防火墙,扫不到端口
nmap 的 TCP 隐蔽端口扫描
namp -sS -p[start-port]-[end-port] ip
namp -sS -p[start-port]-[end-port] ip --open(--open 只显示端口状态为 open 的端口)
hping3 基于 SYN 的隐蔽端口扫描
hping3 --scan 1-30,70-90 -S 192.168.0.109
hping3 -c 10 -S --spoof fake_source -p ++1 dst_ip
-c 10:发 10 个包
–spoof fake_source:将 IP 伪造成 fake_source 实现对源 IP 的隐藏
-p ++:从端口 1 开始,每次增加 1
当目标主机的端口是开放的那么它会发送一个 ACK 包给 fake_source,如果想要知道扫描的结果,那么必须具有登录拥有 fake_source IP 的主机才能看到
全连接端口扫描
用 SYN 包进行扫描时,如果在存在防火墙,或者网络条件十分苛刻时,可能无法判断目标端口是否开放,以此我们这时需要通过三次握手跟目标主机建立完整的 TCP 连接来进行试探,全连接的扫描结果准确率是最高的,但是不隐蔽,很容易触发目标网络层的报警系统
脚本:
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
SYN = IP(dst="192.168.86.132")/TCP(dport=25,flags="S")
print("---SENT---")
SYN.display()
#显示要发的包
print"\n\n---RECEIVED---"
response = sr1(SYN,timeout=1,verbose=0)
#将定义好的 SYN 包发送出去
response.display()
#----------------
#这里有问题,就是机器内核会认为 SYN/ACK
#是非法包,将会直接发送 RST 断开连接,导致三次握手(全连接)失败
#可以使用 linux 的自带防火墙 iptables 直接 DROP 掉由系统发出的 RST 包
#iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 192.168.86.132 -j DROP
#- A 新家一条规则,出站,-p tcp 表示使用 TCP 协议 - d 表示目标 ip,- j 表示动作
#----------------
if int(response[TCP].flags)==18:
#如果收到的回包是 SYN+ACK,那么 TCP 包头的 flags 将会是 18
print("\n\n---SENT---")
A = IP(dst="192.168.86.132")/TCP(dport=25,flags="A",ack=(response[TCP].seq+1))
#确定收到 syn+ack 相应,再次向目标发送 ACK 包确认,同时序列号加 1
A.display()
print("\n\n---RECRIVED---")
response2 = sr1(A,timeout=1,verbose=0)
response2.display()
else:
#如果没有收到 syn+ack 回应,将不做任何相应
print"SYN.ACK not returned"
nmap 进行 TCP 全连接扫描
namp -sT 192.168.86.134 -p 1-100
-sT:表示基于 TCP 连接的扫描;基于 TCP 的全连接扫描会较慢非全连接扫描
其它扫描工具
dmitry -P 192.168.86.34
nv -w 1 -z 192.168.14.112 1-100