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

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端口时开放的

2

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

3

扫描过程中,先使用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")

4

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是递增的
  • 选择僵尸机(闲置机)
  1. 向僵尸机发送syn/ack数据包,会收到rst包,里面会有ipid=x
  2. 向目标主机发送syn包,需要伪造源地址为僵尸机,如果端口开发,目标主机就会向来源ip(僵尸机)发送syn/ack。僵尸机收到后,由于它没有发送过包,不是正常数据包,会返回rst包,里面ipid=x+1
  3. 目标主机向僵尸机发送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