You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MiaCTFer/client/portscan/portscan_run.py

110 lines
4.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 导入必要的模块
import os # 用于操作系统路径
import sys # 用于操作系统相关的功能
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../') # 将父级目录添加到模块搜索路径中
import time # 用于时间操作,例如延时
# 从client.portscan模块导入ShodanScan和NmapScan类用于进行端口扫描
from client.portscan.ShodanScan import Scan
from client.portscan.NmapScan import Nmap_Portscan
# 从client.database模块导入数据库会话和数据表模型
from client.database import session, SrcAssets, SrcPorts
# 定义PortScan类用于执行端口扫描操作
class PortScan:
def __init__(self, ip):
# 初始化方法接收IP地址
self.ip = ip
def run(self):
# 执行端口扫描
# 1. 使用Shodan扫描IP的端口和漏洞
port_list, vulns_list = Scan(ip=self.ip)
# 2. 使用Nmap扫描获取更详细的端口信息
port_dict = Nmap_Portscan(ip=self.ip, port_info_list=port_list)
# 返回端口扫描结果和漏洞信息
return port_dict, vulns_list
# 定义读取资产数据的函数
def ReadAssets():
'''读取资产数据'''
# 查询数据库获取未进行端口扫描的资产资产表中asset_port_flag为False
assets_sql = session.query(SrcAssets).filter(SrcAssets.asset_port_flag == False).first()
# 提交数据库事务
session.commit()
if assets_sql:
# 获取该资产的IP地址
ip = assets_sql.asset_ip
# 查询所有具有相同IP地址的资产
assets_sql1 = session.query(SrcAssets).filter(SrcAssets.asset_ip == ip).all()
# 遍历所有相同IP的资产将其端口扫描状态更新为True
for sql in assets_sql1:
sql.asset_port_flag = True # 修改资产的端口扫描状态为True
session.add(sql) # 将修改的资产添加到会话中
try:
# 提交事务,将修改保存到数据库
session.commit()
except Exception as error:
# 如果提交失败,打印异常信息并回滚事务
print(f'[-]端口扫描-修改IP扫描状态异常{error}')
session.rollback()
# 返回读取到的资产数据
return assets_sql
# 定义将扫描结果写入数据库的函数
def WritePosts(port_dict, assets_sql):
'''端口扫描入库'''
# 遍历扫描到的端口信息
for info in port_dict:
# 构造要插入到数据库的端口数据
port_sql = SrcPorts(
port_name=assets_sql.asset_name, # 资产名称
port_host=assets_sql.asset_host, # 资产主机
port_ip=assets_sql.asset_ip, # 资产IP地址
port_port=port_dict[info]['port'], # 端口号
port_service=port_dict[info]['name'], # 服务名称
port_product=port_dict[info]['product'], # 产品名称
port_version=port_dict[info]['version'] # 产品版本
)
# 将端口信息添加到数据库会话中
session.add(port_sql)
try:
# 提交事务,将端口信息保存到数据库
session.commit()
except Exception as error:
# 如果提交失败,回滚事务并打印错误信息
session.rollback()
print(f'[-]端口入库异常{error}')
# 打印扫描结果已入库完成的提示
print(f'[+]端口[{assets_sql.asset_ip}]入库完成')
# 主函数,启动端口扫描和入库操作
def main():
print('[+]端口扫描启动')
while True:
# 读取资产数据
assets_sql = ReadAssets()
# 如果没有可处理的资产等待30秒后继续尝试
if not assets_sql:
time.sleep(30)
else:
# 创建PortScan实例传入要扫描的IP地址
portscan = PortScan(assets_sql.asset_ip)
# 运行端口扫描,获取端口信息和漏洞信息
port_dict, vulns_list = portscan.run()
# 如果扫描结果不为空,写入数据库
if port_dict:
WritePosts(port_dict, assets_sql)
# 如果该脚本作为主程序执行,启动端口扫描程序
if __name__ == '__main__':
main()