使用Nmap进行端口扫描
在未经授权的情况下夺取计算机系统控制权的行为是 违法行为, 此篇文章仅作为学习交流和探讨,若要测试成果,请在自己虚拟机上测试,或者被允许渗透的计算机系统上演练, 请勿做出违法之骚操作,操作者做出的一切违法操作均与本人和此文无关
本文使用Nmap进行扫描,其他扫描手段本文不进行探讨
Nmap是端口扫描方面的业内标准,网上的资料让人眼花缭乱,时至今日,各式各样的防火墙已经普遍采用了入侵检测和入侵防御技术,他们能够有效地拦截常见的端口扫描,所以,即使使用Nmap程序扫描结果一无所获也不是什么意外的事。换句话说, 如果你在公网上对指定网段进行主机扫描时没检测出一台在线主机,那么就应当认为扫描行动多半是被防火墙系统拦截下来了,反之则是另一种极端情况:每台主机都在线,每个端口都处于开放状态
SYN扫描
所谓的SYN扫苗实际上是一种模拟TCP握手的端口扫描技术。TCP握手分为3个阶段:SYN、SYN-ACK、ACK。在进行SYN扫描时,Nmap程序向远程主机发送SYN数据包并等待对方的SYN-ACK数据。 如果在最初发送SYN数据包之后没有收到SYN-ACK响应,那么既定端口就不会是开放端口,在此情况下,既定端口不是关闭就是被过滤了
在使用Nmap扫描之前,可以先使用maltego之类的信息搜集工具分析出有用的信息。我使用一个非法网站的IP来作为演示
需要注意的是,某个端口是开放端口不代表这个端口背后的程序存在安全缺陷,我们仅能够通过开放端口初步了解计算机运行的应用程序,进而判断这个程序是否存在安全缺陷
版本扫描
虽然SYN扫描具有某种隐蔽性,但它不能告诉我们打开这些端口的程序到底是什么版本,如果说我们想要知道这台主机的某个端口在运行着什么程序以及它运行的版本,这在我们后期威胁建模阶段有极大的用处, 使用-sT或者-sV 即可查看
运气很好,看来这个网站运行的程序有安全漏洞,这个名为OpenSSH 5.3的软件存在着一个CVE-2016-10009漏洞,攻击者可以通过远程攻击openssh来获得服务器权限。我们在这里不做攻击操作,毕竟这是别人的网站,虽然是个违法网站。如果有机会后期笔者将会根据情况写一些关于漏洞利用的文章
UPD扫描
Nmap的SYN扫描和完整的TCP扫描都不能扫描UDP,因为UDP的程序采用无连接的方式传输。在进行UDP扫描时,Nmap将向既定端口发送UPD数据包,不过UDP协议的应用程序有着各自不同的数据传输协议,因此在远程主机正常回复该数据的情况下,能够确定既定端口处于开放状态。 如果既定端口处于关闭状态,那么Nmap程序应当收到ICMP协议的端口不可达信息。 如果没有从远程主机收到任何数据那么情况就比较复杂了,比如说:端口可能处于发放状态,但是响应的应用程序没有回复Nmap发送的查询数据,或者远程主机的回复信息被过滤了,由此可见 在开放端口和被防火墙过滤的端口方面,Nmap存在相应的短板
扫描指定端口
指定端口的扫描可能造成服务器崩溃,更好还是踏踏实实的彻底扫描全部端口 。就不拿别人的服务器来测试了,毕竟我也怕被报复,在这里我把渗透目标设置为我自己的xp靶机,步骤跟前面一样,扫描出端口查看是否有可利用程序,然后对想扫描的端口进行扫描
在渗透测试中,我们都不希望致使任何服务器崩溃,但是我们的确可能会遇到那些无法正确受理非预期输入的应用程序,在这种情况下,Nmap的扫描数据就可能引发程序崩溃
如何用Scapy写一个端口扫描器
常见的端口扫描类型有:
1. TCP 连接扫描
2. TCP SYN 扫描(也称为半开放扫描或stealth扫描)
3. TCP 圣诞树(Xmas Tree)扫描
4. TCP FIN 扫描
5. TCP 空扫描(Null)
6. TCP ACK 扫描
7. TCP 窗口扫描
8. UDP 扫描
下面先讲解每种扫描的原理,随后提供具体实现代码。
TCP 连接扫描
客户端与服务器建立 TCP 连接要进行一次三次握手,如果进行了一次成功的三次握手,则说明端口开放。
客户端想要连接服务器80端口时,会先发送一个带有 SYN 标识和端口号的 TCP 数据包给服务器(本例中为80端口)。如果端口是开放的,则服务器会接受这个连接并返回一个带有 SYN 和 ACK 标识的数据包给客户端。随后客户端会返回带有 ACK 和 RST 标识的数据包,此时客户端与服务器建立了连接。如果完成一次三次握手,那么服务器上对应的端口肯定就是开放的。
当客户端发送一个带有 SYN 标识和端口号的 TCP 数据包给服务器后,如果服务器端返回一个带 RST 标识的数据包,则说明端口处于关闭状态。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
tcp_connect_scan_resp = sr1(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=10)
if(str(type(tcp_connect_scan_resp))=="type 'NoneType'"):
print "Closed"
elif(tcp_connect_scan_resp.haslayer(TCP)):
if(tcp_connect_scan_resp.getlayer(TCP).flags == 0x12):
send_rst = sr(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="AR"),timeout=10)
print "Open"
elif (tcp_connect_scan_resp.getlayer(TCP).flags == 0x14):
print "Closed"
TCP SYN 扫描
这个技术同 TCP 连接扫描非常相似。同样是客户端向服务器发送一个带有 SYN 标识和端口号的数据包,如果目标端口开发,则会返回带有 SYN 和 ACK 标识的 TCP 数据包。但是,这时客户端不会返回 RST+ACK 而是返回一个只带有 RST 标识的数据包。这种技术主要用于躲避防火墙的检测。
如果目标端口处于关闭状态,那么同之前一样,服务器会返回一个 RST 数据包。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
stealth_scan_resp = sr1(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=10)
if(str(type(stealth_scan_resp))=="type 'NoneType'"):
print "Filtered"
elif(stealth_scan_resp.haslayer(TCP)):
if(stealth_scan_resp.getlayer(TCP).flags == 0x12):
send_rst = sr(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="R"),timeout=10)
print "Open"
elif (stealth_scan_resp.getlayer(TCP).flags == 0x14):
print "Closed"
elif(stealth_scan_resp.haslayer(ICMP)):
if(int(stealth_scan_resp.getlayer(ICMP).type)==3 and int(stealth_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print "Filtered"
TCP 圣诞树(Xmas Tree)扫描
在圣诞树扫描中,客户端会向服务器发送带有 PSH,FIN,URG 标识和端口号的数据包给服务器。如果目标端口是开放的,那么不会有任何来自服务器的回应。
如果服务器返回了一个带有 RST 标识的 TCP 数据包,那么说明端口处于关闭状态。
但如果服务器返回了一个 ICMP 数据包,其中包含 ICMP 目标不可达错误类型3以及 ICMP 状态码为1,2,3,9,10或13,则说明目标端口被过滤了无法确定是否处于开放状态。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
xmas_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="FPU"),timeout=10)
if (str(type(xmas_scan_resp))=="type 'NoneType'"):
print "Open|Filtered"
elif(xmas_scan_resp.haslayer(TCP)):
if(xmas_scan_resp.getlayer(TCP).flags == 0x14):
print "Closed"
elif(xmas_scan_resp.haslayer(ICMP)):
if(int(xmas_scan_resp.getlayer(ICMP).type)==3 and int(xmas_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print "Filtered"
TCP FIN扫描
FIN 扫描会向服务器发送带有 FIN 标识和端口号的 TCP 数据包。如果没有服务器端回应则说明端口开放。
如果服务器返回一个 RST 数据包,则说明目标端口是关闭的。
如果服务器返回了一个 ICMP 数据包,其中包含 ICMP 目标不可达错误类型3以及 ICMP 代码为1,2,3,9,10或13,则说明目标端口被过滤了无法确定端口状态。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
fin_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="F"),timeout=10)
if (str(type(fin_scan_resp))=="type 'NoneType'"):
print "Open|Filtered"
elif(fin_scan_resp.haslayer(TCP)):
if(fin_scan_resp.getlayer(TCP).flags == 0x14):
print "Closed"
elif(fin_scan_resp.haslayer(ICMP)):
if(int(fin_scan_resp.getlayer(ICMP).type)==3 and int(fin_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print "Filtered"
TCP 空扫描(Null)
在空扫描中,客户端发出的 TCP 数据包仅仅只会包含端口号而不会有其他任何的标识信息。如果目标端口是开放的则不会回复任何信息。
如果服务器返回了一个 RST 数据包,则说明目标端口是关闭的。
如果返回 ICMP 错误类型3且代码为1,2,3,9,10或13的数据包,则说明端口被服务器过滤了。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
null_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags=""),timeout=10)
if (str(type(null_scan_resp))=="type 'NoneType'"):
print "Open|Filtered"
elif(null_scan_resp.haslayer(TCP)):
if(null_scan_resp.getlayer(TCP).flags == 0x14):
print "Closed"
elif(null_scan_resp.haslayer(ICMP)):
if(int(null_scan_resp.getlayer(ICMP).type)==3 and int(null_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print "Filtered"
TCP ACK扫描
ACK 扫描不是用于发现端口开启或关闭状态的,而是用于发现服务器上是否存在有状态防火墙的。它的结果只能说明端口是否被过滤。再次强调,ACK 扫描不能发现端口是否处于开启或关闭状态。
客户端会发送一个带有 ACK 标识和端口号的数据包给服务器。如果服务器返回一个带有 RST 标识的 TCP 数据包,则说明端口没有被过滤,不存在状态防火墙。
如果目标服务器没有任何回应或者返回ICMP 错误类型3且代码为1,2,3,9,10或13的数据包,则说明端口被过滤且存在状态防火墙。
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
ack_flag_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="A"),timeout=10)
if (str(type(ack_flag_scan_resp))=="type 'NoneType'"):
print "Stateful firewall presentn(Filtered)"
elif(ack_flag_scan_resp.haslayer(TCP)):
if(ack_flag_scan_resp.getlayer(TCP).flags == 0x4):
print "No firewalln(Unfiltered)"
elif(ack_flag_scan_resp.haslayer(ICMP)):
if(int(ack_flag_scan_resp.getlayer(ICMP).type)==3 and int(ack_flag_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print "Stateful firewall presentn(Filtered)"
TCP窗口扫描
TCP 窗口扫描的流程同 ACK 扫描类似,同样是客户端向服务器发送一个带有 ACK 标识和端口号的 TCP 数据包,但是这种扫描能够用于发现目标服务器端口的状态。在 ACK 扫描中返回 RST 表明没有被过滤,但在窗口扫描中,当收到返回的 RST 数据包后,它会检查窗口大小的值。如果窗口大小的值是个非零值,则说明目标端口是开放的。
如果返回的 RST 数据包中的窗口大小为0,则说明目标端口是关闭的。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
window_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="A"),timeout=10)
if (str(type(window_scan_resp))=="type 'NoneType'"):
print "No response"
elif(window_scan_resp.haslayer(TCP)):
if(window_scan_resp.getlayer(TCP).window == 0):
print "Closed"
elif(window_scan_resp.getlayer(TCP).window 0):
print "Open"
UDP扫描
TCP 是面向连接的协议,而UDP则是无连接的协议。
面向连接的协议会先在客户端和服务器之间建立通信信道,然后才会开始传输数据。如果客户端和服务器之间没有建立通信信道,则不会有任何产生任何通信数据。
无连接的协议则不会事先建立客户端和服务器之间的通信信道,只要客户端到服务器存在可用信道,就会假设目标是可达的然后向对方发送数据。
客户端会向服务器发送一个带有端口号的 UDP 数据包。如果服务器回复了 UDP 数据包,则目标端口是开放的。
如果服务器返回了一个 ICMP 目标不可达的错误和代码3,则意味着目标端口处于关闭状态。
如果服务器返回一个 ICMP 错误类型3且代码为1,2,3,9,10或13的数据包,则说明目标端口被服务器过滤了。
但如果服务器没有任何相应客户端的 UDP 请求,则可以断定目标端口可能是开放或被过滤的,无法判断端口的最终状态。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=53
dst_timeout=10
def udp_scan(dst_ip,dst_port,dst_timeout):
udp_scan_resp = sr1(IP(dst=dst_ip)/UDP(dport=dst_port),timeout=dst_timeout)
if (str(type(udp_scan_resp))=="type 'NoneType'"):
retrans = []
for count in range(0,3):
retrans.append(sr1(IP(dst=dst_ip)/UDP(dport=dst_port),timeout=dst_timeout))
for item in retrans:
if (str(type(item))!="type 'NoneType'"):
udp_scan(dst_ip,dst_port,dst_timeout)
return "Open|Filtered"
elif (udp_scan_resp.haslayer(UDP)):
return "Open"
elif(udp_scan_resp.haslayer(ICMP)):
if(int(udp_scan_resp.getlayer(ICMP).type)==3 and int(udp_scan_resp.getlayer(ICMP).code)==3):
return "Closed"
elif(int(udp_scan_resp.getlayer(ICMP).type)==3 and int(udp_scan_resp.getlayer(ICMP).code) in [1,2,9,10,13]):
return "Filtered"
print udp_scan(dst_ip,dst_port,dst_timeout)
下面解释下上述代码中的一些函数和变量:
RandShort():产生随机数
type():获取数据类型
sport:源端口号
dport:目标端口号
timeout:等待相应的时间
haslayer():查找指定层:TCP或UDP或ICMP
getlayer():获取指定层:TCP或UDP或ICMP
以上扫描的概念可以被用于“多端口扫描”,源码可以参考这里:
Scapy 是一个非常好用的工具,使用它可以非常简单的构建自己的数据包,还可以很轻易的处理数据包的发送和相应。
(译者注:上述所有代码均在Kali 2.0下测试通过,建议读者在Linux环境下测试代码,如想在Windows上测试,请参见 Scapy官方文档 配置好scapy环境)
*** 攻击的种类分析及防范策略总结怎么写
用特征进行检测。攻击工具有三个特点:反侦破,攻击者采用隐蔽攻击工具特性的技术,这使安全专家分析新攻击工具和了解新攻击行为所耗费的时间增多;动态行为,早期的攻击工具是以但已确定的顺序执行攻击步骤,今天的自动攻击工具可以根据随机选择、预先定义的决策路径或通过入侵者直接管理,来变化它们的模式和行为;攻击工具的成熟性,与早期的攻击工具不同,目前攻击工具可以通过升级或更换工具的一部分迅速变化,发动迅速变化的功绩,且在每一次攻击中会出现多种不同形态的攻击工具。
1.1发现安全漏洞越来越快
新发现的安全漏洞每年都要增加一倍,管理人员不断用最新的补丁修复这些漏洞,而且每年都会发现安全漏洞的新类型。入侵者经常能够在厂商修补这些漏洞前发现攻击目标。
1.2越来越高的防火墙渗透率
防火墙使人们牙防反入侵者的主要保护措施。但是越来越多的攻击技术可以绕过防火墙。例如,(IPP Internet打印协议)和WebDAV(基于Web的分布式创作与翻译)都可以被攻击者利用来绕过防火墙。
1.3 越来越不对称的威胁
Internet上的安全是相互依赖的。每个Internet系统遭受攻击的可能性取决于连接到全球Internet上其他系统的阿安全状态。由于攻击技术的进步,一个攻击者可以比较容易地利用分布式系统,对一个受害者发动破坏性的攻击。随着部署自动化程度和攻击工具管理技术的提高,威胁的不对称性将继续增加。
1.4 对基础设施将形成越来越大的威胁
基础设施攻击是大面积影响Internet关键组成部分的攻击。由于用户越来越多地依赖Internet完成日常业务,基础设施攻击引起人们越来越大的担心。基础设施面临分布式拒绝服务攻击、蠕虫病毒、对Internet域名系统DNS的攻击和对路由器攻击或利用路由器的攻击。
个人用户防护策略
针对一些常用的攻击 *** 、手段,个人用户有必要采取一些安全的防范措施,下面介绍一些可行的防范实例。
经常检查系统信息
上网过程中,如果感觉计算机有异常状态,如运行速度变慢,某些软件运行出错,不受控制等情况,应停下来检查一下系统运行状况。一是观看系统资源的使用状态,二是按“Ctrl+Alt+Del”复合键来查看系统正在运行的程序,看是否有其他程序在运行。如有自己部熟悉或自己并没有运行的程序在列表里面,应立即终止其运行,以防后患。
检测并清除木马程序
如果你的电脑一旦被人为诸如木马程序,就会被人操纵,以致出现死机,数据文件被删除等现象。这时候可以通过查看注册表,看注册表中\HKEY LOCAL MACHINE\HKEY.LOCAL_MACHINE\Softwere\Microsoft\Windows\CurrenVersion\kun下面类似Netspy.exe或空格.exe或其他可疑的文件名,如果有,则尽快闪出相应的键值,在查找到住在机内的相应的程序,并把它删除。
保护入网账号和口令
在Windows目录下经常有一些以“.pwl”为后追名的文件,这些文件作为密码保存之用,如开启Exchange电子信箱的密码、开机口令等信息就保存在以“.pwl”为后缀名的文件中。有些黑客可以运用一些专用软件来破解Windows95/98种的pwl文件,以很快的速度便可以直接读出pwl中的开机口令、用户名等加密数据信息。对于这种情况,最安全的 *** 是不用Windows95/98自动即以密码功能这一项,这样pwl文件中就没有任何加密信息流下,破解软件也无从下手。另外,对付这种情况也有较为直接的 *** ,就是经常删除这些以”.pwl”为后缀名的文件,以免将密码留在硬盘上。
保护好自己的IP地址
国内用户很多是通过163 *** 拨号的方式上网的,某些恶意破坏者往往通过跟踪上网账号并从用户信息中找IP,或者等待BBS、聊天室纪录的IP或者通过ICQ获取IP。为防止用户非法获取个人用户的IP地址信息,更好采用如下两种安全措施:一是使用 *** 服务器进行中转,这样用户上网是不需要真实的IP地址,别人也就无法获取自己的IP地址信息。二是注意避免在某些会显示IP的BBS和聊天室上暴露自己的IP地址。
屏蔽ActiveX控件
由于ActiveX控件可以被嵌入到HTML页面中,并下再到浏览器端加以执行,因此会给浏览器造成一定程度上的安全威胁。所以,用户如果要保证自己在因特网上的信息绝对安全,可以屏蔽掉这些可能对计算机安全构成威胁的ActiveX控件,具体操作步骤为:首先用鼠标单击菜单栏中的“工具”菜单项,并从下拉菜单中选择“Internet选项”:接着在选项设置框中选中“安全”标签,并单击标签中的“自定义级别”按钮:同时在打开的“安全设置”对话框中找到关于ActiveX控件的设置,然后选择“禁用”或“提示”。
使用“拨号后出现终端窗口”要小心
选中某一连接,单击鼠标右键,选“属性-常规-配置-选项-拨号后出现终端窗口”,然后拨号时,在拨号界面上不要填入用户名和密码(更不能选中“保存密码”项),在出现拨号终端口后再进行相应的输入,这可以避免用户名和密码被记录到硬盘上的密码文件中,同时,也可以避免某些黑客程序捕获用户名和密码。
拒绝“饼干”信息
许多网站会用不易觉察的技术,暗中搜集你填写的表格中的电子邮件地址信息,最常见的就是利用饼干程序(cookie)记录访客上网的浏览行为和习惯。如果你不想随便让饼干程序(cookie)来记录你个人的隐私信息,可以在浏览器中作一些必要的设置,要求浏览器在接受cookie之前提醒你,或者干脆拒绝它们。屏蔽cookie的操作步骤为:首先用鼠标单击菜单栏中的“工具”菜单项,并从下拉菜单中选择“Internet选项”:接着在选项设置框中选中“安全”标签,并单击标签中的“自定义级别”按钮:同时在打开的“安全设置”对话框中找到关于cookie的设置,然后选择“禁用:或“提示”即可。
不使用“MYDocuments”文件夹存放Word、Excel文件
Word、Excel默认的文件存放路径是根目录下的“MYDocuments”文件夹,在特洛伊木马把用户硬盘变成共享硬盘后,入侵者从这个目录中的文件名一眼就能看出这个用户是干什么的,这个目录几乎就是用户的特征标示,所以为安全起见应把工作路径改成别的目录,并且参差越深越好。
加密保护电子邮件
由于越来越多的人通过电子邮件进行重要的商务活动和发送机密信息,而且随着互联网的发展,这类应用会更加频繁。因此保证邮件的真实性和不被其他人截取和偷阅也变得越来越重要。所以,对于包含敏感信息的邮件,更好利用数字标示对你原写的邮件进行数字签名后再发送。所谓数字标示是指由独立的授权机构发放的证明你在Internet上的身份的证件,是你在因特网上的身份证。这些发证的商业机构将发放给你这个身份证并不断地效验其有效性。你首先向这些公司申请标示,然后就可以利用这个数字标示对自己的邮件进行数字签名,如果你获得了别人的数字标示,那么,你还可以跟他发送加密邮件。你通过对发送的邮件进行数字签名可以把你的数字标示发送给他人,这是他们收到的实际上是公用密钥,以后他们就可以通过这个公用密钥对发给你的邮件进行加密,你在使用私人密钥对加密邮件进行解密和阅读。在Outlook Eepress中可以通过数字签名来证明你的邮件身份,即让对方确信该有见是由你的机器发送的,它同时提供邮件加密功能使得你的邮件只有预定的接收者才能接收并阅读。但前提是你必须先获得对方的数字标示。数字标示的数字签名部分是你原电子身份卡,数字签名可使收件人确信又见是你发的,并且未被伪造或篡改过。从这些着手来写 就差不多了
Kali Linux *** 扫描秘籍 第三章 端口扫描(二)
执行 TCP 端口扫描的一种方式就是执行一部分。目标端口上的 TCP 三次握手用于识别端口是否接受连接。这一类型的扫描指代隐秘扫描, SYN 扫描,或者半开放扫描。这个秘籍演示了如何使用 Scapy 执行 TCP 隐秘扫描。
为了使用 Scapy 执行 TCP 隐秘 扫描,你需要一个运行 TCP *** 服务的远程服务器。这个例子中我们使用 Metasploitable2 实例来执行任务。配置 Metasploitable2 的更多信息请参考之一章中的“安装 Metasploitable2”秘籍。
此外,这一节也需要编写脚本的更多信息,请参考之一章中的“使用文本编辑器*VIM 和 Nano)。
为了展示如何执行 SYN 扫描,我们需要使用 Scapy 构造 TCP SYN 请求,并识别和开放端口、关闭端口以及无响应系统有关的响应。为了向给定端口发送 TCP SYN 请求,我们首先需要构建请求的各个层面。我们需要构建的之一层就是 IP 层:
为了构建请求的 IP 层,我们需要将 IP 对象赋给变量 i 。通过调用 display 函数,我们可以确定对象的属性配置。通常,发送和接受地址都设为回送地址, 127.0.0.1 。这些值可以通过修改目标地址来修改,也就是设置 i.dst 为想要扫描的地址的字符串值。通过再次调用 dislay 函数,我们看到不仅仅更新的目标地址,也自动更新了和默认接口相关的源 IP 地址。现在我们构建了请求的 IP 层,我们可以构建 TCP 层了。
为了构建请求的 TCP 层,我们使用和 IP 层相同的技巧。在这个立即中, TCP 对象赋给了 t 变量。像之前提到的那样,默认的配置可以通过调用 display 函数来确定。这里我们可以看到目标端口的默认值为 HTTP 端口 80。对于我们的首次扫描,我们将 TCP 设置保留默认。现在我们创建了 TCP 和 IP 层,我们需要将它们叠放来构造请求。
我们可以通过以斜杠分离变量来叠放 IP 和 TCP 层。这些层面之后赋给了新的变量,它代表整个请求。我们之后可以调用 dispaly 函数来查看请求的配置。一旦构建了请求,可以将其传递给 sr1 函数来分析响应:
相同的请求可以不通过构建和堆叠每一层来执行。反之,我们使用单独的一条命令,通过直接调用函数并传递合适的参数:
要注意当 SYN 封包发往目标 Web 服务器的 TCP 端口 80,并且该端口上运行了 HTTP 服务时,响应中会带有 TCP 标识 SA 的值,这表明 SYN 和 ACK 标识都被激活。这个响应表明特定的目标端口是开放的,并接受连接。如果相同类型的封包发往不接受连接的端口,会收到不同的请求。
当 SYN 请求发送给关闭的端口时,返回的响应中带有 TCP 标识 RA,这表明 RST 和 ACK 标识为都被激活。ACK 为仅仅用于承认请求被接受,RST 为用于断开连接,因为端口不接受连接。作为替代,如果 SYN 封包发往崩溃的系统,或者防火墙过滤了这个请求,就可能接受不到任何信息。由于这个原因,在 sr1 函数在脚本中使用时,应该始终使用 timeout 选项,来确保脚本不会在无响应的主机上挂起。
如果函数对无响应的主机使用时, timeout 值没有指定,函数会无限继续下去。这个演示中, timout 值为 1秒,用于使这个函数更加完备,响应的值可以用于判断是否收到了响应:
Python 的使用使其更易于测试变量来识别 sr1 函数是否对其复制。这可以用作初步检验,来判断是否接收到了任何响应。对于接收到的响应,可以执行一系列后续检查来判断响应表明端口开放还是关闭。这些东西可以轻易使用 Python 脚本来完成,像这样:
在这个 Python 脚本中,用于被提示来输入 IP 地址,脚本之后会对定义好的端口序列执行 SYN 扫描。脚本之后会得到每个连接的响应,并尝试判断响应的 SYN 和 ACK 标识是否激活。如果响应中出现并仅仅出现了这些标识,那么会输出相应的端口号码。
运行这个脚本之后,输出会显示所提供的 IP 地址的系统上,前 100 个端口中的开放端口。
这一类型的扫描由发送初始 SYN 封包给远程系统的目标 TCP 端口,并且通过返回的响应类型来判断端口状态来完成。如果远程系统返回了 SYN+ACK 响应,那么它正在准备建立连接,我们可以假设这个端口开放。如果服务返回了 RST 封包,这就表明端口关闭并且不接收连接。此外,如果没有返回响应,扫描系统和远程系统之间可能存在防火墙,它丢弃了请求。这也可能表明主机崩溃或者目标 IP 上没有关联任何系统。
Nmap 拥有可以执行远程系统 SYN 扫描的扫描模式。这个秘籍展示了如何使用 Namp 执行 TCP 隐秘扫描。
为了使用 Nmap 执行 TCP 隐秘扫描,你需要一个运行 TCP *** 服务的远程服务器。这个例子中我们使用 Metasploitable2 实例来执行任务。配置 Metasploitable2 的更多信息请参考之一章中的“安装 Metasploitable2”秘籍。
就像多数扫描需求那样,Nmap 拥有简化 TCP 隐秘扫描执行过程的选项。为了使用 Nmap 执行 TCP 隐秘扫描,应使用 -sS 选项,并附带被扫描主机的 IP 地址。
在提供的例子中,特定的 IP 地址的 TCP 80 端口上执行了 TCP 隐秘扫描。和 Scapy 中的技巧相似,Nmap 监听响应并通过分析响应中所激活的 TCP 标识来识别开放端口。我们也可以使用 Namp 执行多个特定端口的扫描,通过传递逗号分隔的端口号列表。
在这个例子中,目标 IP 地址的端口 21、80 和 443 上执行了 SYN 扫描。我们也可以使用 Namp 来扫描主机序列,通过标明要扫描的之一个和最后一个端口号,以破折号分隔:
在所提供的例子中,SYN 扫描在 TCP 20 到 25 端口上执行。除了拥有指定被扫描端口的能力之外。Nmap 同时拥有配置好的 1000 和常用端口的列表。我们可以执行这些端口上的扫描,通过不带任何端口指定信息来运行 Nmap:
在上面的例子中,扫描了 Nmap 定义的 1000 个常用端口,用于识别 Metasploitable2 系统上的大量开放端口。虽然这个技巧在是被多数设备上很高效,但是也可能无法识别模糊的服务或者不常见的端口组合。如果扫描在所有可能的 TCP 端口上执行,所有可能的端口地址值都需要被扫描。定义了源端口和目标端口地址的 TCP 头部部分是 16 位长。并且,每一位可以为 1 或者 0。因此,共有 2 ** 16 或者 65536 个可能的 TCP 端口地址。对于要扫描的全部可能的地址空间,需要提供 0 到 65535 的端口范围,像这样:
这个例子中,Metasploitable2 系统上所有可能的 65536 和 TCP 地址都扫描了一遍。要注意该扫描中识别的多数服务都在标准的 Nmap 1000 扫描中识别过了。这就表明在尝试识别目标的所有可能的攻击面的时候,完整扫描是个更佳实践。Nmap 可以使用破折号记法,扫描主机列表上的 TCP 端口:
这个例子中,TCP 80 端口的 SYN 扫描在指定地址范围内的所有主机上执行。虽然这个特定的扫描仅仅执行在单个端口上,Nmap 也能够同时扫描多个系统上的多个端口和端口范围。此外,Nmap 也能够进行配置,基于 IP 地址的输入列表来扫描主机。这可以通过 -iL 选项并指定文件名,如果文件存放于执行目录中,或者文件路径来完成。Nmap 之后会遍历输入列表中的每个地址,并对地址执行特定的扫描。
Nmap SYN 扫描背后的底层机制已经讨论过了。但是,Nmap 拥有多线程功能,是用于执行这类扫描的快速高效的方式。
除了其它已经讨论过的工具之外,Metasploit 拥有用于 SYN 扫描的辅助模块。这个秘籍展示了如何使用 Metasploit 来执行 TCP 隐秘扫描。
为了使用 Metasploit 执行 TCP 隐秘扫描,你需要一个运行 TCP *** 服务的远程服务器。这个例子中我们使用 Metasploitable2 实例来执行任务。配置 Metasploitable2 的更多信息请参考之一章中的“安装 Metasploitable2”秘籍。
Metasploit 拥有可以对特定 TCP 端口执行 SYN 扫描的辅助模块。为了在 Kali 中启动 Metasploit,我们在终端中执行 msfconsole 命令。
为了在 Metasploit 中执行 SYN 扫描,以辅助模块的相对路径调用 use 命令。一旦模块被选中,可以执行 show options 命令来确认或修改扫描配置。这个命令会展示四列的表格,包括 name 、 current settings 、 required 和 description 。 name 列标出了每个可配置变量的名称。 current settings 列列出了任何给定变量的现有配置。 required 列标出对于任何给定变量,值是否是必须的。 description 列描述了每个变量的功能。任何给定变量的值可以使用 set 命令,并且将新的值作为参数来修改。
在上面的例子中, RHOSTS 值修改为我们打算扫描的远程系统的 IP 地址。地外,线程数量修改为 20。 THREADS 的值定义了在后台执行的当前任务数量。确定线程数量涉及到寻找一个平衡,既能提升任务速度,又不会过度消耗系统资源。对于多数系统,20 个线程可以足够快,并且相当合理。 PORTS 值设为 TCP 端口 80(HTTP)。修改了必要的变量之后,可以再次使用 show options 命令来验证。一旦所需配置验证完毕,就可以执行扫描了。
上面的例子中,所指定的远程主机的钱 100 个 TCP 端口上执行了 TCP SYN 扫描。虽然这个扫描识别了目标系统的多个设备,我们不能确认所有设备都识别出来,除非所有可能的端口地址都扫描到。定义来源和目标端口地址的TCP 头部部分是 16 位长。并且,每一位可以为 1 或者 0。因此,共有 2 ** 16 或 65536 个可能的 TCP 端口地址。对于要扫描的整个地址空间,需要提供 0 到 65535 的 端口范围,像这样:
在这个李忠,远程系统的所有开放端口都由扫描所有可能的 TCP 端口地址来识别。我们也可以修改扫描配置使用破折号记法来扫描地址序列。
这个例子中,TCP SYN 扫描执行在由 RHOST 变量指定的所有主机地址的 80 端口上。与之相似, RHOSTS 可以使用 CIDR 记法定义 *** 范围。
Metasploit SYN 扫描辅助模块背后的底层原理和任何其它 SYN 扫描工具一样。对于每个被扫描的端口,会发送 SYN 封包。SYN+ACK 封包会用于识别活动服务。使用 MEtasploit 可能更加有吸引力,因为它拥有交互控制台,也因为它是个已经被多数渗透测试者熟知的工具。
除了我们之前学到了探索技巧,hping3 也可以用于执行端口扫描。这个秘籍展示了如何使用 hping3 来执行 TCP 隐秘扫描。
为了使用 hping3 执行 TCP 隐秘扫描,你需要一个运行 TCP *** 服务的远程服务器。这个例子中我们使用 Metasploitable2 实例来执行任务。配置 Metasploitable2 的更多信息请参考之一章中的“安装 Metasploitable2”秘籍。
除了我们之前学到了探索技巧,hping3 也可以用于执行端口扫描。为了使用 hping3 执行端口扫描,我们需要以一个整数值使用 --scan 模式来指定要扫描的端口号。
上面的例子中,SYN 扫描执行在指定 IP 地址的 TCP 端口 80 上。 -S 选项指明了发给远程系统的封包中激活的 TCP 标识。表格展示了接收到的响应封包中的属性。我们可以从输出中看到,接收到了SYN+ACK 响应,所以这表示目标主机端口 80 是开放的。此外,我们可以通过输入够好分隔的端口号列表来扫描多个端口,像这样:
在上面的扫描输出中,你可以看到,仅仅展示了接受到 SYN+ACK 标识的结果。要注意和发送到 443 端口的 SYN 请求相关的响应并没有展示。从输出中可以看出,我们可以通过使用 -v 选项增加详细读来查看所有响应。此外,可以通过传递之一个和最后一个端口地址值,来扫描端口范围,像这样:
这个例子中,100 个端口的扫描足以识别 Metasploitable2 系统上的服务。但是,为了执行 所有 TCP 端口的扫描,需要扫描所有可能的端口地址值。定义了源端口和目标端口地址的 TCP 头部部分是 16 位长。并且,每一位可以为 1 或者 0。因此,共有 2 ** 16 或者 65536 个可能的 TCP 端口地址。对于要扫描的全部可能的地址空间,需要提供 0 到 65535 的端口范围,像这样:
hping3 不用于一些已经提到的其它工具,因为它并没有 SYN 扫描模式。但是反之,它允许你指定 TCP 封包发送时的激活的 TCP 标识。在秘籍中的例子中, -S 选项让 hping3 使用 TCP 封包的 SYN 标识。
在多数扫描工具当中,TCP 连接扫描比 SYN 扫描更加容易。这是因为 TCP 连接扫描并不需要为了生成和注入 SYN 扫描中使用的原始封包而提升权限。Scapy 是它的一大例外。Scapy 实际上非常难以执行完全的 TCP 三次握手,也不实用。但是,出于更好理解这个过程的目的,我们来看看如何使用 Scapy 执行连接扫描。
为了使用 Scapy 执行全连接扫描,你需要一个运行 UDP *** 服务的远程服务器。这个例子中我们使用 Metasploitable2 实例来执行任务。配置 Metasploitable2 的更多信息请参考之一章中的“安装 Metasploitable2”秘籍。
此外,这一节也需要编写脚本的更多信息,请参考之一章中的“使用文本编辑器*VIM 和 Nano)。
Scapy 中很难执行全连接扫描,因为系统内核不知道你在 Scapy 中发送的请求,并且尝试阻止你和远程系统建立完整的三次握手。你可以在 Wireshark 或 tcpdump 中,通过发送 SYN 请求并嗅探相关流量来看到这个过程。当你接收到来自远程系统的 SYN+ACK 响应时,Linux 内核会拦截它,并将其看做来源不明的响应,因为它不知道你在 Scapy 中 发送的请求。并且系统会自动使用 TCP RST 封包来回复,因此会断开握手过程。考虑下面的例子:
这个 Python 脚本的例子可以用做 POC 来演系统破坏三次握手的问题。这个脚本假设你将带有开放端 *** 动系统作为目标。因此,假设 SYN+ACK 回复会作为初始 SYN 请求的响应而返回。即使发送了最后的 ACK 回复,完成了握手,RST 封包也会阻止连接建立。我们可以通过观察封包发送和接受来进一步演示。
在这个 Python 脚本中,每个发送的封包都在传输之前展示,并且每个收到的封包都在到达之后展示。在检验每个封包所激活的 TCP 标识的过程中,我们可以看到,三次握手失败了。考虑由脚本生成的下列输出:
在脚本的输出中,我们看到了四个封包。之一个封包是发送的 SYN 请求,第二个封包时接收到的 SYN+ACK 回复,第三个封包时发送的 ACK 回复,之后接收到了 RST 封包,它是最后的 ACK 回复的响应。最后一个封包表明,在建立连接时出现了问题。Scapy 中可能能够建立完成的三次握手,但是它需要对本地 IP 表做一些调整。尤其是,如果你去掉发往远程系统的 TSR 封包,你就可以完成握手。通过使用 IP 表建立过滤机制,我们可以去掉 RST 封包来完成三次握手,而不会干扰到整个系统(这个配置出于功能上的原理并不推荐)。为了展示完整三次握手的成功建立,我们使用 Netcat 建立 TCP 监听服务。之后尝试使用 Scapy 连接开放的端口。
这个例子中,我们在 TCP 端口 4444 开启了监听服务。我们之后可以修改之前的脚本来尝试连接 端口 4444 上的 Netcat 监听服务。
这个脚本中,SYN 请求发送给了监听端口。收到 SYN+ACK 回复之后,会发送 ACK回复。为了验证连接尝试被系统生成的 RST 封包打断,这个脚本应该在 Wireshark 启动之后执行,来捕获请求蓄力。我们使用 Wireshark 的过滤器来隔离连接尝试序列。所使用的过滤器是 tcp (ip.src == 172.16.36.135 || ip.dst == 172.16.36.135) 。过滤器仅仅用于展示来自或发往被扫描系统的 TCP 流量。像这样:
既然我们已经精确定位了问题。我们可以建立过滤器,让我们能够去除系统生成的 RST 封包。这个过滤器可以通过修改本地 IP 表来建立:
在这个例子中,本地 IP 表的修改去除了所有发往被扫描主机的目标地址的 TCP RST 封包。 list 选项随后可以用于查看 IP 表的条目,以及验证配置已经做了修改。为了执行另一次连接尝试,我们需要确保 Natcat 仍旧监听目标的 4444 端口,像这样:
和之前相同的 Python 脚本可以再次使用,同时 WIreshark 会捕获后台的流量。使用之前讨论的显示过滤器,我们可以轻易专注于所需的流量。要注意三次握手的所有步骤现在都可以完成,而不会收到系统生成的 RST 封包的打断,像这样:
此外,如果我们看一看运行在目标系统的 Netcat 服务,我们可以注意到,已经建立了连接。这是用于确认成功建立连接的进一步的证据。这可以在下面的输出中看到:
虽然这个练习对理解和解决 TCP 连接的问题十分有帮助,恢复 IP 表的条目也十分重要。RST 封包 是 TCP 通信的重要组成部分,去除这些响应会影响正常的通信功能。洗唛按的命令可以用于刷新我们的 iptable 规则,并验证刷新成功:
就像例子中展示的那样, flush 选项应该用于清楚 IP 表的条目。我们可以多次使用 list 选项来验证 IP 表的条目已经移除了。
执行 TCP 连接扫描的同居通过执行完整的三次握手,和远程系统的所有被扫描端口建立连接。端口的状态取决于连接是否成功建立。如果连接建立,端口被认为是开放的,如果连接不能成功建立,端口被认为是关闭的。
0条大神的评论