·15 min·4 views

FreePBX Security After CVE-2025-64328: Monitor Your PBX

900+ FreePBX instances compromised by web shells. Detect compromise, harden your PBX, and set up ongoing security monitoring with Asterisk configs and SQL queries.

A
Astervis
Engineering & product team

900+ FreePBX instances are still running web shells right now. Yours might be one of them.

In February 2026, the Shadowserver Foundation confirmed that over 900 Sangoma FreePBX systems were actively compromised through CVE-2025-64328 - a post-authentication command injection vulnerability in the Endpoint Manager filestore module. The attacks started in December 2025. The patch existed since November. Most victims never applied it.

This isn't a theoretical risk. The threat group INJ3CTOR3 deployed a web shell called EncystPHP on vulnerable systems. Once inside, they execute arbitrary commands as the asterisk user, generate fraudulent outbound calls, and pivot deeper into victim networks.

My take: The real problem isn't the CVE itself - it's that most FreePBX admins have zero visibility into what's happening on their PBX. They can't detect a compromise because they never set up monitoring. This article fixes that.

I'll walk you through exactly how to detect if your FreePBX is already compromised, harden it against future attacks, and set up ongoing monitoring that catches anomalies before they become incidents.

What Happened: CVE-2025-64328 Explained

CVE-2025-64328 (CVSS 8.6) is a command injection vulnerability in FreePBX's Endpoint Manager module, specifically in the check_ssh_connect() function within the filestore component.

Here's what makes it dangerous:

  • Attack vector: An authenticated user sends an HTTP request with command=testconnection and driver=SSH. The user-supplied values for host, port, user, key, and path are passed to an exec() call without sanitization.
  • Impact: Arbitrary shell command execution as the asterisk user - the service account that controls your entire PBX.
  • Affected versions: FreePBX Endpoint Manager 17.0.2.36 and above, before 17.0.3.
  • Exploited by: INJ3CTOR3, a known threat group that targets VoIP infrastructure for toll fraud.

The injected web shell (EncystPHP) provides persistent remote access, command execution, and the ability to deploy additional web shells. Fortinet's FortiGuard Labs documented the campaign in January 2026.

Who's at Risk

If you run FreePBX with the Endpoint Manager module and your admin panel is accessible from the internet - even behind authentication - you're in the target zone.

The Shadowserver data shows compromised instances across 50+ countries:

  • 401 in the United States
  • 51 in Brazil
  • 43 in Canada
  • 40 in Germany
  • 36 in France

My take: The "post-authentication" label gives people false comfort. It means the attacker needs any valid admin credential - not that your system is safe if you're running auth. Default credentials, reused passwords, and phished accounts all qualify.

Step 1: Check If You're Already Compromised

Before you harden anything, check if you're already owned. Run these checks on your FreePBX server via SSH.

Scan for Web Shells

The EncystPHP web shell and similar payloads typically hide in the web root. Search for suspicious PHP files:

# Find PHP files modified in the last 120 days in web-accessible directories find /var/www/html -name "*.php" -mtime -120 -ls 2>/dev/null # Look for common web shell signatures grep -rl "eval(base64_decode" /var/www/html/ 2>/dev/null grep -rl "system(\$_" /var/www/html/ 2>/dev/null grep -rl "exec(\$_" /var/www/html/ 2>/dev/null grep -rl "passthru(" /var/www/html/ 2>/dev/null grep -rl "shell_exec(" /var/www/html/ 2>/dev/null | grep -v "/vendor/" # Check for files owned by asterisk user that shouldn't be there find /var/www/html -user asterisk -name "*.php" -newer /var/www/html/index.php -ls

If any of these return results, stop. Treat the system as compromised. Don't try to "clean" it - rebuild from known-good backups taken before December 2025.

Check for Unauthorized Cron Jobs

Web shells often install persistent cron jobs:

# Check asterisk user's crontab crontab -u asterisk -l # Check system cron directories ls -la /etc/cron.d/ ls -la /etc/cron.daily/ cat /var/spool/cron/asterisk 2>/dev/null # Look for recently modified cron entries find /etc/cron* -mtime -120 -ls 2>/dev/null

Check Active Network Connections

Compromised PBXes often maintain outbound connections to command-and-control servers:

# List all established connections from the asterisk process ss -tnp | grep asterisk # Look for unexpected outbound connections (not your SIP trunks) ss -tnp state established | grep -v ":5060" | grep -v ":5061" # Check for listeners on unusual ports ss -tlnp | grep -v -E ":(22|80|443|5060|5061|8080|8443|4569|10000)"

Audit CDR for Toll Fraud

The #1 goal of INJ3CTOR3 is toll fraud - generating expensive international calls through your PBX. Check your CDR:

-- Find calls to international premium-rate destinations (last 30 days) -- Run in Asterisk MySQL/MariaDB or your CDR database SELECT calldate, src, dst, duration, disposition, channel FROM cdr WHERE calldate > DATE_SUB(NOW(), INTERVAL 30 DAY) AND ( dst LIKE '011%' -- International (US dialing) OR dst LIKE '00%' -- International (EU dialing) OR dst LIKE '+%' -- E.164 international OR LENGTH(dst) > 12 -- Unusually long numbers ) AND duration > 0 ORDER BY calldate DESC LIMIT 100;
-- Find calls outside business hours (potential fraud indicator) SELECT DATE(calldate) as call_date, HOUR(calldate) as call_hour, COUNT(*) as call_count, SUM(duration) as total_seconds, COUNT(DISTINCT dst) as unique_destinations FROM cdr WHERE calldate > DATE_SUB(NOW(), INTERVAL 30 DAY) AND (HOUR(calldate) < 6 OR HOUR(calldate) > 22) AND disposition = 'ANSWERED' GROUP BY DATE(calldate), HOUR(calldate) HAVING call_count > 5 ORDER BY call_date DESC, call_hour;
-- Detect sudden spikes in outbound call volume SELECT DATE(calldate) as call_date, COUNT(*) as total_calls, COUNT(CASE WHEN dst LIKE '011%' OR dst LIKE '00%' OR dst LIKE '+%' THEN 1 END) as international_calls, SUM(duration) as total_duration_sec, ROUND(SUM(duration)/3600, 1) as total_hours FROM cdr WHERE calldate > DATE_SUB(NOW(), INTERVAL 60 DAY) GROUP BY DATE(calldate) ORDER BY call_date DESC;

If you see international calls you don't recognize - especially to destinations in Africa, Eastern Europe, or the Caribbean - your system has likely been used for toll fraud.

My take: Most FreePBX admins check CDR once a month when the SIP trunk bill arrives. By then, a compromised system has generated thousands of dollars in fraudulent calls. Real-time CDR monitoring isn't optional - it's the difference between a $200 incident and a $20,000 phone bill.

Step 2: Patch and Harden Your FreePBX

If your system is clean (or you've rebuilt from backup), here's how to lock it down.

Apply the Patch

Update the Endpoint Manager module to version 17.0.3 or later:

# Update FreePBX modules fwconsole ma upgradeall fwconsole reload # Verify the Endpoint Manager version fwconsole ma list | grep endpoint

If you can't update immediately, disable the vulnerable function by restricting access to the filestore component.

Lock Down the Admin Panel

The CVE requires authentication, but that's a weak barrier if your admin panel is internet-facing.

Restrict access by IP with iptables:

# Allow admin panel only from your management network iptables -A INPUT -p tcp --dport 443 -s 10.0.0.0/8 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -s 192.168.0.0/16 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j DROP # Allow admin panel from a specific public IP (your office) iptables -A INPUT -p tcp --dport 443 -s YOUR.OFFICE.IP.HERE -j ACCEPT

Or use the FreePBX Responsive Firewall:

Admin -> Connectivity -> Firewall -> Interfaces - Mark your LAN interface as "Trusted" - Mark WAN/Internet as "Internet" (not Trusted) - Enable "Responsive Firewall" for SIP only - NEVER mark the internet interface as Trusted

Disable Unnecessary Modules

Every enabled module is an attack surface:

# List all installed modules fwconsole ma list # Disable modules you don't use fwconsole ma disable endpointman # If you don't use Endpoint Manager fwconsole ma disable restapi # If you don't use REST API fwconsole ma disable webrtc # If you don't use WebRTC fwconsole reload

Harden SSH Access

The exploit chain often starts with SSH compromise. Harden it:

# /etc/ssh/sshd_config - add or modify: Port 2222 # Change from default 22 PermitRootLogin no # Never allow root SSH PasswordAuthentication no # Key-based auth only AllowUsers your-admin-user # Whitelist specific users MaxAuthTries 3 LoginGraceTime 30
# Restart SSH after changes systemctl restart sshd

Tired of guessing what's happening in your queues?

Astervis gives you 30+ real-time charts, operator KPIs, and CRM integration for your Asterisk PBX. Self-hosted. Install in 5 minutes. From $119/mo flat unlimited operators.

Try Free

Configure Fail2Ban for FreePBX

Fail2Ban watches your logs and blocks IPs after failed auth attempts:

# /etc/fail2ban/jail.local [freepbx] enabled = true filter = freepbx action = iptables-allports[name=FreePBX, protocol=all] logpath = /var/log/asterisk/freepbx_security.log maxretry = 3 bantime = 86400 findtime = 600 [asterisk] enabled = true filter = asterisk action = iptables-allports[name=Asterisk, protocol=all] logpath = /var/log/asterisk/messages maxretry = 3 bantime = 86400 findtime = 600
# /etc/fail2ban/filter.d/freepbx.conf [Definition] failregex = \[SECURITY\](.*) from <HOST> ignoreregex =
# Restart Fail2Ban systemctl restart fail2ban # Check current bans fail2ban-client status freepbx

Step 3: Set Up Ongoing Security Monitoring

Patching and hardening are one-time actions. Monitoring is what keeps you safe long-term.

Monitor Asterisk Logs for Suspicious Activity

Your Asterisk logs contain signals that most admins never look at.

Key log files to watch:

Log FileWhat It Contains
/var/log/asterisk/freepbx_security.logAuthentication failures, blocked IPs
/var/log/asterisk/fullAll Asterisk events, including channel activity
/var/log/asterisk/messagesSIP registration attempts, errors
/var/log/httpd/access_logWeb panel access attempts
/var/log/secureSSH login attempts

Automated log monitoring script:

#!/bin/bash # /usr/local/bin/pbx-security-check.sh # Run via cron every hour: 0 * * * * /usr/local/bin/pbx-security-check.sh ALERT_EMAIL="admin@yourcompany.com" LOG="/var/log/asterisk/freepbx_security.log" # Count failed auth attempts in the last hour FAILURES=$(grep "$(date -d '1 hour ago' '+%Y-%m-%d %H')" "$LOG" 2>/dev/null | grep -c "SECURITY") if [ "$FAILURES" -gt 20 ]; then echo "ALERT: $FAILURES auth failures in the last hour on $(hostname)" | \ mail -s "FreePBX Security Alert" "$ALERT_EMAIL" fi # Check for new PHP files in web root NEW_PHP=$(find /var/www/html -name "*.php" -mmin -60 -ls 2>/dev/null) if [ -n "$NEW_PHP" ]; then echo "ALERT: New PHP files detected in web root:\n$NEW_PHP" | \ mail -s "FreePBX: Suspicious File Alert" "$ALERT_EMAIL" fi # Check for unexpected outbound connections SUSPICIOUS=$(ss -tnp state established | grep asterisk | grep -v -E ":(5060|5061|3306|6379)" | head -5) if [ -n "$SUSPICIOUS" ]; then echo "ALERT: Unexpected outbound connections from asterisk:\n$SUSPICIOUS" | \ mail -s "FreePBX: Suspicious Connection Alert" "$ALERT_EMAIL" fi

Set Up CDR-Based Anomaly Detection

CDR analysis catches toll fraud faster than anything else. Here's a query you can run daily:

-- Daily anomaly detection: compare today's pattern to the 30-day average SELECT 'TODAY' as period, COUNT(*) as total_calls, COUNT(CASE WHEN dst LIKE '011%' OR dst LIKE '00%' OR dst LIKE '+%' THEN 1 END) as international_calls, ROUND(AVG(duration), 0) as avg_duration, COUNT(DISTINCT src) as unique_sources, MAX(duration) as longest_call FROM cdr WHERE calldate >= CURDATE() UNION ALL SELECT '30D_AVG' as period, ROUND(COUNT(*) / 30, 0) as total_calls, ROUND(COUNT(CASE WHEN dst LIKE '011%' OR dst LIKE '00%' OR dst LIKE '+%' THEN 1 END) / 30, 0) as international_calls, ROUND(AVG(duration), 0) as avg_duration, ROUND(COUNT(DISTINCT src) / 30, 0) as unique_sources, MAX(duration) as longest_call FROM cdr WHERE calldate >= DATE_SUB(CURDATE(), INTERVAL 30 DAY) AND calldate < CURDATE();

If today's international call count is more than 3x the 30-day daily average, investigate immediately.

Monitor SIP Registration Attempts

Brute-force SIP registration is often the precursor to a full compromise:

-- Track failed SIP registrations per source IP (last 24 hours) -- Requires Asterisk security event logging enabled SELECT SUBSTRING_INDEX( SUBSTRING_INDEX(channel, '/', 2), '/', -1 ) as source, COUNT(*) as attempts, MIN(calldate) as first_seen, MAX(calldate) as last_seen FROM cdr WHERE calldate >= DATE_SUB(NOW(), INTERVAL 24 HOUR) AND disposition = 'FAILED' GROUP BY source HAVING attempts > 10 ORDER BY attempts DESC;

Asterisk Configuration for Security Logging

Enable detailed security logging in your Asterisk config:

; /etc/asterisk/logger.conf [logfiles] security => security full => notice,warning,error,verbose(3) messages => notice,warning,error [general] dateformat=%F %T.%3q
; /etc/asterisk/sip.conf (or pjsip.conf) [general] alwaysauthreject=yes ; Don't reveal valid extensions allowguest=no ; Block unauthenticated calls
; /etc/asterisk/extensions.conf ; Block international dialing by default - whitelist specific trunks [from-internal] ; Only allow international calls through approved trunk exten => _011.,1,NoOp(International call attempt: ${CALLERID(num)} -> ${EXTEN}) exten => _011.,n,Set(CDR(userfield)=INTL_ATTEMPT) exten => _011.,n,GotoIf($["${CHANNEL(peerip)}" = "10.0.0.100"]?allow:deny) exten => _011.,n(deny),Playback(ss-noservice) exten => _011.,n,Hangup() exten => _011.,n(allow),Dial(SIP/trunk/${EXTEN})

Real-Time Monitoring: What to Track

Here are the metrics that matter for PBX security monitoring:

MetricNormal RangeAlert ThresholdWhat It Means
Failed SIP registrations/hour< 10> 50Brute-force attempt in progress
International calls/dayYour baseline> 3x baselinePossible toll fraud
After-hours call volume< 5> 20Unauthorized call generation
Active channels (off-hours)0-2> 10Compromised system making calls
New PHP files in web root0> 0Web shell deployment
Admin panel login failures/hour< 5> 15Panel brute-force attempt
Unique outbound destinations/hour< 20> 100Call generation bot active

My take: Most security articles tell you to "enable logging." That's useless without someone (or something) actually reading the logs. Automated monitoring with threshold-based alerts is the only approach that works. You're not going to SSH into your PBX at 3 AM to check logs. But an alert at 3 AM about 200 international calls will wake you up.

Step 4: Build a Security Dashboard

Individual checks are useful, but a dashboard gives you a single view of PBX health and security.

What Your Dashboard Should Show

Real-time panel:

  • Active channels count (with after-hours highlighting)
  • Failed auth attempts (last hour, trending)
  • International/premium-rate call volume
  • Unusual destination countries

Daily summary:

  • Total calls vs. 30-day average
  • International call ratio
  • Top destinations (flag new countries)
  • Failed SIP registrations by source IP
  • Admin panel access log

Weekly audit:

  • Module versions vs. latest available
  • File integrity check (new/modified PHP files)
  • Fail2Ban block statistics
  • CDR anomaly trend

Using Astervis for PBX Security Monitoring

You can build all of this manually with cron scripts, custom SQL queries, and a Grafana instance. That's about 40 hours of setup, ongoing maintenance, and no mobile access.

Or you can install Astervis in 5 minutes and get:

  • Real-time CDR analytics - see every call as it happens, with automatic anomaly detection
  • 30+ pre-built charts - including call volume trends, destination analysis, and after-hours activity
  • Operator tracking - know which extensions are generating unexpected traffic
  • Trunk monitoring - detect SIP trunk abuse before the bill arrives
  • Heatmaps - visualize call patterns and spot anomalies instantly

Astervis connects directly to your Asterisk CDR database. It's self-hosted (your data stays on your server), installs with one command, and gives you the monitoring visibility that could have prevented every compromised instance in the CVE-2025-64328 campaign.

-> Start your 14-day free trial

The Bigger Picture: Why PBX Security Monitoring Matters

CVE-2025-64328 won't be the last FreePBX vulnerability. Before it, there was CVE-2025-57819 (CVSS 10.0) - an unauthenticated admin access flaw exploited since August 2025. Before that, similar vulnerabilities in Elastix and older FreePBX versions.

The pattern is consistent:

  1. Vulnerability disclosed
  2. Patch released
  3. Most admins don't apply the patch for weeks or months
  4. Threat groups exploit the window
  5. Admins discover the breach only when the phone bill arrives

The only thing that breaks this cycle is monitoring. If you have real-time visibility into your PBX activity, you detect anomalies within hours - not months. You see the spike in failed auth attempts before the attacker finds valid credentials. You see the first fraudulent international call before it becomes a thousand.

Security Checklist: FreePBX Hardening After CVE-2025-64328

Use this as your action plan:

  • Immediate: Check for web shells in /var/www/html
  • Immediate: Audit CDR for international calls you don't recognize
  • Immediate: Check for unauthorized cron jobs under the asterisk user
  • Today: Update Endpoint Manager to version 17.0.3+
  • Today: Restrict admin panel access to trusted IPs only
  • Today: Change all admin passwords (FreePBX, SSH, MySQL)
  • This week: Configure Fail2Ban for FreePBX and Asterisk
  • This week: Disable unused FreePBX modules
  • This week: Set up CDR anomaly alerts (script or monitoring tool)
  • This week: Enable Asterisk security logging
  • This week: Block international dialing by default in dialplan
  • Ongoing: Monitor CDR daily for volume and destination anomalies
  • Ongoing: Review Fail2Ban blocks weekly
  • Ongoing: Check for FreePBX module updates monthly
  • Ongoing: Run file integrity checks on the web root

Conclusion

900+ compromised FreePBX instances is not a statistic - it's 900+ organizations that lost control of their phone system. Some are still compromised right now, running web shells they don't know about, generating calls they'll pay for.

The fix isn't just patching CVE-2025-64328. It's changing the fundamental approach from "set up the PBX and forget it" to "monitor the PBX continuously." Every other piece of infrastructure in your network has monitoring - servers, networks, applications. Your PBX handles your company's phone calls. It deserves the same visibility.

Start with the checklist above. Check for compromise, patch, harden, and then set up monitoring that runs 24/7. Your phone bill - and your security team - will thank you.


Astervis provides real-time call center analytics for Asterisk-based PBX systems. Self-hosted, one-command install, 30+ charts, and the monitoring visibility your PBX needs. Try it free for 14 days - no credit card required.

Stop guessing. Start monitoring.

See your Asterisk call center's real performance — queue wait times, agent activity, trunk usage, and 30+ charts. Self-hosted on your server. Install in 5 minutes. No credit card required.

From $119/mo flat. Unlimited operators. 14-day free trial.

Share this article