引言
在渗透过程中,经常会遇到 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[√] 所有扫描均已完成!")
说明
- 线程最好不要太高,太高会漏掉一些开放的端口。