ReDoc API文档界面暴露漏洞检测工具

本文介绍了一个Metasploit辅助模块,用于检测公开暴露的ReDoc API文档页面。该模块通过安全的只读GET请求和HTML标记识别ReDoc实例,包含路径配置选项和响应分析逻辑,适用于网络安全扫描和漏洞评估。

漏洞利用:ReDoc API文档界面暴露检测

2025-10-24 | CVSS 7.0

模块概述

此模块需要Metasploit框架:https://metasploit.com/download 当前源代码:https://github.com/rapid7/metasploit-framework

类定义

1
2
3
class MetasploitModule < Msf::Auxiliary
  include Msf::Auxiliary::Scanner
  include Msf::Exploit::Remote::HttpClient

初始化配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def initialize(info = {})
  super(
    update_info(
      info,
      'Name' => 'ReDoc API Docs UI Exposed',
      'Description' => %q{
        检测公开暴露的ReDoc API文档页面。
        该模块执行安全的只读GET请求,并基于HTML标记报告可能的ReDoc实例。
      },
      'Author' => [
        'Hamza Sahin (@hamzasahin61)'
      ],
      'License' => MSF_LICENSE,
      'Notes' => {
        'Stability' => [CRASH_SAFE],  # 仅GET请求;不应崩溃或中断目标服务
        'Reliability' => [],          # 不建立会话;留空是可接受的
        'SideEffects' => [IOC_IN_LOGS] # 请求可能被目标Web服务器记录
      },
      'DefaultOptions' => {
        'RPORT' => 80
      }
    )
  )

注册选项

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
register_options(
  [
    # 标记为必需并在此处显示内置默认值
    OptString.new('REDOC_PATHS', [
      true,
      '要探测的路径的逗号分隔列表',
      '/redoc,/redoc/,/docs,/api/docs,/openapi'
    ])
  ]
)

ReDoc检测方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 如果响应看起来像ReDoc页面,则返回true
def redoc_like?(res)
  # 仅接受2xx或403(排除重定向;许多3xx缺少要分析的HTML)
  return false unless res && (res.code.between?(200, 299) || res.code == 403)

  # 优先进行DOM检查
  doc = res.get_html_document
  if doc && (doc.at_css('redoc, redoc-, #redoc') ||
             doc.css('script[src*="redoc"]').any? ||
             doc.css('script[src*="redoc.standalone"]').any?)
    return true
  end

  # 回退到body/title启发式方法
  title = res.get_html_title.to_s
  body = res.body.to_s
  return true if title =~ /redoc/i || body =~ /<redoc-?/i || body =~ /redoc(\.standalone)?\.js/i

  false
end

路径检查方法

1
2
3
def check_path(path)
  redoc_like?(send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(path) }))
end

主机扫描方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def run_host(ip)
  vprint_status("#{ip} - 正在扫描ReDoc")

  # REDOC_PATHS是必需的并有默认值;始终直接使用它
  paths = datastore['REDOC_PATHS'].split(',').map(&:strip)

  hit = paths.find { |p| check_path(p) }
  if hit
    print_good("#{ip} - ReDoc可能暴露在 #{hit}")
    report_service(host: ip, port: rport, proto: 'tcp', name: 'http')
  else
    vprint_status("#{ip} - 未找到ReDoc")
  end
end
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计