7. 主动信息收集-端口扫描
端口扫描(四层)
当我们发现存活主机ip后,接下来就是确定这些活着的ip上面有哪些开放的端口,每个服务器都会跑很多应用,每个应用会侦听某些端口,通过侦听这些端口来接受来自客户端和用户对应用程序的访问。
这些应用程序的漏洞都是通过端口来体现出来的,后面渗透测试如果能够攻击进入操作系统也是从端口进入,这些端口都会成为后续攻击面的一个体现。
端口扫描使用的技术其实与发现阶段一样的。
UDP端口扫描
发现阶段确认是活着的ip,这时候我们扫描是没有不在线的ip的,所以对于在线ip进行UDP扫描也就是两种情况,端口开了和没开。
此时判断思路与发现阶段相反,发现阶段是依靠判断对方没有打开端口,通过返回端口不可达来确定主机是存在的,而现在返回ICMP端口不可达的信息是我们不关心的,只有那些没有响应的端口,我们认为它是开放的。
一些特殊情况(对于返回消息进行了处理),会导致扫描所有端口都是没有回复-55
-
假设ICMP port-unreachable 响应代表端口关闭
- 目标系统不响应ICMP port-unreachable时,可能会产生误判
-
完整的UDP应用层请求
- 准确性高
- 耗时巨大
tcp和udp各有 有6万多个端口,如果全部扫描准确性还是比较高的,但是数量太多,耗时比较大
#!/usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import*
import sys
if len( sys.argv ) !=4:
print "Example - ./syn_scan.py 1.1.1.1 1 100"
sys.exit()
ip = str(sys.argv[1])
start = int(sys.argv[2])
end = int(sys.argv[3])
for port in range(start,end+1):
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
TCP端口扫描
- 基于连接的协议
- 三次握手
- 隐蔽扫描
- 僵尸扫描
- 全连接扫描
- 所有的TCP扫描方式都是基于三次握手的变化来判断目标端口状态

1.全连接扫描
建立完整三次握手
2.隐蔽扫描——syn
不建立完整连接,只发送syn包,如果收到ack/syn即可判断端口开发,如果没有开放会收到rst
- 由于没有建立完整连接,因此应用层日志不会记录扫描行为——隐蔽,网络层还是会留下迹象的。
使用scapy给192.168.1.1的22端口发送ack包
a=sr1(IP(dst="192.168.1.1")/TCP(flags="S",dport=22), timeout=1, verbose=0)
>>> a=sr1(IP(dst="192.168.1.1")/TCP(flags="S",dport=22), timeout=1, verbose=0)
>>> a.display()
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 40
id = 28556
flags = DF
frag = 0
ttl = 64
proto = tcp
chksum = 0x47ec
src = 192.168.1.1
dst = 192.168.1.6
\options \
###[ TCP ]###
sport = ssh
dport = ftp_data
seq = 0
ack = 1
dataofs = 5
reserved = 0
flags = RA
window = 0
chksum = 0x2c4e
urgptr = 0
options = []
收到返回的ack/syn包,这样可以判断tcp的22端口时开放的

python脚本
tcp隐蔽扫描——syn脚本
flags=18代表ack+syn位为1
#!/usr/bin/python
#该脚本用户实现扫描目标主机中开放的TCP端口
from scapy.all import*
import sys
if len( sys.argv ) !=4:
print "Example - ./syn_scan.py 1.1.1.1 1 100"
sys.exit()
ip = str(sys.argv[1])
start = int(sys.argv[2])
end = int(sys.argv[3])
for port in range(start,end+1):
a=sr1(IP(dst=ip)/TCP(dport=port),timeout=0.1,verbose=0)
if a ==None:
pass
else:
if int(a[TCP].flags)==18: #SYN+ACK值为18
print (port)
else:
pass
nmap隐蔽端口扫描
不指定-sS也使用的是
- 加上–open后只显示打开端口,如果在防火墙后面可能会把一些cclose状态的端口也显示出来
nmap -sS 1.1.1.1 -p 80,443,110
nmap -sS 1.1.1.1 -p -65535 --open
nmap -sS 1.1.1.1 -p --open
nmap -sS -iL iplist.txt -p -80

扫描过程中,先使用DNS查询ptr记录,看看ip地址能不能反向解析一个主机名,解析失败后进行端口扫描,随机扫描端口,
hping3 进行syn隐蔽扫描
顺序扫描端口
hping3 1.1.1.1 -scan 80 -S
hping3 1.1.1.1 -scan 80,35,443 -S
hping3 1.1.1.1 -scan 0-65535 -S
hping3 -c 10 -S -spoof 1.1.1.2 -p ++1 1.1.1.3//伪造源地址为1.1.1.2,扫描1.1.1.3,这样需要去1.1.1.2上去查看收到哪些syn/ack包
全连接扫描
在一些情况下,syn包无法成功的情况下(防火墙过滤等等),需要用到全连接扫描,一般很少使用,因为不隐蔽,很容易触发目标报警系统
scapy实现
scapy对全连接扫描比较困难,如果直接给目标系统发SYN,目标系统会回应一个SYN/ACK,这时候,操作系统内核会认为没建立完整的连接,会返回一个RST,断开TCP连接,此时,如果在向目标系统发送一个ACK,目标系统会回应RST;
若需要让操作系统不产生RST包,影响后续的操作,就需要添加一定的防火墙策略,讲操作系统系统内核产生的RST包drop掉;
使用策略:iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 192.168.1.1 -j DROP
#!/usr/bin/python
#该脚本用于与目标主机建立全连接的端口扫描需要进行iptable配合
from scapy.all import *
SYN=IP(dst="192.168.1.1")/TCP(dport=80,flags="S")
print("-- SENT --" )
SYN.display()
print("\n\n-- REVEIED" )
response=sr1(SYN,timeout=1,verbose=0)
response.display()
if int(response[TCP].flags)==18:
print ("\n\n-- SENT --" )
A=IP(dst="192.168.1.1")/TCP(dport=80,flags="A",ack=(response[TCP].seq+1))
A.display()
response2=sr1(A,timeout=1,verbose=0)
else:
print ("SYN-ACK not returned")

nmap全连接扫描
root@root:~# nmap -sT 192.168.1.1 -p 1-100 #扫描1-100端口
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-27 23:47 EDT
Nmap scan report for 192.168.1.1 (192.168.1.1)
Host is up (1.0s latency).
Not shown: 97 closed ports
PORT STATE SERVICE
21/tcp open ftp
23/tcp open telnet
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 6.41 seconds
---
root@root:~# nmap -sT 192.168.1.1 -p 22,25,28,80 #扫描指定的端口
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-27 23:48 EDT
Nmap scan report for 192.168.1.1 (192.168.1.1)
Host is up (0.00076s latency).
PORT STATE SERVICE
22/tcp filtered ssh
25/tcp filtered smtp
28/tcp filtered unknown
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 1.33 seconds
root@root:~# nmap -sT 192.168.1.1 #扫描1000个常见端口
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-27 23:48 EDT
Nmap scan report for 192.168.1.1 (192.168.1.1)
Host is up (1.0s latency).
Not shown: 989 closed ports
PORT STATE SERVICE
21/tcp open ftp
23/tcp open telnet
80/tcp open http
139/tcp filtered netbios-ssn
443/tcp filtered https
445/tcp open microsoft-ds
514/tcp filtered shell
1119/tcp filtered bnetgame
8080/tcp open http-proxy
32768/tcp open filenet-tms
52869/tcp open unknown
Nmap done: 1 IP address (1 host up) scanned in 108.16 seconds
全连接端口扫描——dmitry
- 功能简单,使用简便;
- 默认150个最常用的端口;
root@root:~# dmitry -p 192.168.1.1
Deepmagic Information Gathering Tool
"There be some deep magic going on"
HostIP:192.168.1.1
HostName:192.168.1.1
Gathered TCP Port information for 192.168.1.1
---------------------------------
Port State
21/tcp open
23/tcp open
80/tcp open
全连接端口扫描——nc
nc的扫描通过-c参数实现
root@root:~# nc -nv -w 1 -z 192.168.1.1 1-100
(UNKNOWN) [192.168.1.1] 90 (?) : Connection timed out
(UNKNOWN) [192.168.1.1] 89 (?) : Connection timed out
(UNKNOWN) [192.168.1.1] 88 (kerberos) : Connection timed out
僵尸扫描
- 极其隐蔽
- 实施条件苛刻
- 可以伪造源地址
- ipid是递增的
- 选择僵尸机(闲置机)
- 向僵尸机发送syn/ack数据包,会收到rst包,里面会有ipid=x
- 向目标主机发送syn包,需要伪造源地址为僵尸机,如果端口开发,目标主机就会向来源ip(僵尸机)发送syn/ack。僵尸机收到后,由于它没有发送过包,不是正常数据包,会返回rst包,里面ipid=x+1
- 目标主机向僵尸机发送syn/ack,收到rst包,内部ipid=x+2.
为什么要足够闲置,因为不闲置,这期间就会发生新的ipid递增,发起者就无法判断。
python脚本
//判断僵尸主机部分有问题
#!/usr/bin/python
# -*- coding: utf-8 -*-
# 该脚本用于识别僵尸机,并使用僵尸机对目标主机进行端口扫描
from scapy.all import *
import time
import sys
def IsZombie(zombie_ip): #判断僵尸机是否是一个合格的僵尸机
a1 = sr1(IP(dst = zombie_ip)/TCP(flags = "SA", dport = 445),timeout = 1,verbose = 0)
time.sleep(2) #给僵尸机充足的时间,以判断僵尸机网络是否繁忙
a2 = sr1(IP(dst = zombie_ip)/TCP(flags = "SA", dport = 445),timeout = 1,verbose = 0)
if (a1[IP].id + 1) == a2[IP].id: #比较两次ipid值
print ("this is a good zombie!")
action = raw_input("do you want to use this zombie?(y/n)")
if action == "y":
target_ip = raw_input("please input the target's ip:") #目标主机ip
scan(zombie_ip,target_ip)
else:
sys.exit()
else:
print ("this is not a good zombie!")
def scan(zombie_ip,target_ip):
print("\nScanning target:"+target_ip+" with zombie:"+zombie_ip)
print("\n------------------Open Ports on Target---------------\n")
for port in range(1,100):
try:
start_val=sr1(IP(dst=zombie_ip)/TCP(flags="SA",dport=port),timeout=2,verbose=0) #给僵尸机发送第一个SYN/ACK数据包
send(IP(dst=target_ip,src=zombie_ip)/TCP(flags="S",dport=port),verbose=0) #给目标主机发送一个伪造原地址的SYN数据包
end_val = sr1(IP(dst=zombie_ip)/TCP(flags="SA"),timeout=2,verbose=0) #给僵尸机发送第二个SYN/ACK数据包
if (start_val[IP].id+2) == end_val[IP].id: #比较ipid值,从而判断端口是否开放
print(port)
except:
pass
print("------------------Zombie Scan Suite-------------------\n")
ip = raw_input("the zombie's ip:")
IsZombie(ip)
使用nmap实现僵尸扫描
判断僵尸主机是否合格
调用脚本,_ipidseq: Incremental!表示ipid为顺序递增
root@kali:~/Desktop# nmap -p445 192.168.1.1 --script=ipidseq.nse
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-28 01:17 EDT
Nmap scan report for 192.168.1.1 (192.168.1.1)
Host is up (0.00076s latency).
PORT STATE SERVICE
445/tcp open microsoft-ds
Host script results:
|_ipidseq: Incremental!
Nmap done: 1 IP address (1 host up) scanned in 0.72 seconds
sI:指定僵尸扫描的参数
前面的ip为目标主机,后面为僵尸机
nmap 192.168.1.7 -sI 192.168.1.1 -Pn -p 1-150
僵尸扫描
oot@kali:~/Desktop# nmap 192.168.1.6 -sI 192.168.1.1 -Pn -p 130-140
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-28 01:40 EDT
Idle scan using zombie 192.168.1.1 (192.168.1.1:80); Class: Incremental
Nmap scan report for pc-20190715ykdz (192.168.1.6)
Host is up (0.31s latency).
PORT STATE SERVICE
130/tcp closed|filtered cisco-fna
131/tcp closed|filtered cisco-tna
132/tcp closed|filtered cisco-sys
133/tcp open statsrv
134/tcp open ingres-net
135/tcp closed|filtered msrpc
136/tcp open profile
137/tcp open netbios-ns
138/tcp closed|filtered netbios-dgm
139/tcp open netbios-ssn
140/tcp closed|filtered emfis-data
正常扫描
root@kali:~# nmap 192.168.1.6 -p 1-150
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-28 01:39 EDT
Nmap scan report for pc-20190715ykdz (192.168.1.6)
Host is up (1.0s latency).
Not shown: 148 closed ports
PORT STATE SERVICE
135/tcp open msrpc
139/tcp open netbios-ssn