Python 实战:内网渗透中的信息收集自动化脚本(2)

用途限制声明,本文仅用于网络安全技术研究、教育与知识分享。文中涉及的渗透测试方法与工具,严禁用于未经授权的网络攻击、数据窃取或任何违法活动。任何因不当使用本文内容导致的法律后果,作者及发布平台不承担任何责任。渗透测试涉及复杂技术操作,可能对目标系统造成数据损坏、服务中断等风险。读者需充分评估技术能力与潜在后果,在合法合规前提下谨慎实践。

这次主要介绍子域名爆破脚本,关于这个脚本大家应该不会陌生一个工具,oneforall子域名爆破,接下来我们就从代码的角度看看是如何进行子域名爆破的,先提供源码,再进行逐个模块分析

import dns.resolver
import socket
import argparse
import time
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor, as_completed
import logging
from typing import List, Optional# 配置日志输出
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(message)s',handlers=[logging.FileHandler("dns_exploration.log"),logging.StreamHandler()]
)
logger = logging.getLogger(__name__)def reverse_dns(ip: str) -> Optional[List[str]]:"""反向DNS查询,获取IP对应的域名信息"""try:result = socket.gethostbyaddr(ip)return [result[0]] + result[1]except (socket.herror, socket.timeout):return Nonedef dns_request(domain: str, record_type: str = 'A') -> List[str]:"""DNS查询函数,支持多种记录类型:param domain: 待查询域名:param record_type: DNS记录类型(A, AAAA, CNAME, MX, NS等):return: 查询到的记录列表"""ips = []try:resolver = dns.resolver.Resolver()resolver.timeout = 5  # 超时时间resolver.lifetime = 10  # 总生命周期result = resolver.resolve(domain, record_type)for answer in result:record_value = answer.to_text()ips.append(record_value)logger.info(f"域名: {domain} | 类型: {record_type} | 记录值: {record_value}")# 对A/AAAA记录进行反向查询if record_type in ['A', 'AAAA']:reverse_domains = reverse_dns(record_value)if reverse_domains:logger.info(f"  反向解析: {', '.join(reverse_domains)}")except dns.resolver.NXDOMAIN:logger.debug(f"域名不存在: {domain} (类型: {record_type})")except dns.resolver.NoAnswer:logger.debug(f"无{record_type}记录: {domain}")except (dns.exception.Timeout, dns.resolver.NoNameservers):logger.warning(f"查询超时/无可用DNS服务器: {domain} (类型: {record_type})")except Exception as e:logger.error(f"查询错误 {domain}: {str(e)}")return ipsdef check_subdomain(word: str, domain: str, record_types: List[str], nums: bool) -> List[str]:"""检查单个子域名(含数字后缀变种)"""successes = []# 基础子域名subdomain = f"{word}.{domain}"for rtype in record_types:if dns_request(subdomain, rtype):successes.append(subdomain)# 带数字后缀的子域名if nums:for i in range(10):num_subdomain = f"{word}{i}.{domain}"for rtype in record_types:if dns_request(num_subdomain, rtype):successes.append(num_subdomain)return successesdef subdomain_search(domain: str, dictionary: List[str], nums: bool = False,record_types: List[str] = ['A'], threads: int = 5) -> List[str]:"""子域名枚举主函数:param domain: 主域名:param dictionary: 子域名字典列表:param nums: 是否检查数字后缀:param record_types: 需要查询的DNS记录类型:param threads: 线程数,控制并发:return: 所有存在的子域名列表"""successes = []total = len(dictionary)start_time = time.time()with ThreadPoolExecutor(max_workers=threads) as executor:# 提交所有任务futures = {executor.submit(check_subdomain, word, domain, record_types, nums): wordfor word in dictionary}# 跟踪进度completed = 0for future in as_completed(futures):completed += 1progress = (completed / total) * 100logger.info(f"进度: {progress:.2f}% ({completed}/{total})")successes.extend(future.result())logger.info(f"枚举完成,耗时: {time.time() - start_time:.2f}秒")return list(set(successes))  # 去重def save_results(results: List[str], domain: str) -> None:"""保存结果到文件"""timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")filename = f"subdomains_{domain}_{timestamp}.txt"with open(filename, "w") as f:for subdomain in sorted(results):f.write(f"{subdomain}\n")logger.info(f"结果已保存到: {filename}")def main():# 命令行参数解析parser = argparse.ArgumentParser(description="高级DNS子域名枚举工具")parser.add_argument("-d", "--domain", required=True, help="目标主域名 (例如: google.com)")parser.add_argument("-f", "--file", default="subdomains.txt", help="子域名字典文件路径")parser.add_argument("-n", "--nums", action="store_true", help="检查带数字(0-9)后缀的子域名")parser.add_argument("-t", "--types", default="A", help="DNS记录类型,多个用逗号分隔 (例如: A,AAAA,CNAME)")parser.add_argument("-th", "--threads", type=int, default=5, help="并发线程数 (默认: 5)")args = parser.parse_args()# 解析记录类型record_types = [t.strip().upper() for t in args.types.split(',')]# 读取字典文件try:with open(args.file, "r", encoding="utf-8") as f:dictionary = [line.strip() for line in f if line.strip()]logger.info(f"已加载字典文件: {args.file} (共{len(dictionary)}个条目)")except FileNotFoundError:logger.error(f"字典文件不存在: {args.file}")return# 执行子域名枚举logger.info(f"开始枚举 {args.domain} 的子域名...")results = subdomain_search(domain=args.domain,dictionary=dictionary,nums=args.nums,record_types=record_types,threads=args.threads)# 输出结果if results:logger.info(f"共发现 {len(results)} 个有效子域名:")for sub in sorted(results):logger.info(f"  - {sub}")save_results(results, args.domain)else:logger.info("未发现有效子域名")if __name__ == "__main__":main()

1. 模块导入与日志配置

import dns.resolver
import socket
import argparse
import time
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor, as_completed
import logging
from typing import List, Optional# 配置日志输出
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(message)s',handlers=[logging.FileHandler("dns_exploration.log"),logging.StreamHandler()]
)
logger = logging.getLogger(__name__)
解析:
  • 模块选择逻辑

    • dns.resolver:核心 DNS 查询工具,用于解析域名的各类 DNS 记录(替代原始版本的基础查询)。
    • socket:仅保留反向 DNS 查询功能(IP→域名映射)。
    • argparse:实现命令行参数解析,让工具支持灵活配置(如指定域名、字典文件等)。
    • concurrent.futures:提供线程池支持,实现并发查询以提升效率(解决原始版本单线程慢的问题)。
    • logging:替代原始的print输出,支持多级别日志(INFO/WARNING/ERROR)和双目标输出(控制台 + 文件)。
    • typing:添加类型注解,提升代码可读性和 IDE 支持(如List[str]表示字符串列表)。
  • 日志配置细节

    • level=logging.INFO:默认输出 INFO 及以上级别日志(DEBUG 信息需手动开启)。
    • format:包含时间戳、日志级别和消息内容,便于追溯执行过程。
    • handlers:同时输出到文件(dns_exploration.log)和控制台,既保留记录又方便实时查看。

2. 反向 DNS 查询函数 reverse_dns

def reverse_dns(ip: str) -> Optional[List[str]]:"""反向DNS查询,获取IP对应的域名信息"""try:result = socket.gethostbyaddr(ip)return [result[0]] + result[1]except (socket.herror, socket.timeout):return None
解析:
  • 功能定位:通过 IP 地址反向解析对应的域名(IP→域名映射),补充正向 DNS 查询的信息。
  • 参数与返回值
    • 输入ip: str:待查询的 IP 地址(IPv4 或 IPv6)。
    • 返回Optional[List[str]]:可能为None(解析失败)或域名列表(主域名 + 别名)。
  • 异常处理
    • socket.herror:主机不存在或无反向记录时触发。
    • socket.timeout:查询超时(新增处理,解决原始版本未处理超时的问题)。
  • 实现细节socket.gethostbyaddr(ip)返回元组(主机名, 别名列表, IP列表),此处提取主机名和别名合并为列表返回。

3. DNS 查询函数 dns_request

def dns_request(domain: str, record_type: str = 'A') -> List[str]:"""DNS查询函数,支持多种记录类型:param domain: 待查询域名:param record_type: DNS记录类型(A, AAAA, CNAME, MX, NS等):return: 查询到的记录列表"""ips = []try:resolver = dns.resolver.Resolver()resolver.timeout = 5  # 超时时间resolver.lifetime = 10  # 总生命周期result = resolver.resolve(domain, record_type)for answer in result:record_value = answer.to_text()ips.append(record_value)logger.info(f"域名: {domain} | 类型: {record_type} | 记录值: {record_value}")# 对A/AAAA记录进行反向查询if record_type in ['A', 'AAAA']:reverse_domains = reverse_dns(record_value)if reverse_domains:logger.info(f"  反向解析: {', '.join(reverse_domains)}")except dns.resolver.NXDOMAIN:logger.debug(f"域名不存在: {domain} (类型: {record_type})")except dns.resolver.NoAnswer:logger.debug(f"无{record_type}记录: {domain}")except (dns.exception.Timeout, dns.resolver.NoNameservers):logger.warning(f"查询超时/无可用DNS服务器: {domain} (类型: {record_type})")except Exception as e:logger.error(f"查询错误 {domain}: {str(e)}")return ips
解析:
  • 核心改进:从原始版本仅支持 A 记录查询,扩展为支持任意 DNS 记录类型(A/AAAA/CNAME/MX 等)。
  • ** resolver 配置 **:
    • timeout=5:单次查询超时时间(5 秒),避免长时间阻塞。
    • lifetime=10:总查询生命周期(10 秒),包含重试时间,防止无限等待。
  • 记录处理逻辑
    • 对查询结果result遍历,将每条记录转为文本(如 A 记录的 IP、CNAME 的域名)并存储。
    • 仅对 A/AAAA 记录(IP 地址记录)触发反向查询,因为其他类型(如 MX)的记录值不是 IP,无需反向解析。
  • 异常处理增强
    • NXDOMAIN:域名不存在(DEBUG 级别,避免日志冗余)。
    • NoAnswer:域名存在但无指定类型记录(如查询 AAAA 但域名仅支持 IPv4)。
    • Timeout/NoNameservers:警告级别,提示网络或 DNS 服务器问题。
    • 通用异常捕获:防止未预料的错误导致程序崩溃。

4. 子域名检查函数 check_subdomain

def check_subdomain(word: str, domain: str, record_types: List[str], nums: bool) -> List[str]:"""检查单个子域名(含数字后缀变种)"""successes = []# 基础子域名subdomain = f"{word}.{domain}"for rtype in record_types:if dns_request(subdomain, rtype):successes.append(subdomain)# 带数字后缀的子域名if nums:for i in range(10):num_subdomain = f"{word}{i}.{domain}"for rtype in record_types:if dns_request(num_subdomain, rtype):successes.append(num_subdomain)return successes
解析:
  • 功能定位:处理单个字典词的子域名生成与查询,是并发任务的最小执行单元。
  • 逻辑拆分
    1. 基础子域名:将字典词与主域名拼接(如word + .google.com),查询所有指定记录类型。
    2. 数字后缀子域名:若nums=True,在字典词后拼接 0-9 数字(如word0.google.com),再查询记录类型。
  • 去重预备:返回的successes列表可能包含重复子域名(如同一子域名同时有 A 和 CNAME 记录),后续在主函数中通过list(set(successes))去重。

5. 子域名枚举主函数 subdomain_search

def subdomain_search(domain: str, dictionary: List[str], nums: bool = False,record_types: List[str] = ['A'], threads: int = 5) -> List[str]:"""子域名枚举主函数:param domain: 主域名:param dictionary: 子域名字典列表:param nums: 是否检查数字后缀:param record_types: 需要查询的DNS记录类型:param threads: 线程数,控制并发:return: 所有存在的子域名列表"""successes = []total = len(dictionary)start_time = time.time()with ThreadPoolExecutor(max_workers=threads) as executor:# 提交所有任务futures = {executor.submit(check_subdomain, word, domain, record_types, nums): wordfor word in dictionary}# 跟踪进度completed = 0for future in as_completed(futures):completed += 1progress = (completed / total) * 100logger.info(f"进度: {progress:.2f}% ({completed}/{total})")successes.extend(future.result())logger.info(f"枚举完成,耗时: {time.time() - start_time:.2f}秒")return list(set(successes))  # 去重
解析:
  • 并发核心:使用ThreadPoolExecutor实现多线程查询,解决原始版本单线程效率低下的问题。max_workers=threads控制并发数(默认 5,可通过命令行调整)。
  • 任务管理
    • executor.submit:为每个字典词提交一个check_subdomain任务,返回Future对象(代表异步任务)。
    • as_completed(futures):迭代已完成的任务,实时获取结果并更新进度。
  • 进度跟踪:通过completed/total计算进度百分比,让用户了解枚举进展(原始版本无进度提示)。
  • 性能优化
    • 并发查询大幅缩短总耗时(尤其字典较大时)。
    • 最终通过list(set(successes))去重,避免同一子域名被多次记录。

6. 结果保存与主函数 main

def save_results(results: List[str], domain: str) -> None:"""保存结果到文件"""timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")filename = f"subdomains_{domain}_{timestamp}.txt"with open(filename, "w") as f:for subdomain in sorted(results):f.write(f"{subdomain}\n")logger.info(f"结果已保存到: {filename}")def main():# 命令行参数解析parser = argparse.ArgumentParser(description="高级DNS子域名枚举工具")parser.add_argument("-d", "--domain", required=True, help="目标主域名 (例如: google.com)")parser.add_argument("-f", "--file", default="subdomains.txt", help="子域名字典文件路径")parser.add_argument("-n", "--nums", action="store_true", help="检查带数字(0-9)后缀的子域名")parser.add_argument("-t", "--types", default="A", help="DNS记录类型,多个用逗号分隔 (例如: A,AAAA,CNAME)")parser.add_argument("-th", "--threads", type=int, default=5, help="并发线程数 (默认: 5)")args = parser.parse_args()# 解析记录类型record_types = [t.strip().upper() for t in args.types.split(',')]# 读取字典文件try:with open(args.file, "r", encoding="utf-8") as f:dictionary = [line.strip() for line in f if line.strip()]logger.info(f"已加载字典文件: {args.file} (共{len(dictionary)}个条目)")except FileNotFoundError:logger.error(f"字典文件不存在: {args.file}")return# 执行子域名枚举logger.info(f"开始枚举 {args.domain} 的子域名...")results = subdomain_search(domain=args.domain,dictionary=dictionary,nums=args.nums,record_types=record_types,threads=args.threads)# 输出结果if results:logger.info(f"共发现 {len(results)} 个有效子域名:")for sub in sorted(results):logger.info(f"  - {sub}")save_results(results, args.domain)else:logger.info("未发现有效子域名")
解析:
  • save_results 函数

    • 生成带时间戳的文件名(如subdomains_google.com_20240520_153045.txt),避免结果文件覆盖。
    • 对结果排序后写入,方便阅读和后续处理。
  • main 函数(程序入口)

    1. 参数解析:通过argparse定义命令行参数,支持用户灵活配置目标域名、字典文件、记录类型等(原始版本需硬编码修改参数)。
    2. 字典加载:读取子域名字典文件,过滤空行,统计条目数(便于进度计算)。
    3. 流程调度:调用subdomain_search执行枚举,最终输出结果并保存到文件。

通过此代码,我们能够了解子域名爆破的内在逻辑,以及通过附加的功能以及不断优化从而能够在大多数的情况下进行子域名爆破。以上源代码能够进行基本的使用,这里主要作用是能够通过代码了解工具的内在原理,代码可自行进行完善等操作。还有,爆破就重要的一点,就是需要一个强大的字典。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/94419.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/94419.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

批量转双层PDF软件:高效转换,提升文档管理效率

在文档管理和信息检索中,双层PDF文件因其独特的结构而备受青睐。双层PDF文件不仅保留了原始文档的外观,还增加了对文档内容进行搜索和选择的功能,极大地提高了文档管理和信息检索的效率。批量转双层PDF软件正是为了解决这一需求而设计的&…

rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(七) 鼠标在控件上悬浮时的提示

文本提示on_hover_text ui.label("标签").on_hover_text("这是一个标签"); ui.text_edit_singleline(&mut edittext).on_hover_text("这是输入框"); if ui.button("提交").on_hover_text("这是一个按钮").clicked(){}提…

【NVIDIA-B200】生产报错 Test CUDA failure common.cu:1035 ‘system not yet initialized‘

目录 1. 检查 NVIDIA 驱动状态 2. 验证 CUDA 安装情况 3. 检查相关服务运行状态(多 GPU 场景关键) 4. 用简单 CUDA 程序验证基础功能 5. 重启系统 6. 排查硬件相关问题 7.实际生产解决步骤 报错日志: # Collective test starting: all_reduce_perf # nThread 1 nGpu…

ansible playbook 实战案例roles | 实现基于nfs的日志归档

文章目录一、核心功能描述二、roles内容2.1 文件结构2.2 tasks文件内容2.3 files文件内容免费个人运维知识库,欢迎您的订阅:literator_ray.flowus.cn 一、核心功能描述 这个 Ansible Role 的核心功能是:​实现自动化日志归档系统&#xff0c…

RabbitMQ:技巧汇总

目录一、基础知识1.1、RabbitMQ:Windows版本安装部署1.2、RabbitMQ:Linux版本安装部署1.3、RabbitMQ:数据隔离1.4、RabbitMQ:交换机(Exchange)1.5、RabbitMQ:SpringAMQP入门案例1.6、RabbitMQ&a…

【ARM vs RISC-V:芯片架构双雄争霸,谁将主宰AI时代?】

2010年,加州大学伯克利分校的实验室诞生了一个颠覆性的构想——RISC-V开源指令集。谁曾想,这个学术项目会在15年后让芯片巨头ARM如临大敌?2025年7月,ARM悄悄上线riscv-basics.com质疑网站又紧急撤下的戏剧性事件,揭开了…

深入理解纹理与QtOpenGL的实现

引言 在现代计算机图形学中,纹理(Texture)是增强三维模型视觉效果的重要工具。通过将二维图像映射到三维模型表面,纹理可以为简单的几何形状添加复杂的细节和真实感。OpenGL作为广泛使用的图形库,提供了强大的纹理处理…

CrystalDiskInfo中文版(硬盘检测工具) 中文版

获取地址:硬盘检测工具 Process Lasso是一款独特的调试进程级别的系统优化工具,主要功能是基于其特别的算法动态调整各个进程的优先级并设为合理的优先级以实现为系统减负的目的,可有效避免蓝屏、假死、进程停止响应、进程占用 CPU 时间过多…

K8S集群-基于Ingress资源实现域名访问

目录 一、准备 1、在master节点部署ingress的资源清单文件 2、在node节点部署ingress-1.11.tar镜像(根据部署环境选择版本) 二、基于NodePort模式验证 1、在master节点进入ingress的资源清单文件 2、修改deploy.yaml文件 3、生成deploy.yaml资源 4…

iOS 数据持久化

📱 iOS数据持久化 ✨ 核心概念 数据持久化是指将内存中的数据以特定格式保存到持久存储介质(如硬盘)的过程,使得应用重启后数据依然可用。在iOS中,由于沙盒机制的限制,应用只能访问自己沙盒内的文件。 沙盒…

数据结构 -- 树

一、树的基本概念(一)定义树是由 n(n ≥ 0) 个结点组成的有限集合,是一种非线性层次结构:当 n 0 时,称为空树;当 n > 0 时,存在唯一的根结点(无前驱结点&…

单片机---------WIFI模块

1.ESP-12F模组基础知识ESP12-F模组(安信可(Ai-Thinker)ESP8266系列模组)是一款基于乐鑫(Espressif)公司ESP8266芯片的Wi-Fi无线通信模块,广泛应用于物联网(IoT)领域。它体…

迅为RK3562开发板Android修改uboot logo

本文档配套资料在网盘资料“iTOP-3562 开发板\02_【iTOP-RK3562 开发板】开发资料\07_Android 系统开发配套资料\05_Android 修改 uboot logo 配套资料”路径下。1 准备 logo系统默认 uboot logo,如下图所示:我们如果想要替换这个 logo,首先要制作一个新…

反催收APP开发思路:用Flutter打造证据链管理工具

针对非法催收问题,熊哥分享了一款反催收APP的开发思路,旨在帮助“诚而不幸”的负债人收集骚扰证据,通过Flutter实现跨平台部署。本文整理其核心功能与技术方案,助力开发者快速上手!一、核心功能:证据收集与…

市政道路井盖缺失识别误报率↓82%!陌讯多模态融合算法实战优化与边缘部署

原创声明本文为原创技术解析文章,核心技术参数、架构设计及实战数据引用自 “陌讯技术白皮书”,文中算法实现与优化方案均基于实测验证,禁止未经授权转载或篡改内容。一、行业痛点:市政井盖识别的 “三大拦路虎”市政道路井盖作为…

navicat及SQLyog的下载和安装

navicat安装和使用navicat下载和安装navicat 下载navicat 的安装SQLyog下载和安装SQLyog 的下载SQLyog 的安装连接到MySQL数据库navicat下载和安装 navicat 下载 navicat下载地址 这两个都是满足我们需求的,均可 这样我们就得到了一个双击可执行的exe文件 navic…

在TencentOS3上部署OpenTenBase:从入门到实战的完整指南

文章目录前言初识OpenTenBase:不只是又一个分布式数据库OpenTenBase的核心特性环境准备系统环境检查安装必要的依赖包用户环境配置:安全第一创建专用用户配置SSH免密登录(单机部署也需要)源码编译:从零开始构建获取源码…

flink常见问题之超出文件描述符限制

引言Apache Flink 是一个强大且流行的流处理框架,它支持高吞吐量和低延迟的数据处理。在处理大规模数据流时,Flink 用户可能会遇到各种性能瓶颈,其中之一就是文件描述符的限制。文件描述符是操作系统用来表示打开文件或其他输入/输出资源的一…

雅菲奥朗SRE知识墙分享(一):『SRE对智能运维领域所产生的深远影响』

一、SRE推动了运维与开发的融合1、增强协作:SRE模式鼓励运维与开发团队之间的紧密合作,共享知识、资源和责任,共同解决系统稳定性和性能问题。2、共同目标:通过共同设定系统可靠性和性能目标,运维和开发团队能够协同工…

【JVM内存结构系列】一、入门:先搞懂整体框架,再学细节——避免从一开始就混淆概念

在Java开发中,你是否遇到过这些困惑:明明代码没写错,却突然抛出OutOfMemoryError?调优GC参数时,不知道-Xms和-XX:MetaspaceSize分别影响哪块内存?面试时被问“JVM内存结构和Java内存模型有啥区别”,只能含糊其辞? 其实,这些问题的根源都指向同一个核心——没搞懂JVM的…