|
|
# 导入所需的库
|
|
|
import shodan # 用于与Shodan API进行交互
|
|
|
import time # 用于时间操作(如延时)
|
|
|
|
|
|
# 从 client.subdomain.oneforall.config 模块导入 PortScan 配置信息
|
|
|
from client.subdomain.oneforall.config import PortScan
|
|
|
|
|
|
# 初始化检查标志,默认为True
|
|
|
check = True
|
|
|
|
|
|
# 检查是否配置了Shodan的API密钥
|
|
|
if not PortScan.shodan_api:
|
|
|
# 如果没有配置API密钥,输出错误信息并将check设为False
|
|
|
print('[-]端口扫描-未填写shodan api秘钥')
|
|
|
check = False
|
|
|
else:
|
|
|
# 如果有API密钥,则使用Shodan库进行初始化
|
|
|
API = shodan.Shodan(PortScan.shodan_api)
|
|
|
try:
|
|
|
# 稍微延时,防止请求过快导致问题
|
|
|
time.sleep(1)
|
|
|
# 测试API是否有效,调用API的info()方法
|
|
|
API.info()
|
|
|
except shodan.exception.APIError as e:
|
|
|
# 捕获Shodan API错误,输出错误信息
|
|
|
print(f'[-]端口扫描-shodan api秘钥错误:{e}')
|
|
|
check = False
|
|
|
except Exception as e:
|
|
|
# 捕获其他类型的异常
|
|
|
print(f'[-]端口扫描-shodan api接口异常:{e}')
|
|
|
check = False
|
|
|
|
|
|
# 定义扫描函数,接收IP地址作为参数
|
|
|
def Scan(ip):
|
|
|
# 打印扫描开始的提示信息
|
|
|
print(f'[+]端口扫描-开始shodan端口扫描')
|
|
|
try:
|
|
|
# 使用Shodan API查询指定IP的详细信息
|
|
|
ipinfo = API.host(ip)
|
|
|
except Exception as e:
|
|
|
# 如果查询失败,捕获异常并打印错误信息
|
|
|
print(f'[-]端口扫描-shodan查询{ip}失败,原因:{e}')
|
|
|
return None, None # 返回None,表示扫描失败
|
|
|
# 获取该IP的开放端口列表
|
|
|
port_list = ipinfo.get('ports', None)
|
|
|
# 获取该IP的漏洞信息列表
|
|
|
vulns_list = ipinfo.get('vulns', None)
|
|
|
if port_list:
|
|
|
# 如果有端口信息,打印扫描完成的信息并返回端口列表和漏洞列表
|
|
|
print(f'[+]端口扫描-shodan端口扫描[{ip}]完成:{port_list}')
|
|
|
return port_list, vulns_list
|
|
|
else:
|
|
|
# 如果没有端口信息,返回None
|
|
|
return None, None
|
|
|
|
|
|
# 程序入口,执行端口扫描
|
|
|
if __name__ == '__main__':
|
|
|
# 调用Scan函数进行端口扫描,扫描IP地址'123.147.194.210'
|
|
|
port_list, vulns_list = Scan('123.147.194.210')
|
|
|
# 输出扫描结果(端口列表和漏洞列表)
|
|
|
print(port_list, vulns_list)
|