引言
在渗透过程中,经常会遇到 nmap 扫描不出端口的情况,web 端口确定开放,且用网上的在线端口扫描是可以扫描到的,但是 nmap 就是无法扫出来,因此花了些时间写了 2 个基于 python 端口扫描工具。
基于在线网站调用扫描工具
截图
代码
# -*- coding: utf-8 -*- import sys, getopt import requests import json import click def banner(): print(''' _____ _ _____ | __ \ | | / ____| | |__) |__ _ __| |_ | (___ ___ __ _ _ __ | ___/ _ \| '__| __| \___ \ / __/ _` | '_ \ | | | (_) | | | |_ ____) | (_| (_| | | | | |_| \___/|_| \__| |_____/ \___\__,_|_| |_| Author:MrWu Blog:www.mrwu.red ''') def save(data): f = open(r'F:\桌面\端口结果.txt', 'a') #记得修改此处路径为你要存放结果的路径 f.write(data + '\n') f.close() def run(url): try: for port in range(1,65536): headers ={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36'} data = {'port':url,'ports':port} data = requests.post('http://www.yzcopen.com/seo/getport',data=data,headers = headers) data = json.loads(data.text) result = data["restparm"] data = " ".join('%s' %a for a in result) if "开启" in data: click.secho(f"[√] %s 端口开启"%(port), fg="red") save("%s:%s 端口开启"%(url,port)) else: print("[×] %s 端口关闭"%(port)) click.secho(f"[ok] 全部端口扫描完毕", fg="red") except: pass def main(argv): banner() try: options, args = getopt.getopt(argv, "hp:i:", ["help", "url="]) except getopt.GetoptError: print("使用方法: python portscan.py --url www.baidu.com") sys.exit() for option, value in options: if option in ("-h", "--help"): print("使用方法: python portscan.py --url www.baidu.com") if option in ("-u", "--url"): print("目标:%s 端口扫描任务现在开始\n"%(value)) run(value) if __name__ == '__main__': main(sys.argv[1:])
说明
- 修改代码中 19 行,成功结果保存路径为你自己的路径。
- 由于是调用第三方,所以并没有加入多线程,否则会触发防火墙拉IP。
- 工具默认扫描 1-65535 全端口,如果需要扫描指定端口范围,可修改代码 25 行中的 1 (起始端口) 和 65536 (结束端口)
基于 socket 的多线程扫描工具2
截图
代码
# -*- coding: utf-8 -*- # @Author: mrwu # @Date: 2022-05-12 16:46:09 # @Last Modified by: mrwu # @Last Modified time: 2022-05-17 15:23:51 # 多线程扫描工具 import queue import socket import sys import threading import time def banner(): print(''' _____ _ _____ | __ \ | | / ____| | |__) |__ _ __| |_ | (___ ___ __ _ _ __ | ___/ _ \| '__| __| \___ \ / __/ _` | '_ \ | | | (_) | | | |_ ____) | (_| (_| | | | | |_| \___/|_| \__| |_____/ \___\__,_|_| |_| Author:MrWu Blog:www.mrwu.red ''') # 定义端口扫描类 # 要想创建一个线程对象,只要继承类threading.Thread,然后在__ init__里边调用threading.Thread.__init__()方法 class PortScaner(threading.Thread): def __init__(self, ip, portqueue, timeout=3): threading.Thread.__init__(self) self.portqueue = portqueue self.ip = ip self.timeout = timeout def run(self): while True: # 判断当前端口是否为空,为空跳False跳出循环,否则从队列中取出端口,判断当超过指定时间的话退出等待 if self.portqueue.empty(): break port = self.portqueue.get(timeout=0.5) time.sleep(0.2) print("\r[-] 正在扫描端口: ".format(port)+str(port)+"/"+str(end_port), end="") try: # Ipv4网络协议 提供面向连接的稳定数据传输,建立可靠的通讯,即TCP协议 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 超时调用,超过时间,就执行 s.settimeout(self.timeout) result_code = s.connect_ex((self.ip, port)) # 该方法如果链接成功会返回0,失败会返回errno库中的errorcode中的key,当为0是代表端口开放 if result_code == 0: sys.stdout.write(f"\r[!] 目标: {self.ip}:%d 端口开放\n" % port) except Exception as e: print(e) finally: s.close() # 根据用户输入的参数来指定目标ip,端口队列的生成以及子线程的生成,同时还支持单个端口的扫描和范围端口的扫描 def StartScan(targetip, start_port, end_port, threadNum): portlist = [] # 端口列表 for i in range(start_port, end_port): portlist.append(i) # 目标ip地址 ip = targetip # 线程列表 threads = [] # 线程数量 threadNumber = threadNum # 端口队列 portQueue = queue.Queue() # 生成端口,加入端口队列 for port in portlist: portQueue.put(port) for t in range(threadNumber): threads.append(PortScaner(ip, portQueue, timeout=3)) # 启动线程 for thread in threads: thread.start() # 阻塞线程 for thread in threads: thread.join() # 主函数 if __name__ == '__main__': banner() print("----------------------------------------------") ip = input(' 输入目标IP:') if not ip: ip = '127.0.0.1' print(" >>>>[1] 端口范围 [2] 指定端口") dk = input(' 根据上述输入选择 (默认1):') if not dk: dk = '1' if dk == '1': start_port = input(' 输入起始端口 (默认1):') if not start_port: start_port = 1 end_port = input(' 输入结束端口 (默认65535):') if not end_port: end_port = 65535 elif dk == '2': start_port = input(' 输入指定端口:') end_port = start_port threadNum = input(' 输入线程数 (默认100-太高容易不准确):') if not threadNum: threadNum = 100 print("----------------------------------------------") #print('\n') StartScan(ip, int(start_port), int(end_port)+1, int(threadNum)) print("\r[√] 所有扫描均已完成!")
说明
- 线程最好不要太高,太高会漏掉一些开放的端口。
本文作者为Mr.Wu,转载请注明,尊守博主劳动成果!
由于经常折腾代码,可能会导致个别文章内容显示错位或者别的 BUG 影响阅读; 如发现请在该文章下留言告知于我,thank you !
有没有整理一些现成的工具,可以直接使用得当