当前位置: 首页 > article >正文

批量ip反查域名工具

0x01 工具简介:

        ReverseIP-CN 是一款专为中文网络环境优化的IP反查工具,能够快速查询指定IP/域名关联的所有网站,是网络安全检测、资产梳理的利器。

0x02 功能简介:

1、智能解析

  • 支持多种输入格式:URLIP域名
  • 自动清洗不规范输入
    (示例:http://baidu.com/ → baidu.com

2、高效查询

  • 多线程并发处理(默认5线程)
  • 国内接口优化,响应更快
  • 智能去重,结果精准

3、可视化报告

  • 终端高亮显示关键信息
  • Excel报告自动标注重点条目
  • 支持结果导出(.xlsx格式)

4、Api可扩展

  • 依赖api可进行自行扩展

0x03 依赖包安装:

pip install -r requirements.txt
# requirements.txt

requests>=2.26.0      # HTTP请求库
openpyxl>=3.0.9       # Excel文件处理

0x04 使用方法:

参数说明

参数全称说明
-u--url指定单个目标URL/IP
-l--list指定包含多个目标的文件路径
-o--output指定输出Excel文件名(可选)
-h--help显示帮助信息

查询单个目标:

python revip_cn.py -u "目标URL/IP"

批量读取:

python revip_cn.py -l 目标列表.txt -o 结果.xlsx

目标文件格式支持:

https://127.0.0.1
http://127.0.0.1
127.0.0.1:8080
aaa.example.com
https://127.0.0.1:8080
127.0.0.1

效果截图:

0x05 源码及项目地址: 

项目地址:

https://github.com/iSee857/ReverseIP-CN

欢迎各位师傅们提供可用、稳定的api。

欢迎提交issue或评论与我联系。

项目源码:

import re
import sys
import socket
import random
import getopt
import requests
import openpyxl
import time
from urllib.parse import urlparse
from openpyxl.styles import PatternFill
from openpyxl.utils import get_column_letter
from concurrent.futures import ThreadPoolExecutor


HIGHLIGHT_FILL = PatternFill(start_color='FFFF00', fill_type='solid')
HEADER_FILL = PatternFill(start_color='DDDDDD', fill_type='solid')
VERSION = "V2.1"
AUTHOR = "iSee857"

def print_banner():
    banner = f"""
██████╗ ███████╗███████╗██████╗ ███████╗██████╗ ███████╗
██╔══██╗██╔════╝██╔════╝██╔══██╗██╔════╝██╔══██╗██╔════╝
██████╔╝█████╗  █████╗  ██║  ██║█████╗  ██████╔╝███████╗
██╔══██╗██╔══╝  ██╔══╝  ██║  ██║██╔══╝  ██╔══██╗╚════██║
██║  ██║███████╗██║     ██████╔╝███████╗██║  ██║███████║
╚═╝  ╚═╝╚══════╝╚═╝     ╚═════╝ ╚══════╝╚═╝  ╚═╝╚══════╝
Reverse IP Lookup Tool {VERSION}
Author: {AUTHOR}
"""
    print(banner)

def clean_target(target):
    """智能清洗输入目标"""
    try:
        target = target.strip(" '\"")
        if not target.startswith(('http://', 'https://')):
            target = f'http://{target}'
        
        parsed = urlparse(target)
        hostname = parsed.hostname
        if not hostname:
            return None
        
        return socket.gethostbyname(hostname)
    except Exception as e:
        print(f"解析失败: {str(e)}")
        return None

def user_agents():
    """国内主流浏览器User-Agent"""
    return [
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0",
        "Mozilla/5.0 (Linux; Android 10; M2007J3SC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36",
        "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1"
    ]

def fetch_domains_cn(ip):
    """使用国内接口查询IP关联域名"""
    headers = {
        'User-Agent': random.choice(user_agents()),
        'Referer': 'https://site.ip138.com/'
    }
    """国内接口可配"""
    apis = [
        {
            'url': f'https://site.ip138.com/{ip}/',
            'method': 'regex',
            'pattern': r'<li><span class="date">.*?</span><a href="/(.*?)/" target="_blank">'
        },
        #站点关闭
        # {
        #     'url': f'https://api.webscan.cc/?query={ip}',
        #     'method': 'json',
        #     'field': 'domain'
        # }
    ]
    
    domains = []
    for api in apis:
        try:
            session = requests.Session()
            session.trust_env = False
            response = session.get(
                api['url'],
                headers=headers,
                timeout=15,
                proxies={'http': None, 'https': None}
            )
            
            if response.status_code != 200:
                continue
                
            if api['method'] == 'regex':
                matches = re.findall(api['pattern'], response.text)
                cleaned = [m.strip() for m in matches if m.strip()]
                domains.extend(cleaned)
                
            elif api['method'] == 'json':
                data = response.json()
                if isinstance(data, list):
                    valid = [str(d.get(api['field'], '')).strip() for d in data]
                    domains.extend([v for v in valid if v])
            
            # 去重并限制最大数量防止站点重定向
            domains = list(set(domains))[:50]
            time.sleep(random.uniform(1, 2))
            
        except Exception as e:
            print(f"接口 {api['url']} 查询失败: {str(e)}")
            continue
            
    return domains

def process_target(target):
    """处理目标"""
    ip = clean_target(target)
    if not ip:
        print(f"\n❌ 目标解析失败: {target}")
        print("-" * 50)
        return (target, None)
    
    domains = fetch_domains_cn(ip)
    
    original_host = urlparse(target).hostname or target.split('//')[-1].split('/')[0]
    highlighted_domains = [
        f"\033[93m{d}*\033[0m" if (ip in d or original_host in d) else d 
        for d in domains if isinstance(d, str)
    ]
    
    ip_display = f"\033[92m{ip}\033[0m" if domains else ip
    
    print(f"\n► 原始输入: \033[94m{target}\033[0m")
    print(f"► 解析IP : {ip_display}")
    print(f"► 关联域名: {len(domains)} 个")
    
    if domains:
        print("  " + "\n  ".join(highlighted_domains))
    else:
        print("  未找到关联域名")
    
    print("-" * 50) 
    
    return (target, {"ip": ip, "domains": domains})

def export_results(results, filename):
    """导出Excel"""
    wb = openpyxl.Workbook()
    ws = wb.active
    ws.title = "反查结果"
    
    headers = ["原始输入", "IP地址", "关联域名"]
    for col, header in enumerate(headers, 1):
        ws.cell(row=1, column=col, value=header).fill = HEADER_FILL
    
    row_idx = 2
    for target, data in results.items():
        if not data:
            ws.append([target, None, "解析失败"])
            continue
            
        domains = data['domains']
        original_host = urlparse(target).hostname
        
        highlight = any(
            (data['ip'] in d) or 
            (original_host and original_host in d)
            for d in domains if isinstance(d, str)
        )
        
        row = [
            target,
            data['ip'],
            "\n".join(domains) if domains else "无结果"
        ]
        ws.append(row)
        
        if highlight:
            ws.cell(row=row_idx, column=3).fill = HIGHLIGHT_FILL
        
        row_idx += 1
    
    for col in ws.columns:
        max_len = max(len(str(cell.value)) for cell in col)
        ws.column_dimensions[get_column_letter(col[0].column)].width = max_len + 2
    
    wb.save(filename)
    print(f"\n✅ 结果已保存到: {filename}")

def main(argv):
    print_banner()
    targets = []
    output = "results.xlsx"

    try:
        opts, args = getopt.getopt(argv, "hu:l:o:", ["help", "url=", "list=", "output="])
    except getopt.GetoptError:
        print("参数错误!使用 -h 查看帮助")
        sys.exit(2)

    for opt, arg in opts:
        if opt == '-h':
            print(f"Usage: {sys.argv[0]} [-u URL/IP] [-l FILE] [-o FILE]")
            sys.exit()
        elif opt in ("-u", "--url"):
            targets.append(arg)
        elif opt in ("-l", "--list"):
            try:
                with open(arg, 'r') as f:
                    targets.extend(line.strip() for line in f if line.strip())
            except FileNotFoundError:
                print(f"文件不存在: {arg}")
                sys.exit(1)
        elif opt in ("-o", "--output"):
            output = arg

    if not targets:
        print("请指定目标(-u/-l)")
        sys.exit(1)

    print(f"\n🔍 开始处理 {len(targets)} 个目标...")
    
    results = {}
    with ThreadPoolExecutor(max_workers=5) as executor:
        futures = [executor.submit(process_target, t) for t in targets]
        for future in futures:
            target, data = future.result()
            results[target] = data
    
    export_results(results, output)

if __name__ == "__main__":
    main(sys.argv[1:])

0x06 注意事项:

国内接口有频率限制,建议:

        单次批量查询不超过50个目标

        每个查询间隔1-2秒

结果文件会自动高亮显示:

        黄色:包含原始域名的结果        

        绿色IP:表示该IP存在关联域名


http://www.kler.cn/a/586925.html

相关文章:

  • 删除有序数组中的重复项(26)
  • [网络] 网络基础概念--socket编程预备
  • Ubuntu 24 常用命令方法
  • 【Git】配置Git
  • 按钮权限的设计及实现
  • uniapp-x vue 特性
  • 在线 SQL 转 SQLAlchemy:一键生成 Python 数据模型
  • AcWing--870.约数个数
  • Windows环境下安装部署dzzoffice+onlyoffice的私有网盘和在线协同系统
  • Java中的I/O
  • 通过qemu仿真树莓派系统调试IoT固件和程序
  • 深度解析国产推理大模型DeepSeek:从入门到本地化部署!
  • C++Primer学习(7.1 定义抽象数据类型)
  • FPGA为何要尽量减少组合逻辑的使用
  • 人工智能与人的智能,改变一生的思维模型【8】逆向思维
  • 国家网络安全事件应急预案
  • DC-6靶机详解
  • Vue3 Pinia $subscribe localStorage的用法 Store的组合式写法
  • 基于变分推理与 Best‑of‑N 策略的元 Prompt 自动生成与优化框架
  • 《Python实战进阶》No24: PyAutoGUI 实现桌面自动化