实训项目制作的端口扫描脚本
附有详细的使用命令解释
可以实现单个端口进行扫描和端进行扫描
eg:1-65535
import optparse # 导入用于解析命令行参数的模块
import socket # 导入用于网络通信的模块# 定义函数:扫描指定主机的指定端口
def PortScan(targetHost, targetPort):
try:
connSkt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建套接字对象, # socket.AF_INET 表示地址族(Address Family),用于指定套接字使用的地址类型,这里是 IPv4 地址族。
# socket.SOCK_STREAM 表示套接字类型(Socket Type),用于指定套接字的传输类型,这里是 TCP。
connSkt.settimeout(1) # 设置连接超时时间为 1 秒
connSkt.connect((targetHost, targetPort)) # 尝试连接指定的主机和端口
connSkt.send(b'PortScan
') # 发送字节数据到连接的套接字
results = connSkt.recv(1000) # 接收数据并存储结果
print('[+] %d/tcp open' % targetPort) # 输出端口开放信息
print('[+] ' + str(results)) # 输出收到的数据
except socket.error:
print('[-] %d/tcp closed' % targetPort) # 端口关闭或发生错误时输出信息
finally:
connSkt.close() # 关闭套接字连接# 定义函数:执行端口扫描
def Scan(targetHost, targetPorts):
try:
tgtIP = socket.getaddrinfo(targetHost, 0)[0][4][0] # 获取目标主机的 IP 地址,socket.getaddrinfo(targetHost, 0) 返回一个包含解析信息的列表。
except socket.gaierror:
print('[-] Cannot resolve %s: Unknown host' % targetHost) # 若无法解析主机名则输出错误信息并返回
return
try:
tgtName = socket.gethostbyaddr(tgtIP)[0] # 获取 IP 地址对应的主机名
# socket.gethostbyaddr() 函数用于执行 IP 地址到主机名的反向 DNS 解析。它接受一个 IP 地址作为参数,并返回与该地址关联的主机名。
print("
[+] Scan results for: " + tgtName) # 输出扫描结果的主机名
except socket.herror: # 表示与主机和网络相关的错误。
print("Scan Results for: " + tgtIP) # 若无法获取主机名则输出 IP 地址
for targetPort in targetPorts: # 遍历指定的端口列表
print("Scanning port: " + str(targetPort)) # 输出当前正在扫描的端口
PortScan(targetHost, int(targetPort)) # 调用 PortScan 函数扫描各个端口# 解析端口范围参数
def parse_port_range(port_range):
ports = []
try:
if "-" in port_range:
start, end = port_range.split("-") #split("-") 方法通过分隔符 "-" 将字符串 port_range 拆分成两部分,左侧部分是起始端口,右侧部分是结束端口。这两部分被赋值给 start 和 end 变量。
for port in range(int(start), int(end) + 1):
ports.append(port)
else:
ports.append(int(port_range))
except ValueError:
print("Invalid port range specified. Please use format 'start-end' or 'port'.")
exit(0)
return ports# 主函数
def main():
parser = optparse.OptionParser("Usage prog -H <target host> -p <target ports>") # 是 Python 中用于解析命令行参数的模块。它允许您编写带有选项和参数的命令行接口,并解析用户提供的输入
parser.add_option('-H', dest='targetHost', type='string', help='specify target host') # add_option() 方法用于添加选项,
# dest 参数用于指定选项被解析后存储的目标属性名称。当用户在命令行中使用选项时,解析器会将解析后的值存储到指定的目标属性中。
# type 参数用于指定在解析命令行参数时所期望的数据类型。这个参数允许您告诉解析器应该将参数解析为何种数据类型。
# string 是一个数据类型或一个表示字符类型的字符串
parser.add_option('-p', dest='targetPort', type='string', help='specify target port▼显示 inside "" separated by commas(1-65535)')
(options, args) = parser.parse_args() #parse_args() 方法用于解析命令行参数,并返回解析后的结果。
targetHost = options.targetHost # 获取目标主机
port_range = options.targetPort # 获取端口范围参数if (targetHost is None) or (port_range is None): # 如果未提供目标主机或端口范围,则输出用法信息并退出程序
print(parser.usage) # parser.usage 是一个属性,用于获取程序使用说明的自定义文本。
exit(0)targetPorts = parse_port_range(port_range) # 解析端口范围参数
Scan(targetHost, targetPorts) # 调用 Scan 函数执行端口扫描
# 程序入口
if __name__ == "__main__":
main() # 调用主函数开始执行端口扫描