◆孟彬 智云垒 钟翡
基于Python的端口扫描技术研究
◆孟彬 智云垒 钟翡
(96822部队 云南 650000)
本文研究了计算机端口扫描技术,介绍了常用端口扫描技术的原理,并利用Python的socket模块实现远程计算机TCP端口的全连接扫描,通过扫描发现处于开放状态的高危端口,提醒网络运维人员合理的关闭高危端口可提高计算机的安全性。
全连接扫描;Python;socket
端口在计算机中有非常重要的意义,端口是计算机与外界交互信息的通道。可以这样理解,计算机端口在传输层上用来标识同一台计算机的不同进程。客户端通常对它使用的端口号不关心,只需要保障该端口在本机上是唯一的即可,客户端与服务端通信时常用动态端口,服务端使用固定的知名端口,客户端的端口号与服务端的端口号不需要一一对应。IP地址和端口号的组合成为套接字Socket,在一个主机上是唯一的,一条连接由客户端和服务器的套接字组成[1]。
计算机端口在网络安全方面有极重要的意义,黑客和一些木马程序会利用端口漏洞实施入侵活动。对目标主机进行扫描可以得到其端口的开放情况,根据主机运行的业务,合理的关闭不需要的高危端口,就可以防止木马与黑客利用这些端口开展攻击的活动,从而提高计算机的安全性。常见的高危端口有135、137、138、139、445等端口,135端口用于RPC(远程过程调用)服务、137端口用于NetBIOS名称服务,138和139端口用于局域网中的共享服务,445用于文件夹和打印机共享服务[2]。
常见端口扫描技术有全连接扫描、半连接扫描、FIN扫描、ACK扫描和NULL扫描等。
TCP Connect扫描又称全连接扫描,TCP connect()函数会调用系统提供的传输层接口API,尝试通过三次握手与目标的指定端口建立TCP连接,根据连接的建立情况判断目标端口是否开放。优点是易于实现,扫描速度快,可同时扫描多个用户,无须管理员权限。缺点是会在目标主机的日志中记录大量的连接建立与关闭信息。
TCP SYN扫描又称半连接扫描,扫描时与目标机指定端口建立TCP连接时仅完成前两次握手,在第三次握手时不发送确认报文,使TCP连接无法确认。优点是目标主机日志中记录的连接信息较少,缺点是实现较为复杂且需要较高的权限。
FIN扫描,不依赖TCP的三次握手,向目标端口发送一个设置了FIN标记的报文,根据系统返回或不返回报文判断端口的开放情况。缺点是扫描结果不准确,容易得到错误结论。
ACK扫描,发送的报文只设置ACK标志位,若收到目标主机返回的RST标记的报文,只能判断目标主机未被防火墙保护不能判断端口是否开放。若未收到任何报文或收到ICMP不可达报文,说明端口受到防火墙保护。ACK扫描判断端口是否开放容易出错,更适合确定目标是否在线。
NULL扫描又称空扫描,将发送的报文中所有标记都置为0,若目标返回RST报文表示端口关闭,若目标没返回报文,表示端口开放或被防火墙保护[3]。缺点是扫描结果不准确。
综上所述,TCP Connect扫描因具有扫描速度快、扫描结果准确、权限要求低等优点,得到了较广泛的应用。
计算机间通过IP地址与端口号进行通信的方式称为socket通信,HTTP、FTP、DNS等应用都是通过socket通信实现的,socket通信中提供服务的一方称为socket服务端,调用socket服务的一方称为socket客户端。Socket服务端用自己的IP地址、指定端口号和连接方式创建服务并启动服务并等待客户端的连接请求,socket客户端向服务端发起连接请求,连接请求被服务端接受后,客户端和服务端就可以进行通信了。
Python可直接调用socket对象,通过socket套接字向目标主机的端口发送TCP connect()请求,若目标主机上的指定端口处于侦听状态,就可以建立连接[4]。若目标主机未开放该端口,则connect()操作失败,产生异常。
在扫描前要先建立TCP连接,关键代码如下:
import socket #导入socket模块
tcps=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #建立TCP套接字
tcps.connect((ip,port))#连接指定主机的目标端口
tcps.shutdown(2)
tcps就是建立的socket对象,利用socket对象tcps对目标主机进行connect连接,connect()函数只能接受一个参数,ip地址与端口号要用元组表示,ip与端口号在函数调用时传入。tcps.shutdown(2)表示tcps套接字不允许传输数据,只能用于扫描端口。
若目标主机指定端口未开启,则返回connect refuse结果,会产生connect操作失败异常,可以用try except捕捉connect异常,通过对连接异常的捕捉可判断目标主机端口的开启情况。
定义连接判断函数:
def TcpOpen(ip,port):
tcps=socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
try:
tcps.connect((ip,int(port)))
tcps.shutdown(2)
result.insert('insert','TCP端口{}isopen!!! '.format(port))
tcps.close()
except Exception as e:
return None
连接判断函数的主要功能是:根据ip和port参数指定的IP地址和端口号,去连接目标主机的相应端口,若连接成功在Text窗体result上显示端口开放信息,表示端口是开放的,连接失败的端口不显示,表示端口未开放。
定义扫描函数:
def scanport():
begin = input1.get() #变量begin表示起始扫描端口
end=input2.get() #变量end表示终止扫描端口
ip =show_ip.get() #变量ip是要扫描的目标主机IP
for i in range(eval(begin), eval(end)):
TcpOpen(ip,i)
扫描主机的ip地址由用户填写,ip地址默认为”127.0.0.1”,,既可以扫描远程计算机也可以扫描本地计算机。用户可任意指定开始端口号和终止端口号,知名端口、注册端口和动态端口号均可,但要注意的是端口范围越大扫描的时间就越长。
界面设计采用Python自带的Tkinter模块,运行的界面如下:
图1 端口扫描器的界面
指定扫描端口范围是0-1024,指定目标主机的ip是28.90.31.182,程序执行完毕后就会输出在1-1024范围里的所有的开放的端口,如下图2所示。
图2 目标主机的端口扫描结果
通过端口扫描可看到110、135、139、443、902、912等知名端口是处于开放状态的,网络运维人员可以根据主机的实际运行情况关闭部分开放的端口,可提高计算机的安全性。这里以扫描TCP知名端口为例,对于动态端口和注册端口也同样适用。
端口扫描技术对于计算机安全有重要的意义,随着计算机网络的发展,计算机面临的网络攻击与日俱增,端口扫描是网络防御的重要环节。本文介绍了5种常用的端口扫描技术,并编写了端口扫描工具,实现了对目标主机TCP端口的扫描功能,得到了开放的TCP端口列表,及时关闭不使用的高危端口可提高计算机的安全性。下一步,将重点研究如何快捷高效的扫描UDP端口,同时端口扫描工具有较强的可扩展性,还需进一步丰富扫描工具的功能、提高可用性。
[1]Brandon Rhodes John Goerzen. Python网络编程[M].北京:人民邮电出版社,2016:18-19.
[2]裴志斌,李斌勇,王星程.IP及端口扫描体系的逻辑处理设计[J]. 网络安全技术与应用,2017(10):26-27.
[3]梁剑非.多线程端口扫描软件设计与实现[D].成都:电子科技大学,2011
[4]赵宏,包广斌,马栋林.Python网络编程(Linux)[M].北京:清华大学出版社,2018:108-111.