python版局域网端口扫描

433 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情

使用python实现一个局域网端口扫描器,需要用到库是:

import ipaddress import socket import threading import os

os是内置库,主要用于执行命令 threading是一个多线程库,用于加快执行速度,是python第三方库,需要自己安装; socket是python内置库,用于链接端口,通过是否可以链接端口判断端口是否开放 ipaddress是一个ip地址库,用于实例化ip对象给到socket,第三方库,需要安装

安装threading和ipaddress推送使用pip方式,相对来说比较简单:

打开命令行窗口; 分别执行以下代码: pip install ipaddress pip install threading 等待安装成功

两个库的安装都比较简单,不依赖与其他库,直接安装即可;

代码实现 实现逻辑: python 局域网端口扫描器

  1. 通过执行ping命令获取指定网段的可用ip
  2. 通过socket链接扫描可用ip的端口
  3. 使用threading进行多线程任务

获取可用ip


live_ips = []
# ip 是否能ping通
def ping_ip(ip_str):
    cmd = ["ping", "-n","1", ip_str]
    output = os.popen(" ".join(cmd)).readlines()
    for line in output:
        if str(line).upper().find("TTL") >= 0:
            print("ip: %s is ok ***" % ip_str)
            live_ips.append(ip_str)
            break
 
 
def find_ip(ip_prefix):
  '''''
  给出当前的192.168.0 ,然后扫描整个段所有地址
  '''
  threads = []
  for i in range(1, 256):
    ip = '%s.%s' % (ip_prefix, i)
    threads.append(threading.Thread(target=ping_ip, args={ip, }))
  for i in threads:
    i.start()
  for i in threads:
    i.join()
 
find_ip('192.168.0')
print(live_ips)

枚举指定网段的所有ip地址,通过ping命令测试是否是可以ip;

扫描端口

port_start = 0
port_end = 100 #65535

def scan(ip_str):
    print(ip_str)
    ip = ipaddress.ip_address(ip_str)
    ports = []
    for port in range(port_start,port_end):
        try:
            with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as s:
                s.settimeout(0.5)
                s.connect(ip,port)
                ports.append(":".join(ip_str,port))
        except:
            print(str(port)+'端口不通')
            pass
    return ports

通过socket的实例化对象的connect方法,传入ip和端口,测试是否有返回;

最后通过多线程方法调用;

def scan_port():
    threads = []
    for live_ip in live_ips:
        threads.append(threading.Thread(target=scan,args={live_ip,}))
    for i in threads:
        i.start()
    for i in threads:
        i.join()
    print('执行结束...')

相比于单线程,多线程的速度明显更快;