Skip to main content
rfxn
//
maldetmalwarewordpresssupply-chainbuddybossgravity-forms

WordPress Supply Chain Attacks: BuddyBoss, Gravity Forms, and the Trust Problem

Ryan MacDonald12 min read

Three separate WordPress plugin vendors had their update or download infrastructure compromised between June and March 2026, turning legitimate software updates into malware delivery vehicles. BuddyBoss, Gravity Forms, and Groundhogg each fell victim to the same class of attack: compromise the vendor's distribution channel rather than the sites themselves, then let the auto-update mechanism do the rest.

Combined, these three incidents exposed over one million WordPress installations to backdoored plugin updates delivered with a valid vendor signature over an authenticated channel. The trust that makes auto-updates safe is exactly what makes this attack class so effective.

This post covers the technical details of each incident, why conventional defenses fail against supply chain delivery, the ten Linux Malware Detect signatures we published for detection, and a step-by-step remediation checklist for affected installations.

Scale of exposure

Gravity Forms alone reports over one million active installs. BuddyBoss counts 27,000+ servers in its ecosystem. Groundhogg saw five confirmed downloads before the malicious file was removed. The Patchstack 2025 report recorded 11,334 new WordPress vulnerabilities last year (a 42% year-over-year increase) and a median time of five hours from disclosure to mass exploitation.

1. COMPROMISEDISTRIBUTION2. INJECTCORE LOADER3. HARVESTCREDENTIALS4. EXFILTRATEVIA C2GroundhoggJun 27, 20255 downloadsPackage downloadcompromised buildcaught same daylicense.phpinjected file(not in clean install)DB credentialsadmin passwordsgroundhogg[.]org(legit: groundhogg.io)SUSPENDEDGravity FormsJul 9-10, 20251M+ installsDownload portalZIP packages replacedmanual installs onlycommon.phpcore shared library+ 3 dropped filesSite metadataadmin email, pluginsserver path, WP vergravityapi[.]orggravityapi[.]io(legit: gravityapi.com)BuddyBossMar 17, 202627k+ at riskUpdate servertrojanized packagesplugin + themebp-loader.phpfunctions.phpbootstrap + themeDB + Stripe keysadmin passwordsuser table dumpwp_remote_post()+ reverse shell309 sites confirmedThree vendors. Nine months. One playbook.

The Pattern#

Despite three different vendors, three different timeframes, and three different threat actors, the attack chain was nearly identical in each case. Understanding the shared playbook is the first step toward building defenses that hold across future incidents.

  1. Compromise the distribution layer, not the code repository. In all three cases the GitHub repository remained clean. The attacker targeted the vendor's update server, download portal, or build pipeline: the infrastructure between the source repository and the end site.
  2. Inject into a core loader file that runs on every page load. Targets were not obscure utility files. BuddyBoss: bp-loader.php. Gravity Forms: common.php. Groundhogg: includes/license.php. All are required includes loaded early in the WordPress bootstrap.
  3. Add credential harvesting and remote shell capability. Each backdoor combined two objectives: exfiltrate high-value credentials (database passwords, Stripe keys, admin passwords) and establish persistent remote code execution via reverse shell or eval-based command handler.
  4. Exfiltrate via typosquatted or lookalike C2 domains. C2 infrastructure was registered days before the attack and designed to blend into traffic monitoring. Gravity Forms: gravityapi[.]org and gravityapi[.]io (legitimate domain is gravityapi.com). Groundhogg: groundhogg[.]org (legitimate domain is groundhogg.io).
  5. Let the trust relationship deliver the payload automatically. Sites that had auto-updates enabled received the backdoored plugin without administrator interaction. The update was signed and delivered over HTTPS from the legitimate vendor's infrastructure.

This playbook is not novel. It mirrors the SolarWinds pattern at the WordPress ecosystem scale. What makes it particularly dangerous here is the density of the target space: tens of thousands of independently operated WordPress sites, most running automated updates, all trusting the same handful of plugin vendors.

BuddyBoss, March 17, 2026#

On March 17, 2026, threat actors compromised BuddyBoss's update server and pushed trojanized versions of both the BuddyBoss Platform plugin and the BuddyBoss Theme. The compromise was discovered on March 19 by Cybernews researchers who located an exposed C2 server containing the stolen data. By that point 309 sites had already been confirmed compromised, with 27,000+ servers in the broader BuddyBoss ecosystem considered at risk.

Post-incident analysis attributed the attack to a French-speaking threat actor who used an AI assistant (specifically Claude) to help craft the attack chain, making it an early documented case of AI-assisted plugin supply chain compromise.

Compromised Files

Two files were replaced in the trojanized distribution packages. Both are first-loaded bootstrap files that run on every WordPress page request:

FilePackageSHA256
bp-loader.phpBuddyBoss Platform 2.20.3ddda12b545a7b817883641421cf6a213f4c5100effa40cdb55018efce11bbe42
functions.phpBuddyBoss Theme 2.19.25027a0e77eca13a5cc120d3e37262c4073452569ad341cd1558051b5a91ce144

The clean version of bp-loader.php is available in the BuddyBoss GitHub repository. If your installed file's hash matches either value above, treat the installation as compromised.

Backdoor Capabilities

The malicious bp-loader.php contained three functional components layered on top of the legitimate plugin bootstrap code:

Credential harvesting. Extracted WordPress admin passwords, database credentials (via DB_PASSWORD and DB_USER), and Stripe secret keys (matching sk_live_ prefix) from the WordPress configuration and active plugin options
Database dump. Ran queries against the WordPress database to extract user tables, including hashed passwords for all registered accounts, and serialized the results for exfiltration
Reverse shell. Established outbound TCP connections via fsockopen() and stream_socket_client() for persistent interactive access. The reverse shell bypasses inbound firewall rules by initiating the connection from the victim server to the attacker

All exfiltration used wp_remote_post() or direct curl_exec() calls, blending into normal outbound HTTP traffic generated by legitimate WordPress plugins.

Gravity Forms, July 9–10, 2025#

On July 9–10, 2025, Gravity Forms' download infrastructure was compromised and manual installer ZIP packages were replaced with backdoored versions. The affected versions were 2.9.11.1 and 2.9.12. Gravity Forms reports over one million active installs, making this the highest-exposure incident of the three. The attack was documented in detail by Patchstack.

Manual installer scope

The compromise affected manually downloaded ZIP packages only. Sites using WordPress's built-in plugin updater (which pulls from WordPress.org) were not affected. Gravity Forms is a premium plugin distributed outside the WordPress.org repository. Any site that manually downloaded and installed versions 2.9.11.1 or 2.9.12 during the July 9–10 window should treat the installation as compromised.

Backdoor Mechanism

The attacker modified gravityforms/common.php (the plugin's core shared library, loaded on every page) and deployed three additional files that served as the command handler and data staging area:

FileRole
gravityforms/common.phpModified: bootstrap hook for beaconing and C2 check-in
wp-includes/bookmark-canonical.phpDropped: persistent backdoor disguised as core WP file
wp-includes/block-caching.phpDropped: secondary payload, also disguised as core file
notification.phpDropped: staging file for collected site metadata

The C2 communication used a function named update_entry_detail() (a name chosen to blend with Gravity Forms' legitimate entry API) which collected site metadata (WordPress version, installed plugins, admin email, server path) and POSTed it to the C2 domain. The C2 response delivered a base64-encoded PHP backdoor that was written to disk and included into the runtime.

C2 Infrastructure

The attacker registered two domains on July 8, 2025, one day before the attack, designed to be indistinguishable from legitimate Gravity Forms API traffic in access logs:

C2 DomainLegitimate DomainIP
gravityapi[.]orggravityapi.com185.193.89.19
gravityapi[.]iogravityapi.com193.160.101.6

Both domains were registered with privacy protection and hosted on bulletproof infrastructure. Neither appeared in any blocklist at the time of the attack, because they were freshly registered and had no prior reputation signal.

Groundhogg, June 27, 2025#

On June 27, 2025, Groundhogg (a WordPress CRM and marketing automation plugin) discovered a malicious file had been injected into their distribution package. The vendor disclosed the incident directly on their press page, describing it as a targeted supply chain attack.

The malicious file was includes/license.php, which does not exist in the legitimate plugin. Its presence in the package was the primary indicator of compromise. The C2 domain was groundhogg[.]org (the legitimate domain is groundhogg.io), which was suspended shortly after discovery.

Limited confirmed exposure

Groundhogg confirmed five downloads of the compromised package and two confirmed installations before the file was removed. The small number reflects either a narrow distribution window or early detection. Regardless, any installation that received a Groundhogg update on June 27 should be audited for the presence of includes/license.php.

The Groundhogg incident is notable for the speed and transparency of the vendor response. Public disclosure occurred the same day as discovery, with specific indicators and remediation steps. Compare this with the industry norm of delayed or vague disclosures, and it represents the right model for handling supply chain incidents.

Why This Bypasses Everything#

Supply chain attacks on plugin distribution infrastructure circumvent nearly every layer of a conventional WordPress security stack. This is not a failure of implementation; it is a structural consequence of how the WordPress update trust model works.

The Trust Model

WordPress establishes trust transitively: a site administrator trusts a plugin vendor, and that vendor's update server delivers signed packages over HTTPS. When the attacker controls the update server, they inherit that trust. Every security control that operates below the trust boundary (file integrity monitoring, WAF rules, IDS signatures) is blind to the initial compromise because the payload arrived over a legitimate, authenticated channel.

DefenseWhy It Fails Against Supply Chain
File integrity monitoring (pre-update baseline)Update resets the baseline; the backdoor is the new "clean" state
WAF / ModSecurityThe backdoor arrives as a ZIP file over the plugin update API, not an HTTP exploit. WAF sees a normal update request
TLS certificate validationThe package is served from the real vendor domain with a valid certificate. HTTPS provides transport security, not content integrity
Network egress filteringExfiltration uses wp_remote_post() (the same mechanism WordPress uses for legitimate API calls). Port 443 to a plausible-looking domain
Static malware scanners (signature-based)The backdoor is novel at time of delivery; no prior signature exists. Detection requires behavioral or anomaly analysis, or post-hoc signatures from incident analysis

What Actually Detects It

Given the above, detection options fall into three categories:

Post-hoc hash matching. Once the compromised file hashes are published (as they were in all three incidents), scanners with hash databases detect them on next run. This is reactive but effective for cleanup
Behavioral compound signatures. Rules that match the combination of plugin-specific strings AND attacker capability markers (reverse shell functions, credential extraction patterns) in the same file. These catch variants beyond the exact known hashes
Out-of-band file verification. Compare installed plugin files against the vendor's published hashes or the upstream GitHub repository. Any deviation in a core loader file is an immediate compromise indicator

The Patchstack 2026 report noted that premium plugins (paid, outside WordPress.org) accounted for 33 zero-day vulnerabilities in 2025, three times the rate of free plugins. The distribution infrastructure for premium plugins is also entirely outside the WordPress.org review process. These two factors together make premium plugin vendors the highest-risk point in the WordPress supply chain.

Linux Malware Detect Signatures#

We have published ten new signatures across three detection formats in Linux Malware Detect (LMD). Four hex pattern signatures target BuddyBoss-specific payload markers. Four compound signatures combine plugin context with attacker capability markers, including two generic patterns that will match future supply chain attacks against any WordPress plugin. Two SHA256 exact-match signatures target the known compromised BuddyBoss files.

Hex Signatures (LMD 1.6+)

These four signatures use byte-pattern matching against the BuddyBoss bootstrap header combined with specific attacker code patterns. They require LMD 1.6 or later for hex matching support.

Signature NameDetection Pattern
php.supply.buddyboss.b64BuddyBoss bootstrap header + BP_PLUGIN_DIR + base64_decode(
php.supply.buddyboss.evalBuddyBoss bootstrap header + BP_PLUGIN_DIR + eval(
php.supply.buddyboss.revshellBuddyBoss bootstrap header + BP_PLUGIN_DIR + fsockopen(
php.supply.buddyboss.streamsockBuddyBoss bootstrap header + BP_PLUGIN_DIR + stream_socket_client(

Compound Signatures (LMD 2.x)

Compound signatures use boolean AND/OR logic across multiple pattern clauses. These are more expressive than hex patterns and can encode semantic context. For example, "a file that contains BuddyBoss plugin markers AND any of several execution sinks." The two generic signatures at the bottom are designed to catch future supply chain attacks against any WordPress plugin, not just BuddyBoss. For a deep dive on the detection language itself, see Compound Signatures: Building a Boolean Detection Language in Bash.

Signature NameScopeLogic
php.supply.buddyboss.backdoorBuddyBossBuddyBoss header AND BP_SOURCE_SUBDIRECTORY AND any of 7 execution sinks (eval, system, exec, passthru, shell_exec, fsockopen, proc_open)
php.supply.buddyboss.credtheftBuddyBossBuddyBoss header AND (DB_PASSWORD OR DB_USER OR sk_live_) AND (wp_remote_post OR file_get_contents OR curl_exec)
php.supply.wp-plugin.revshellGeneric WPAny WP plugin header AND (fsockopen OR stream_socket_client OR proc_open) AND (fwrite OR fread)
php.supply.wp-plugin.dbcred-exfilGeneric WPAny WP plugin header AND DB_PASSWORD AND (wp_remote_post OR curl_exec)

SHA256 Exact-Match Signatures

Two exact-hash signatures match the known-bad BuddyBoss files by their SHA256 digest. These provide zero false positives and match regardless of content obfuscation, but only detect the specific known variants.

Signature NameSHA256
php.supply.buddyboss.platformddda12b545a7b817883641421cf6a213f4c5100effa40cdb55018efce11bbe42
php.supply.buddyboss.theme5027a0e77eca13a5cc120d3e37262c4073452569ad341cd1558051b5a91ce144

LMD users can receive all ten signatures by running:

bash
maldet --update-sigs
maldet --scan-all /var/www/html/wp-content/plugins/

For a more targeted check against the known BuddyBoss compromised files specifically:

bash
maldet --update-sigs
# Scan the BuddyBoss platform plugin loader
maldet --scan-all /var/www/html/wp-content/plugins/buddyboss-platform/bp-loader.php
# Scan the BuddyBoss theme
maldet --scan-all /var/www/html/wp-content/themes/buddyboss-theme/functions.php

Remediation#

If you are running BuddyBoss Platform 2.20.3, BuddyBoss Theme 2.19.2, Gravity Forms 2.9.11.1 or 2.9.12 installed during July 9–10 2025, or any Groundhogg version received on June 27 2025, treat the installation as compromised and follow these steps in order.

Step 1: Verify Compromise

Hash the suspected files and compare against the known-bad values:

bash
# Check BuddyBoss Platform loader
sha256sum wp-content/plugins/buddyboss-platform/bp-loader.php
# Compromised: ddda12b545a7b817883641421cf6a213f4c5100effa40cdb55018efce11bbe42

# Check BuddyBoss Theme
sha256sum wp-content/themes/buddyboss-theme/functions.php
# Compromised: 5027a0e77eca13a5cc120d3e37262c4073452569ad341cd1558051b5a91ce144

# Check for Gravity Forms dropped files (should not exist in clean install)
ls -la wp-includes/bookmark-canonical.php
ls -la wp-includes/block-caching.php
ls -la notification.php

# Check for Groundhogg backdoor file (should not exist in clean install)
ls -la wp-content/plugins/groundhogg/includes/license.php

Step 2: Take the Site Offline

Enable maintenance mode before proceeding. While the backdoor is active, every page load is a potential credential exfiltration event.
Block outbound connections to the C2 domains and IPs listed in the IOCs section at your firewall or hosts file.
Do not simply deactivate the plugin. The backdoor may have already dropped additional files outside the plugin directory.

Step 3: Restore From Backup

Restore the affected plugin from a backup predating the compromise window: before March 17, 2026 for BuddyBoss; before July 9, 2025 for Gravity Forms; before June 27, 2025 for Groundhogg.
Do not reinstall from the vendor update server until the vendor has confirmed clean packages. Check the vendor's security advisory for the all-clear.
After restoring, re-verify the hash of the restored loader file against the clean value from the vendor's GitHub repository.

Step 4: Rotate All Credentials

Assume all credentials stored on or accessible from the server have been exfiltrated. Rotate them all, in this order:

Stripe secret keys (sk_live_*): revoke immediately in the Stripe dashboard before anything else. Stolen payment keys are the highest-urgency item.
WordPress admin account passwords: force reset for all administrator accounts via the database if the admin panel is not accessible.
Database password in wp-config.php: update DB_PASSWORD and restart the database server to invalidate any open sessions.
API tokens for any third-party service configured in WordPress options (payment gateways, email providers, CDN APIs).
Server SSH keys if the reverse shell had interactive access. Audit ~/.ssh/authorized_keys for new entries.

Step 5: Audit for Persistence

A compromised installation may have additional backdoors planted beyond the initial plugin files:

bash
# Audit WordPress admin users for unauthorized accounts
wp user list --role=administrator --fields=user_login,user_email,user_registered

# Scan the full installation with updated LMD signatures
maldet --update-sigs
maldet --scan-all /var/www/html/

# Check for recently modified PHP files outside plugin/theme directories
find /var/www/html/wp-includes/ -name '*.php' -newer /var/www/html/wp-login.php -ls
find /var/www/html/wp-admin/ -name '*.php' -newer /var/www/html/wp-login.php -ls

# Review server access logs for reverse shell activity
grep -E 'fsockopen|stream_socket|proc_open' /var/log/apache2/access.log
grep -E 'CONNECT|:443|:4444|:1337' /var/log/apache2/access.log

Indicators of Compromise#

BuddyBoss File Hashes

text
# Compromised BuddyBoss Platform 2.20.3
ddda12b545a7b817883641421cf6a213f4c5100effa40cdb55018efce11bbe42  bp-loader.php

# Compromised BuddyBoss Theme 2.19.2
5027a0e77eca13a5cc120d3e37262c4073452569ad341cd1558051b5a91ce144  functions.php

Gravity Forms C2 Domains and IPs

text
# Typosquatted C2 domains (legitimate domain: gravityapi.com)
gravityapi[.]org
gravityapi[.]io

# C2 IP addresses
185.193.89.19
193.160.101.6

# Dropped files (presence indicates compromise, not part of clean install)
wp-includes/bookmark-canonical.php
wp-includes/block-caching.php
notification.php

Groundhogg C2 Domain and Backdoor File

text
# Typosquatted C2 domain (legitimate domain: groundhogg.io)
groundhogg[.]org  [suspended]

# Backdoor file (presence indicates compromise, not part of clean install)
wp-content/plugins/groundhogg/includes/license.php

Affected Version Windows

PluginCompromised Version(s)Compromise Window
BuddyBoss Platform2.20.3March 17–19, 2026
BuddyBoss Theme2.19.2March 17–19, 2026
Gravity Forms2.9.11.1, 2.9.12July 9–10, 2025 (manual download only)
GroundhoggAffected build (June 27)June 27, 2025

MITRE ATT&CK Mapping#

The techniques observed across these three supply chain incidents map to the following MITRE ATT&CK entries:

TechniqueIDContext
Supply Chain Compromise: Compromise Software Supply ChainT1195.002Attacker compromised vendor update/download infrastructure to distribute backdoored plugin packages
Command and Scripting Interpreter: Unix ShellT1059.004Reverse shell via fsockopen() and stream_socket_client() for interactive command execution on compromised hosts
Exfiltration Over C2 ChannelT1041Database credentials, Stripe keys, and user tables exfiltrated via wp_remote_post() to typosquatted C2 domains
Valid AccountsT1078Harvested WordPress admin credentials and database passwords enable persistent access beyond the initial backdoor

Conclusion#

Three supply chain attacks against WordPress plugin distribution infrastructure in under a year is not coincidence. It reflects a deliberate attacker shift toward the distribution layer, where a single compromise yields access to thousands of sites simultaneously, and where conventional defenses are structurally blind.

The Patchstack statistic is worth restating: 11,334 new WordPress vulnerabilities in 2025, with a median time of five hours from disclosure to mass exploitation. The ecosystem is under sustained, systematic pressure. Supply chain attacks are the logical escalation: instead of exploiting individual site vulnerabilities one at a time, attackers compromise the trusted update infrastructure that serves all sites at once.

For defenders, the takeaways are practical:

Immediate

Run maldet --update-sigs && maldet --scan-all /var/www/ to scan with the ten new supply chain signatures
Verify BuddyBoss bp-loader.php and functions.php hashes if you run either plugin. The SHA256 values are in the IOCs section above
Check for the presence of Gravity Forms dropped files: bookmark-canonical.php and block-caching.php in wp-includes/ are never part of a clean WordPress install

Harden

Subscribe to security advisories for every premium plugin you run. Vendor disclosure is often the only signal available before a scanner has signatures
For critical premium plugins, pin to a known-good version and upgrade manually after verifying the package hash against the vendor's published value or their GitHub release
Isolate Stripe and payment API keys from the WordPress database entirely where possible. Use environment variables rather than wp_options storage
Audit wp_users after any supply chain incident. Credential harvesting often leads to rogue admin account creation as a persistence mechanism

Detect

Run scheduled maldet scans on wp-content/plugins/ and wp-content/themes/. Supply chain backdoors sit in plugin directories, not just media or upload paths
Monitor for outbound connections to newly registered domains from web server processes. C2 domains in all three incidents were registered days before the attack
Alert on wp_remote_post() or curl_exec() calls from plugin loader files. Legitimate plugin loaders do not typically make outbound HTTP requests at bootstrap time

The LMD signatures referenced in this post are open source under the GPL v2 license and available via linux-malware-detect. If you have additional IOCs, variant samples, or have observed related activity, reach out via Keybase or email.