IP扫描

环境

sudo apt update
sudo apt install python3-pip

pip3 install ipaddress

扫描多个子网(例如 142.171.0.0/24142.171.255.0/24

使用多个 IPv4Network 对象来遍历这些网段

# -*- coding: utf-8 -*-
import socket
import ipaddress
import argparse
import logging
from concurrent.futures import ThreadPoolExecutor

# 设置日志配置
logging.basicConfig(
    format='%(asctime)s - %(levelname)s - %(message)s',
    level=logging.INFO,  # 设置日志级别为 INFO
    handlers=[
        logging.StreamHandler(),  # 输出到控制台
        logging.FileHandler("scan_log.txt", mode='w')  # 写入文件 scan_log.txt
    ]
)

# 定义扫描的IP段和端口
ip_range_base = '142.171.'  # 需要扫描的IP段的前缀(142.171.xxx.xxx)
target_port = 54321  # 需要检查的端口

# 定义写入文件的路径
output_file = 'open_ips.txt'

# 扫描单个IP地址的指定端口
def scan_port(ip, port):
    try:
        # 创建socket连接
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(1)  # 设置超时时间,避免卡住
        result = sock.connect_ex((ip, port))  # 尝试连接目标端口
        sock.close()
        if result == 0:  # 如果连接成功,表示端口开放
            logging.info(f"Port {port} is open on {ip}")  # 日志输出
            return ip
        else:
            logging.debug(f"Port {port} is closed on {ip}")  # 调试日志
    except socket.error as e:
        logging.error(f"Error with IP {ip}, port {port}: {e}")  # 错误日志
    return None

# 扫描指定IP段内的所有IP地址
def scan_ip_range(ip_range_base, start, end, port, max_threads):
    open_ips = []

    with ThreadPoolExecutor(max_workers=max_threads) as executor:  # 设置最大线程数
        for i in range(start, end+1):  # 扫描从start到end的网段
            ip_range = f"{ip_range_base}{i}.0/24"  # 生成 IP 段,如 142.171.0.0/24
            logging.info(f"Scanning IP range: {ip_range}")
            network = ipaddress.IPv4Network(ip_range)
            results = executor.map(scan_port, [str(ip) for ip in network.hosts()], [port] * len(list(network.hosts())))

            # 获取所有有开放端口的IP地址
            for result in results:
                if result:
                    open_ips.append(result)
    
    return open_ips

# 将开放端口的IP信息写入文件
def write_to_file(open_ips, filename):
    with open(filename, 'w') as f:
        for ip in open_ips:
            f.write(f"{ip} has port {target_port} open\n")
    logging.info(f"Results saved to {filename}")

# 解析命令行参数
def parse_args():
    parser = argparse.ArgumentParser(description="Scan IP range for open ports")
    parser.add_argument("--threads", type=int, default=50, help="Number of threads for concurrent scanning (default: 50)")
    parser.add_argument("--start", type=int, default=0, help="Start of the last octet for IP range (default: 0)")
    parser.add_argument("--end", type=int, default=255, help="End of the last octet for IP range (default: 255)")
    return parser.parse_args()

# 主函数
if __name__ == '__main__':
    args = parse_args()  # 获取命令行参数
    logging.info(f"Starting scan on IP range {args.start} to {args.end} with port {target_port}")
    open_ips = scan_ip_range(ip_range_base, args.start, args.end, target_port, args.threads)
    write_to_file(open_ips, output_file)
    logging.info(f"Scan complete. Results are saved in {output_file}")

关键更新:

  1. IP 段范围控制

    • ip_range_base = '142.171.':这里设置了 IP 地址的前缀(如 142.171.),并在后面动态生成每个子网。
    • scan_ip_range(ip_range_base, start, end, port, max_threads):允许你控制扫描的最后一个子网(例如从 142.171.0.0/24142.171.255.0/24)。
  2. 命令行参数

    • 你可以通过命令行参数控制扫描的子网范围(如从 142.171.0.0/24142.171.255.0/24),以及线程数。
    • 参数:

      • --start:扫描的起始网段(默认从 0 开始)。
      • --end:扫描的结束网段(默认到 255)。
      • --threads:线程数,控制扫描速度(默认为 50)。

运行示例:

  1. 默认设置(扫描 142.171.0.0 到 142.171.255.0 的所有子网)

    python3 scan_ports.py
  2. 设置线程数为 100,扫描 142.171.100.0/24142.171.200.0/24

    python3 scan_ports.py --threads 100 --start 100 --end 200

运行效果:

  • 日志输出:将实时扫描信息输出到控制台和日志文件 scan_log.txt
  • 开放端口的 IP 地址:如果某个 IP 地址的端口开放,相关的 IP 会被记录在文件 open_ips.txt 中。

总结:

可以扫描多个子网范围,例如 142.171.0.0/24142.171.255.0/24,并且能够通过命令行参数动态控制扫描的起始和结束网段以及线程数。大大提高扫描的灵活性和效率。

如果觉得我的文章对你有用,请随意赞赏