由于goby无法进行ipv6的端口扫描,所以编写python代码进行单独的ipv6的端口扫描(将近500个ipv6 大概2天左右时间)
安装的第三方模块(通过 pip 安装
nmap
模块(是 python-nmap
的封装)。用于调用 Nmap 扫描器。
安装命令:
pip install python-nmap
tqdm
用于显示进度条的库。
安装命令:
pip install tqdm
第一部分:文件加载、IP 地址扫描与端口扫描
import nmap
import csv
from tqdm import tqdm
import concurrent.futures
def is_ipv6(address):
return ':' in address
def load_from_file(file_path):
try:
with open(file_path, 'r') as file:
return [line.strip() for line in file if line.strip()]
except FileNotFoundError:
print(f"文件 {file_path} 不存在!")
return []
def scan_port(ip, range_ports, specified_ports, batch_size=3000):
scanner = nmap.PortScanner()
results = []
ip_version_flag = "-6" if is_ipv6(ip) else ""
try:
with tqdm(total=len(specified_ports), desc=f"扫描 {ip} 的指定端口", unit="端口") as port_bar:
for port in specified_ports:
try:
scanner.scan(ip, arguments=f"{ip_version_flag} -p {port} -Pn -T4 -n")
found = False
for host in scanner.all_hosts():
for proto in scanner[host].all_protocols():
proto_ports = scanner[host][proto]
if port in proto_ports:
port_info = proto_ports[port]
results.append({
"Port": f"{port}/{proto}",
"State": port_info.get('state', 'unknown'),
"Service": port_info.get('name', 'unknown')
})
found = True
if not found:
results.append({
"Port": f"{port}/tcp",
"State": "closed",
"Service": "unknown"
})
except Exception as e:
results.append({
"Port": f"{port}/tcp",
"State": "error",
"Service": f"扫描异常: {e}"
})
port_bar.update(1)
with tqdm(total=len(range_ports), desc=f"扫描 {ip} 的范围端口", unit="端口") as port_bar:
for i in range(0, len(range_ports), batch_size):
batch_ports = range_ports[i:i + batch_size]
port_batch_str = ','.join(map(str, batch_ports))
scanner.scan(ip, arguments=f"{ip_version_flag} -Pn -p {port_batch_str} -T4 -n")
for host in scanner.all_hosts():
for proto in scanner[host].all_protocols():
for port in batch_ports:
if port in scanner[host][proto] and scanner[host][proto][port]['state'] == 'open':
port_info = scanner[host][proto][port]
results.append({
"Port": f"{port}/{proto}",
"State": "open",
"Service": port_info.get('name', 'unknown')
})
port_bar.update(len(batch_ports))
status = "up" if results else "down"
return {"Host": ip, "Status": status, "Results": results}
except Exception as e:
return {"Host": ip, "Error": f"扫描失败: {e}"}
第二部分:结果写入 CSV 文件并进行多线程扫描
def write_to_csv(output_file, all_results):
with open(output_file, mode='w', newline='', encoding='utf-8') as csvfile:
fieldnames = ['Host', 'Status', 'Port', 'State', 'Service']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for result in all_results:
host = result['Host']
status = result.get('Status', 'Error')
if 'Error' in result:
writer.writerow({
'Host': host,
'Status': 'Error',
'Port': '',
'State': '',
'Service': result['Error']
})
else:
for item in result['Results']:
writer.writerow({
'Host': host,
'Status': status,
'Port': item['Port'],
'State': item['State'],
'Service': item['Service']
})
if __name__ == "__main__":
ip_file = "ipv6.txt"
output_csv = "ipv6_scan_results.csv"
range_ports = range(1, 65536)
specified_ports = [
161, 443, 4430, 8001, 888, 8003, 830, 53, 123, 22, 179, 59022, 5082,
9090, 8000, 5061, 5060, 18032, 23, 59554, 6068, 646, 639, 8322, 7165,
7547, 4389, 6425, 6435, 8081, 2060, 2650, 18989, 50051, 9100, 20022,
32420, 554, 21, 111, 80, 2002
]
ips = load_from_file(ip_file)
if not ips:
print("IP 文件为空,无法继续扫描。")
else:
all_results = []
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
future_to_ip = {executor.submit(scan_port, ip, range_ports, specified_ports): ip for ip in ips}
with tqdm(total=len(ips), desc="IP 扫描进度", unit="IP") as ip_bar:
for future in concurrent.futures.as_completed(future_to_ip):
ip = future_to_ip[future]
try:
result = future.result()
all_results.append(result)
except Exception as e:
all_results.append({"Host": ip, "Error": f"扫描失败: {e}"})
ip_bar.update(1)
write_to_csv(output_csv, all_results)
print(f"扫描任务完成,结果保存在 {output_csv}")
运行截图
运行结果