当前位置: 代码网 > it编程>前端脚本>Python > Python实现IP端口扫描程序

Python实现IP端口扫描程序

2025年05月09日 Python 我要评论
完整代码#!/usr/bin/env python# -*- coding: utf-8 -*- """ip端口扫描程序输入ip地址,扫描该ip哪些端口对外是开放的,输出端口列表""" import

完整代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
"""
ip端口扫描程序
输入ip地址,扫描该ip哪些端口对外是开放的,输出端口列表
"""
 
import socket
import sys
import concurrent.futures
import ipaddress
from tabulate import tabulate
import time
 
def is_valid_ip(ip):
    """
    验证ip地址是否有效
    """
    try:
        ipaddress.ip_address(ip)
        return true
    except valueerror:
        return false
 
def scan_port(ip, port, timeout=1):
    """
    扫描单个端口是否开放
    
    参数:
        ip (str): 目标ip地址
        port (int): 要扫描的端口
        timeout (float): 连接超时时间(秒)
        
    返回:
        bool: 如果端口开放返回true,否则返回false
    """
    try:
        # 创建tcp套接字
        sock = socket.socket(socket.af_inet, socket.sock_stream)
        sock.settimeout(timeout)
        
        # 尝试连接
        result = sock.connect_ex((ip, port))
        
        # 关闭套接字
        sock.close()
        
        # 如果连接成功,端口是开放的
        return result == 0
    
    except (socket.error, socket.timeout, oserror):
        return false
 
def scan_ports(ip, port_range=none, max_workers=100):
    """
    扫描ip地址的多个端口
    
    参数:
        ip (str): 目标ip地址
        port_range (tuple): 端口范围,格式为(起始端口, 结束端口)
        max_workers (int): 最大并发线程数
        
    返回:
        list: 开放端口列表
    """
    if port_range is none:
        # 默认扫描常见端口
        port_range = (1, 1024)
    
    start_port, end_port = port_range
    open_ports = []
    total_ports = end_port - start_port + 1
    
    print(f"开始扫描 {ip} 的端口 {start_port}-{end_port}...")
    start_time = time.time()
    
    # 使用线程池进行并发扫描
    with concurrent.futures.threadpoolexecutor(max_workers=max_workers) as executor:
        # 创建扫描任务
        future_to_port = {
            executor.submit(scan_port, ip, port): port 
            for port in range(start_port, end_port + 1)
        }
        
        # 处理完成的任务
        completed = 0
        for future in concurrent.futures.as_completed(future_to_port):
            port = future_to_port[future]
            completed += 1
            
            # 显示进度
            if completed % 100 == 0 or completed == total_ports:
                progress = (completed / total_ports) * 100
                elapsed = time.time() - start_time
                print(f"进度: {completed}/{total_ports} ({progress:.1f}%) - 已用时间: {elapsed:.1f}秒", end="\r")
            
            try:
                if future.result():
                    open_ports.append(port)
                    print(f"\n发现开放端口: {port}")
            except exception as e:
                print(f"\n扫描端口 {port} 时出错: {e}")
    
    print(f"\n扫描完成! 总用时: {time.time() - start_time:.1f}秒")
    return open_ports
 
def display_open_ports(ip, open_ports):
    """
    显示开放端口列表
    """
    if not open_ports:
        print(f"\n{ip} 没有发现开放的端口")
        return
    
    # 尝试获取常见端口的服务名称
    port_info = []
    for port in sorted(open_ports):
        try:
            service = socket.getservbyport(port)
        except (socket.error, oserror):
            service = "未知"
        
        port_info.append([port, service])
    
    # 显示表格
    print(f"\n{ip} 的开放端口:")
    headers = ["端口", "可能的服务"]
    print(tabulate(port_info, headers=headers, tablefmt="grid"))
 
def main():
    """
    主函数
    """
    # 获取用户输入
    if len(sys.argv) > 1:
        target_ip = sys.argv[1]
    else:
        target_ip = input("请输入要扫描的ip地址: ")
    
    # 验证ip地址
    if not is_valid_ip(target_ip):
        print(f"错误: '{target_ip}' 不是有效的ip地址")
        sys.exit(1)
    
    # 获取端口范围
    try:
        custom_range = input("请输入要扫描的端口范围 (格式: 起始端口-结束端口) [默认: 1-1024]: ")
        if custom_range:
            start, end = map(int, custom_range.split('-'))
            if start < 1 or end > 65535 or start > end:
                raise valueerror
            port_range = (start, end)
        else:
            port_range = (1, 1024)
    except valueerror:
        print("错误: 无效的端口范围,使用默认范围 1-1024")
        port_range = (1, 1024)
    
    # 扫描端口
    open_ports = scan_ports(target_ip, port_range)
    
    # 显示结果
    display_open_ports(target_ip, open_ports)
 
if __name__ == "__main__":
    try:
        main()
    except keyboardinterrupt:
        print("\n\n扫描被用户中断")
        sys.exit(0)
    except exception as e:
        print(f"\n程序执行出错: {e}")
        sys.exit(1)

结果如下

方法补充

python批量扫描ip端口

该程序的主要功能如下:

1. 从自有api接口获取所有的外网ip段;

2. 用nmap 遍历扫描所有的ip段,-ox 生成xml的扫描报告;

3. 用xml.etree.elementtree模块方法读取xml文件,将ip,开放端口,对应服务等写入mysql数据库。

功能很简单,没有满足老大高大上的需求,所以这个小项目就这么英勇的挂掉了!~~~完全都还没考虑程序异常终止,扫描服务器异常歇菜的情况。

贴上代码:

#coding:utf-8
import sys,os,time,subprocess
import mysqldb
import re,urllib2
import configparser
from ipy import ip
import xml.etree.elementtree as et
nowtime = time.strftime('%y-%m-%d',time.localtime(time.time()))
configpath=r'c:portscanconfig.ini'
#传入api接口主路径,遍历获取所有的ip列表,用ipy模块格式成127.0.0.1/24的格式
def getiplist(ipinf):
serverarea=['tj101','tj103','dh','dx']
iplist=[]
for area in serverarea:
ipapi=urllib2.urlopen(ipinf+area).read()
for ip in ipapi.split('n'):
#判断如果ip列表不为空,转换成ip/网关格式,再格式化成ip/24的格式
if ip:
ip=ip.replace('_','/')
ip=(ip(ip))
iplist.append(str(ip))
ipscan(iplist,nmapathx)
#传递ip地址文件和nmap路径
def ipscan(iplist,nmapath):
#古老的去重,对ip文件中的ip地址进行去重
newiplist=[]
scaniplist=[]
for ip in iplist:
if ip not in newiplist:
newiplist.append(ip)
#遍历所有ip段,批量扫描,生成xml格式报告
for ip in newiplist:
filename=nowtime+ip.split('/')[0]+'.xml'
filepath=r"c:portscanscanres\"
nmapcmd=nmapath+' -pt '+ip.strip('rn')+' -ox '+filepath+filename
os.system(nmapcmd)
scaniplist.append(ip)
writeinmysql(scaniplist)
#入库模块是某大婶发写好的给我 我只是简单修改了哈,主要是xml.etree.elementtree模块。
def writeinmysql(scaniplist):
filepath=r"c:portscanscanres"
for ip in scaniplist:
xmlfile=filepath+'\'+ip+'.xml'
#缩进哈 发文章的时候临时改的,懒得缩进了
root=et.parse(xmlfile).getroot()
allhost=root.findall('host')
conn=mysqldb.connect(host='10.5.10.57',user='nxadmin',passwd='nxadmin.com',port=3306,db='scandb',charset='utf8')
cur= conn.cursor()
for host in allhost:
address = host.find('address')
#首先判断端口是不是open的,如果是再进行入库
for port in host.find('ports').findall('port'):
if port.find('state').attrib['state']=="open":
ip=address.attrib['addr']
portval=port.attrib['portid']
state=port.find('state').attrib['state']
sql = "insert into portscan (ip,port,state) values(%s,%s,%s)"
params=[ip,portval,state]
cur.execute(sql,params)
conn.commit()
cur.close()
conn.close()
if __name__=="__main__":
#读取配置文件中要扫描的ip apiurl和nmap安装文件路径
config=configparser.configparser()
config.readfp(open(configpath,'rb'))
nmapathx=config.get('nmap','nmapath')
ipinf=config.get('ip','ipinf')
getiplist(ipinf)

配置文件c:portscanconfig.ini中主要是api接口主url,nmap安装路径。

python 使用 scapy 扫描内网ip或端口

1.利用icmp协议探测内网ip

def ping_ip(ip_fex):
    # 扫描范围: 128~254
    for i in range(128, 255):
        ip = f'{ip_fex}.{i}'
        print(f'\r{ip}', end='')
        output = os.popen(f'ping -n 1 -w 100 {ip} | findstr ttl=').read()
        if len(output) > 0:
            print(f"\n{ip} online")

if __name__ == '__main__':
	ping_ip('192.168.110')

2.利用arp协议探测内网ip

def ip_thread(start, ip_fex):
    for i in range(start, start + 20):
        ip = f'{ip_fex}.{i}'  # 目标ip
        try:
            pkg = arp(psrc=f'{ip_fex}.1', pdst=ip) # 伪造arp广播
            reply = sr1(pkg, timeout=1, verbose=false) # 发送arp并获取响应包
            if reply:
                print(f'\n{ip}->{reply[arp].hwsrc}') # 显示mac地址
            else:
                print(f'\r{ip} ...', end='')
        except exception as e:
            print(e)

def ip_scan(ip_fex):
	# 关闭警告
    import logging
    logging.getlogger("scapy.runtime").setlevel(logging.error)
	# 端口范围 1~254
    for i in range(1, 255, 20): 
        threading.thread(target=ip_thread, args=(i, ip_fex)).start()

3.利用tcp协议探测端口

端口信息在tcp层, 可以使用tcp协议数据包探测端口是否开放

伪造 syn 数据包, 根据响应数据中的标志位 flags 来判断端口是否正常响应.

syn: 0x002
ack: 0x010
syn-ack: 0x012

def scan_port(ip):
    for port in range(22, 100):
        try:
            pkg = ip(src='192.168.112.123', dst=ip) / tcp(dport=port, flags='s')
            reply = sr1(pkg, timeout=1, verbose=false)
            if reply:
                if reply[tcp].flags == 0x12: # syn-ack
                    print(f'port->[{port}]')
        except exception as e:
            print(e)

到此这篇关于python实现ip端口扫描程序的文章就介绍到这了,更多相关python ip端口扫描内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

  • 使用Python开发智能文件备份工具

    概述在数字化时代,数据备份已成为个人和企业数据管理的重要环节。本文将详细介绍如何使用python开发一款功能全面的桌面级文件备份工具,该工具不仅支持即时备份,还能实现定时自动备份、…

    2025年05月09日 前端脚本
  • Python 异步编程 asyncio简介及基本用法

    Python 异步编程 asyncio简介及基本用法

    1、asyncio是什么async io(异步输入输出)是一种编程模式,它允许程序在等待i/o操作(如文件读写、网络请求等)完成时继续执行其他任务。通过这种方式... [阅读全文]
  • Python实现剪贴板历史管理器

    Python实现剪贴板历史管理器

    一、概述:为什么需要剪贴板历史管理在日常工作和编程中,剪贴板是我们使用最频繁的功能之一。但windows自带的剪贴板只能保存最近一次的内容,当我们需要回溯之前复... [阅读全文]
  • Python+wxPython构建图像编辑器

    Python+wxPython构建图像编辑器

    引言图像编辑应用是学习 gui 编程和图像处理的绝佳项目。在本教程中,我们将使用 wxpython,一个跨平台的 python gui 工具包,构建一个简单的图... [阅读全文]
  • Python实现多格式文件预览工具

    Python实现多格式文件预览工具

    在日常办公或文件管理场景中,我们经常面临这样的问题:在一个文件夹中短时间内产生了大量不同类型的文件(如图片、pdf、word、excel),我们需要快速浏览和筛... [阅读全文]
  • python uv 基本使用教程

    python uv 基本使用教程

    以下是 uv 的使用教程。uv 是一个由 astral 开发的超快 python 包安装工具和解析器,使用 rust 编写,旨在替代 pip、pip-tools... [阅读全文]

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com