Campaign SiteGuarding 2013–present 3 audits

← All audits

Audit #28 Malicious Closed by wp.org · trunk uncleaned

27 affected plugins · 5k+ combined active installs · 27 closed on wp.org · baseline 1.2 → head 7.5.4 · by austin · closed 1d ago

Actor: SiteGuarding (SafetyBis Ltd. — Cyprus HE 232905, dissolved 2016-01-11). 13-year operation, 27 plugins under @siteguarding + @sgdevteam, then burner accounts @lulub5592 and @dalielsam.
Show full summary

SiteGuarding 27-plugin portfolio (2013-2020) — 15 plugins shipped siteguarding_tools.php v1.7 RCE backdoor INLINE in the plugin folder; 12 sibling plugins shipped phone-home guideline violations. wp.org closed all 27 in May-June 2020. Operator pivoted to anonymous burner accounts (audits #25, #26). Legacy C2 still operational, currently serving v2.4 backdoor (2026-04-08).

🛑
5k+ installs across 27 plugins potentially exposed to compromised code.

Site owners should remediate immediately. Plugin author: see the steps below to clear this label.

If you run any of these 27 plugins on your site

See the Affected plugins table below for the full slug list. To check whether any are installed across your fleet:

wp plugin list --field=name | grep -E '^(wp\-antivirus\-site\-protection|wp\-admin\-graphic\-password|grab\-youtube\-subtitle|wp\-user\-access\-notification|realtime\-seo|wp\-badbot\-protection|easy\-geo\-blocker\-and\-redirect|easy\-geo\-redirect|server\-mail\-blacklist\-checker|simple\-backup\-tool|spam\-protection\-antispam\-for\-contact\-form\-7|toxic\-links\-scanner|website\-admin\-two\-factor\-authentication|website\-blacklist\-monitor|website\-outbound\-link\-checker|website\-security\-and\-server\-performance\-analytics|wp\-admin\-access\-notification\-telegram\-sms|wp\-admin\-bruteforce\-protection\-and\-notification|wp\-admin\-protection|wp\-antivirus\-website\-protection\-and\-firewall|wp\-automatic\-plagiarism\-checker|wp\-contact\-us\-form|wp\-geo\-website\-protection|wp\-graphic\-captcha\-protection|wp\-seo\-website\-protection|wp\-text\-copy\-blocker|wp\-website\-content\-protection)$'

For each match, verify your install against the wp.org canonical and remove if compromised:

wp plugin verify-checksums <slug>
wp plugin deactivate <slug>
wp plugin delete <slug>

Patched builds for the major affected slugs are hosted at plugins.captaincore.io — see the cleanup instructions for site operators below for the full per-plugin URL list.

If you're the plugin author

Cleanup steps to clear this label have not yet been documented for this audit. Contact the investigator listed above.

The label clears automatically on the next wp beacon scan-deltas once the cleanup conditions above are met.

Affected plugins (27)

All plugins covered by this incident report. Combined exposure: 5k+ active installs across 27 slugs.

Plugin Active installs Trunk version wp.org status
WP Antivirus Site Protection (by SiteGuarding.com) 4k+ 7.5.4 Closed on wp.org
WP Admin Graphic Password (by SiteGuarding.com) 300 1.9 Closed on wp.org
Youtube Subtitle Grabber 100 1.5 Closed on wp.org
WP User Access Notification (by SiteGuarding.com) 100 2.2 Closed on wp.org
Real Time SEO 80 1.8.2 Closed on wp.org
WP BadBot Protection 40 1.5 Closed on wp.org
WP Easy GEO Blocker and Redirect 10 1.6 Closed on wp.org
Easy GEO Redirect 10 1.3 Closed on wp.org
Server Mail Blacklist Checker 10 1.2 Closed on wp.org
Simple Backup & Restore Plugin 10 2.2 Closed on wp.org
Spam Protection, AntiSpam for Contact Form 7 10 1.0 Closed on wp.org
Toxic Link Scanner 10 1.1 Closed on wp.org
Website Admin Two-Factor Authentication 10 1.0 Closed on wp.org
Website Blacklist Monitor 10 1.3 Closed on wp.org
Toxic Links Scanner 10 1.1 Closed on wp.org
Website Security and Server Performance Analytics 10 1.2 Closed on wp.org
WP Admin Access Notification with Telegram SMS 10 2.0 Closed on wp.org
WP Admin Bruteforce Protection and Notification (by SiteGuarding.com) 10 1.0 Closed on wp.org
WP Admin Protection (by SiteGuarding.com) 10 2.4 Closed on wp.org
WP Antivirus Website Protection and Website Firewall (by SiteGuarding.com) 10 8.0.4 Closed on wp.org
WP Automatic Plagiarism Checker 10 1.0 Closed on wp.org
WP Development and Security Assistant 10 1.1 Closed on wp.org
WP GEO Website Protection (by SiteGuarding.com) 10 2.9.1 Closed on wp.org
WP Graphic Captcha Protection (by SiteGuarding.com) 10 1.5 Closed on wp.org
SEO Website Protection 10 1.1 Closed on wp.org
WP Text Copy Blocker 10 1.0 Closed on wp.org
WP Website Content Protection 10 1.1 Closed on wp.org

IOCs extracted (7)

Kind Value Confidence
code_pattern $_GET['task'] == 'remove_malware_files' high
code_pattern $_GET['task'] == 'view_file' high
code_pattern SITEGUARDING_SERVER_IP1 high
code_pattern SITEGUARDING_SERVER_IP2 high
code_pattern Task_savefile medium
domain www.siteguarding.com high
url https://www.siteguarding.com/ext/antivirus/index.php high

Tracing SiteGuarding: A 13-Year WordPress Supply-Chain Operation Hidden in Plain Sight

Draft writeup compiled from WP Beacon audits #25 and #26 — last updated 2026-05-02

The headline

SiteGuarding (siteguarding.com — registered 2013-06-11) ran a 13-year, three-phase WordPress supply-chain operation through at least four wp.org committer accounts, controlling code on thousands of WordPress installs across multiple plugin families. The operation pivoted from overt SaaS branding (2013-2020, 27 wp.org plugins) to anonymous burner accounts (2020-2026, two more plugins) after wp.org closed the original portfolio for guideline-violations in mid-2020. Both SiteGuarding's legacy command-and-control infrastructure AND its new burner-era infrastructure are fully operational right now. Their backdoor codebase has shipped ten-plus iterations across six years; we pulled the current version (v2.4 dated 2026-04-08) directly from the live C2 with no authentication.

WP Beacon caught the operation through committer-graph analysis tying together the original @siteguarding account, the burner account @lulub5592 that surfaced in audit #25, and the second burner @dalielsam from audit #26 — all linked by shared DNS (NS1.SITEGUARDING.COM on the new C2 domain cmsplughub.com) and overlapping infrastructure on the same Leaseweb USA 198.7.59.0/24 cluster.

This is the first published documentation of the SiteGuarding operation as a connected threat actor.

Phase 1 — The overt era (2013-2020, 27 plugins)

SiteGuarding registered the wp.org account @siteguarding on 2013-10-02, four months after registering the company domain. Over the next seven years they shipped 27 plugins across security, scanning, and SEO categories:

PluginFirst seenLast updateActive installs at closure
wp-antivirus-site-protection2014-05-172018-06-11 (v7.5.4)4,000+
wp-admin-graphic-password(8 versions)300+
wp-user-access-notification(8 versions)100+
grab-youtube-subtitle(5 versions)100+
realtime-seo(10 versions)80+
wp-badbot-protection(3 versions)40+
wp-geo-website-protection2020-05-08 (v2.9.1, 30 versions)not snapshotted
wp-admin-protection(13 versions)not snapshotted
wp-graphic-captcha-protection(4 versions)not snapshotted
18 others(1-4 versions each)<10 each

Most-installed: wp-antivirus-site-protection (~85% of the install base). The other 26 were small adjacent utilities.

What the portfolio plugins actually did — two distinct threat tiers

Cross-portfolio code review (greppable IOCs across all 27 local git repos) revealed the portfolio splits into two threat tiers. Both share the same C2 infrastructure, both were closed in the same wp.org sweep, both were operated by the same accounts — but the in-plugin code shape differs significantly:

#### Tier A — Direct supply-chain backdoor (15 plugins)

These plugins ship siteguarding_tools.php v1.7 (482 lines, identical file, md5 3eddf6d18214d0d612809efd585a2471) bundled inline inside the plugin folder. Installing any of these 15 plugins instantly plants a web-accessible RCE backdoor at /wp-content/plugins/<slug>/siteguarding_tools.php. The file:

  • Has no if (!defined('ABSPATH')) exit; guard — directly web-accessible without WordPress bootstrap
  • Accepts unauthenticated requests from operator IPs 185.72.157.169-172 (Polish hosting at support.pl, the v1.7-era control plane)
  • Falls back to RSA-PGP-signed task_pgp parameter for non-allowlisted callers
  • Exposes Task_savefile (write arbitrary file under WEBSITE_ROOT), Task_showfile (exfiltrate any file), Task_download (stream-download), Task_includefile (write attacker PHP to a .tmpcode file then include() it — full RCE), Task_fileinfo (recon)
  • Has its own update action that fetches a fresh backdoor from siteguarding.com/ext/panel_api/index.php (the same self-update mechanism documented in audit #25 that's currently shipping v2.4)

The 15 Tier A plugins:

easy-geo-blocker-and-redirect    easy-geo-redirect
grab-youtube-subtitle            realtime-seo
simple-backup-tool               toxic-links-scanner
website-blacklist-monitor        website-outbound-link-checker
website-security-and-server-performance-analytics
wp-admin-graphic-password        wp-admin-protection
wp-badbot-protection             wp-contact-us-form
wp-geo-website-protection        wp-user-access-notification

Combined install base for Tier A at closure: ~880 active installs (mostly small plugins; flagship is in Tier B). Each install was a direct supply-chain backdoor — the operator could fetch https://victim.example/wp-content/plugins/<slug>/siteguarding_tools.php from any of the four allowlisted IPs and execute arbitrary PHP. No further deployment step required.

#### Tier B — Phone-home guideline violation only (12 plugins)

These plugins call siteguarding.com for legitimate-looking SaaS-plugin features (license check, remote scan, update info) but do NOT bundle siteguarding_tools.php inline. Inspecting the flagship wp-antivirus-site-protection 7.5.4 (50 versions of git history reconstructed):

// antivirus.php:14
define('SITEGUARDING_SERVER', 'http://www.siteguarding.com/ext/antivirus/index.php');

// referenced 9+ times in calls like:
$link = SITEGUARDING_SERVER.'?action=do_remote_scan&remote_id='.$remote_do_id;
$link = SITEGUARDING_SERVER.'?action=licenseinfo&type=json&data=';
$link = SITEGUARDING_SERVER.'?action=updateinfo&data=';
$link = SITEGUARDING_SERVER.'?action=getreport_ver2&data='.$post_data;

The 12 Tier B plugins:

server-mail-blacklist-checker, spam-protection-antispam-for-contact-form-7,
website-admin-two-factor-authentication, wp-admin-access-notification-telegram-sms,
wp-admin-bruteforce-protection-and-notification,
wp-antivirus-site-protection (FLAGSHIP — 4,000+ active installs at closure),
wp-antivirus-website-protection-and-firewall, wp-automatic-plagiarism-checker,
wp-graphic-captcha-protection, wp-seo-website-protection,
wp-text-copy-blocker, wp-website-content-protection

Combined install base for Tier B at closure: ~3,810 active installs (dominated by the flagship at 4,000+). The wp.org policy violation here is undisclosed phone-home: WordPress.org plugin guidelines require explicit user opt-in for any external service calls. SiteGuarding's Tier B plugins phoned home unconditionally, embedded the API endpoint as a hardcoded constant, and offered the user no opt-out.

The flagship wp-antivirus-site-protection had a separate "consent-based remote management tool installation" UX flow that asked the user to opt in to dropping siteguarding_tools.php into WordPress root — a different delivery shape than the inline-bundled Tier A plugins. Users who clicked through that flow ended up with the same backdoor file in ABSPATH rather than /wp-content/plugins/<slug>/.

#### Counterintuitive distribution choice

The flagship — wp-antivirus-site-protection at 4,000+ installs (85% of the portfolio's install base) — is in Tier B. The 15 plugins shipping the inline backdoor were almost all small adjacent utilities (most under 100 installs each, several under 10). The operator deliberately concentrated direct-backdoor distribution in lower-profile plugins where code review by independent security researchers would be less likely. The headline product used the consent-based path; the backwater plugins shipped the backdoor inline.

#### wp.org closure timeline

Across the May-June 2020 wp.org review wave, all 27 plugins were closed in a 32-day window with closed_reason='guideline-violation':

2020-05-04   easy-geo-blocker-and-redirect, toxic-links-scanner,
             wp-antivirus-website-protection-and-firewall  (3 plugins)
2020-06-03   website-security-and-server-performance-analytics, realtime-seo  (2 plugins)
2020-06-05   the remaining 22 plugins

The wp.org review team likely caught the inline-bundled siteguarding_tools.php in some Tier A plugins during the review wave and closed adjacent Tier B plugins from the same author for the looser "undisclosed phone-home" pattern. Either way, the entire portfolio was closed in 32 days.

The closure was apparently silent — searching public WordPress security trackers (Wordfence, Patchstack, WPScan), security-blog archives, news coverage, and the wp.org Plugin Review Team's own announcements yielded zero documentation of the 2020 mass closure. SiteGuarding lost their wp.org distribution channel quietly.

A second SiteGuarding wp.org account

Building local git histories for all 27 plugins surfaced a SECOND committer beyond @siteguarding: @sgdevteam authored most of the trunk-only commits in 2019-2020 across 8 plugins:

easy-geo-redirect             realtime-seo
simple-backup-tool            website-blacklist-monitor
wp-admin-access-notification-telegram-sms
wp-automatic-plagiarism-checker
wp-badbot-protection          wp-website-content-protection

Multiple of these are dated 2020-06-01 — four days before wp.org's mass closure. The team account looks like it was making last-minute commits trying to stay ahead of the looming review action.

Phase 2 — The pivot (2020-mid-2025)

wp.org closed the SiteGuarding portfolio on 2020-06-05. Twenty-six days later (2020-07-01), a new wp.org account was registered: @lulub5592, display name "CaptchaMaster". No bio, no website, no employer, no social links, no portfolio history.

Five months after that, on 2020-12-03, @lulub5592 published a single plugin: wp-advanced-math-captcha. To casual inspection, an unrelated indie WordPress captcha plugin from a new author. From day one, the plugin shipped with wp-math-captcha.dat — a zlib-compressed PHP dropper that, when loaded, decoded a base64 blob and wrote siteguarding_tools.php into the WordPress root. The dropper hardcoded the C2 endpoint as apitest.siteguarding.com/plugin_api/index.php, deleted itself after planting the backdoor, and POSTed the install's URL back to the C2 to register the new infection. The dropped backdoor v1.7 was internally dated 20 March 2020 — the same code SiteGuarding had been distributing through the consent-based path in their original antivirus plugins, just relocated to a covert delivery vehicle.

The plugin grew slowly over the next four years. Six thousand active installations by April 2026. Then, on 2025-11-16, @lulub5592 added a second malicious primitive: includes/advert-test-codes.php. A 32KB class whose only purpose is to nag the WordPress admin to install another specific plugin from wp.org via an admin_post_advrec_install_plugin handler. The hardcoded target slug? image-optimizer-x.

Phase 2.5 — The second burner

image-optimizer-x was launched on wp.org by a different account, @dalielsam (display name "Daniel X"). Same anonymity profile: no bio, no website, no portfolio history. The dalielsam account had been registered on 2022-11-17 — two and a half years before the plugin debuted in May 2025, plenty of buffer to age the account.

For the first six months, image-optimizer-x was a clean image optimizer (472-line main file, no C2 wiring). On 2025-12-16 — exactly 30 days after lulub5592 added the forced-install primitive — @dalielsam shipped v1.3.2 with a 981-line companion file: CMSPlughubAPI_LicenseValidator.php. The validator hardcodes:

private $api_base_url    = 'https://api.cmsplughub.com';
private $verify_endpoint = '/verify.php';
private $updater_endpoint = '/updater.php';
private $rsa_private_key_primary   = '-----BEGIN PRIVATE KEY-----...'; // 2048-bit
private $rsa_private_key_secondary = '-----BEGIN PRIVATE KEY-----...'; // 512-bit

Two embedded RSA private keys (a meaningless construct for legitimate licensing — public keys would suffice; private keys are for bidirectional authenticated control) and a generic downloadFile($url, $destination) primitive wrapped as a "GeoIP database updater". The plugin loads the validator on every admin request, calls home to api.cmsplughub.com, and writes whatever the C2 returns to a fixed local path.

cmsplughub.com was registered on 2025-02-11 — eighty-six days before image-optimizer-x launched on wp.org. Purpose-built infrastructure staged in advance.

The chain became operational on 2025-12-16: lulub5592's plugin pushes users to install dalielsam's plugin; dalielsam's plugin pulls instructions from cmsplughub.com.

The DNS smoking gun

cmsplughub.com was the chain's only public-looking infrastructure surface. Both wp.org accounts (@lulub5592, @dalielsam) had been built over years to look unrelated, with staggered creation dates and zero overlapping metadata. The architectural style of v1.3.2's validator was different enough from the older .dat dropper that, considered in isolation, the two campaigns might pass for separate operators using similar primitives.

But the DNS record gave it away:

$ dig +short NS cmsplughub.com
ns1.siteguarding.com.
ns2.siteguarding.com.

$ dig +short A cmsplughub.com
198.7.59.167

$ dig +short A siteguarding.com
198.7.59.167

cmsplughub.com not only uses SiteGuarding's nameservers — its A record resolves to the same IP address as siteguarding.com itself. Reverse DNS:

$ dig -x 198.7.59.167 +short
server2.siteguarding.com.
hosting2.siteguarding.com.

The supposedly-independent licensing service api.cmsplughub.com lives on a host literally named server2.siteguarding.com. Both domains are colocated in the same Leaseweb USA hosting account. The operator didn't even try to hide it at the rDNS layer.

The C2 is alive and being actively maintained

Both C2 endpoints respond right now to anonymous requests:

GET https://api.cmsplughub.com/updater.php?unique_id=image-optimizer-x&file=geo.mmdb&domain=example.com&md5=00000000000000000000000000000000
→ 9.2MB binary (real MaxMind GeoIP database, MaxMind.com end-marker present)

GET https://api.cmsplughub.com/updater.php?unique_id=wp-advanced-math-captcha&file=geo.mmdb&domain=example.com&md5=00000000000000000000000000000000
→ same binary payload — the C2 backend RECOGNIZES BOTH burner plugins as valid clients

GET https://api.cmsplughub.com/updater.php?unique_id=any-other-slug&...
→ {"status":"error","reason":"Wrong plugin unique_id: any-other-slug"}

The C2 maintains an explicit allowlist of valid plugin IDs. We probed 30+ candidate slugs (the original 27 SiteGuarding portfolio + a dozen guesses at sibling burner names). Only image-optimizer-x and wp-advanced-math-captcha are recognized. The new C2 was purpose-built specifically for this two-burner operation; the older 27 plugins still talk to the legacy C2.

That legacy C2 is also still operational — and serving fresh malware updates:

GET https://www.siteguarding.com/ext/panel_api/index.php?action=update
→ {"md5":"36085499a539d4543b1ec0f59f1ad0c7", "b64content":"PD9waHAK..."}

Decoding the base64 payload yields siteguarding_tools.php version 2.4 dated 2026-04-08 — published one day after wp.org closed both burner plugins on 2026-04-07. That's not an old artifact still reachable; it's the operator visibly continuing development the day after a major disclosure event.

Six years of malware development

The audit #25 dropper bundled siteguarding_tools.php v1.7 (dated 2020-03-20). The live C2 is shipping v2.4 (dated 2026-04-08). Diffing the two versions:

v1.7 (March 2020)v2.4 (April 2026)Change
File size482 lines / 13.8K819 lines / 24.8K+70%
md53eddf6d18214d0d612809efd585a247136085499a539d4543b1ec0f59f1ad0c7(live samples preserved)
Allowlisted control IPs185.72.157.169-172 (4 IPs, Polish hosting at support.pl)198.7.59.167, 198.7.59.168 (2 IPs, Leaseweb USA — same cluster as cmsplughub.com)Operator's control plane migrated
Hostname-based authnot presentNEW: any caller whose reverse DNS ends in siteguarding.com (excluding "hosting") is auto-authenticatedNew auth bypass mechanism
Push-update channelmanual update action onlyOperator passes latest_ver + latest_md5 request params; backdoor self-fetches and overwritesFleet-update capability
Taskssavefile, showfile, download, includefile, fileinfo (5)+ deletefile, copyfile (7)New file-manipulation primitives
Path validationnonenew Validate_Path() defensive checkOperational hardening
Self-fingerprint in pingabsentreports WEBSITE_ROOT (absolute disk path), self_md5, AND contents of webanalyze/website-security-conf.php (operator's panel credentials from prior installs)Telemetry + cred-exfil
Persistence redundancymanualevery ping copies the backdoor to webanalyze/siteguarding_tools.php if missing or smaller; recovery action restores root copy from the webanalyze copySelf-healing persistence

The 2026-era backdoor is mature, actively-maintained malware code. Not a dormant 2020 artifact still floating around — real ongoing software development happening on this codebase.

The most significant change is the operational shift: the v1.7 control plane was on Polish hosting (Support.pl sp. z. o. o., RIPE region) at four sequential IPs; v2.4 collapsed that to two IPs at the SAME Leaseweb USA host that runs cmsplughub.com. Single hosting account now operates: legacy backdoor C2 frontend, cmsplughub validator C2, AND the operator's static control plane. Operationally tighter, also a single takedown target.

Plus: the new hostname-based auth bypass means the operator can promote new control IPs by adding subdomain rDNS entries to siteguarding.com's zone — no code change, no IP allowlist update, no PGP key rotation needed. Production-quality fleet management for malware ops.

Implications

5+ years of historical SiteGuarding-portfolio installs are STILL controllable. Any WordPress site that ran one of the 27 closed plugins between 2013-2020 may still have siteguarding_tools.php (or its webanalyze/ backup copy) in its WordPress root. Those backdoors poll siteguarding.com/ext/panel_api/ on operator schedule, and the C2 is serving fresh tasks today. Many of those sites are likely no longer monitored — small-business or hobbyist sites that installed an antivirus plugin in 2017, lost interest in active security tooling, and never noticed the plugin had been closed in 2020 or that a siteguarding_tools.php had been planted in their WordPress root years earlier.

The wp.org closure response is incomplete by design. wp.org can stop distributing a plugin, but it can't reach into existing installations and pull files out. For plugins that drop files outside the plugin directory (siteguarding_tools.php in WP root, or future image-optimizer-x update payloads written to assets/), the closure is a "stop new infections" action only. Existing installs need active remediation.

This isn't a one-off opportunistic compromise. This is a 13-year operation by an actor that:

  • Built a 27-plugin SaaS portfolio and operated it openly for 7 years
  • Survived a major wp.org policy enforcement action by pivoting to anonymous burner accounts within 26 days
  • Maintained the legacy attack infrastructure continuously across the 6-year burner era
  • Engineered coordinated 30-day rollouts between sibling accounts in 2025
  • Continues active malware development post-disclosure (v2.4 published one day after wp.org's April 2026 closure)
  • Owns four wp.org accounts, three domains (siteguarding.com, cmsplughub.com, safetybis.com), and infrastructure in two regions (Leaseweb USA, plus historic Polish hosting at support.pl)

Cleanup checklist for affected sites

If your site has ever run any of these plugins, treat as compromised until proven otherwise:

Phase 1 portfolio (2013-2020 era, all closed in May-June 2020 by wp.org):

  • wp-antivirus-site-protection, wp-antivirus-website-protection-and-firewall
  • wp-admin-protection, wp-admin-bruteforce-protection-and-notification, wp-admin-graphic-password
  • wp-graphic-captcha-protection, wp-text-copy-blocker, wp-website-content-protection
  • wp-geo-website-protection, wp-seo-website-protection, wp-user-access-notification
  • wp-admin-access-notification-telegram-sms, wp-badbot-protection
  • wp-contact-us-form, wp-automatic-plagiarism-checker
  • spam-protection-antispam-for-contact-form-7
  • realtime-seo, grab-youtube-subtitle, simple-backup-tool
  • easy-geo-blocker-and-redirect, easy-geo-redirect
  • toxic-links-scanner, website-outbound-link-checker, website-blacklist-monitor
  • website-admin-two-factor-authentication
  • server-mail-blacklist-checker
  • website-security-and-server-performance-analytics

Phase 2 burner accounts (2020-2026 era, both closed April 2026):

  • wp-advanced-math-captcha (audit #25)
  • image-optimizer-x (audit #26)

Remediation steps:

1. Search WordPress root recursively for siteguarding_tools.php and webanalyze/siteguarding_tools.php. Delete both. The presence of either indicates the operator has had RCE on this site at some point. 2. Look for the webanalyze/ directory under WP root. It may also contain website-security-conf.php (operator's panel-login credentials previously exfiltrated). Delete the entire directory. 3. Search for files matching the v2.4 backdoor md5 (36085499a539d4543b1ec0f59f1ad0c7) or v1.7 (3eddf6d18214d0d612809efd585a2471). Older versions (v1.0-v1.6, v2.0-v2.3) likely exist in the wild as well — anything matching the siteguarding_tools.php filename should be presumed malicious. 4. Block outbound traffic at the firewall to: siteguarding.com, www.siteguarding.com, apitest.siteguarding.com, .siteguarding.com, cmsplughub.com, api.cmsplughub.com, safetybis.com. Block by hostname rather than IP — the operator can rotate IPs via the rDNS-based auth bypass. 5. Block outbound to the IP cluster 198.7.59.0/24 (Leaseweb USA, currently hosts the operator's control plane) and 185.72.157.0/24 (Polish, legacy backdoor allowlist). 6. Audit Users → All Users for any unfamiliar admin accounts. The siteguarding_tools.php Task_savefile primitive can write arbitrary files; the Task_includefile primitive can execute arbitrary PHP — combined, the operator can create new admin accounts at will. 7. Rotate WordPress admin passwords, database credentials, and SFTP/SSH keys. Per audit #25 disclosures (wp-config.php size > 9KB is a tell, fake wp-comments-posts.php typosquat in WP root, generic admin names like officialwp/superadmin), if any of these markers are present the operator likely already has persistence beyond just the dropped backdoor. 8. For sites that ran image-optimizer-x specifically, also check wp_options for image_optimizer_x_ rows (iox_lic, iox_lic_status, iox_lic_data) — these may contain RSA-encrypted state from the cmsplughub C2. Delete after uninstall.

Indicators of compromise

Domains:

  • siteguarding.com, www.siteguarding.com (legacy C2 frontend, currently operational)
  • apitest.siteguarding.com (2020-era inform endpoint, currently operational)
  • cmsplughub.com, api.cmsplughub.com, www.cmsplughub.com (2025-2026 burner C2)
  • safetybis.com (sibling C2, NS = NS1/NS2.siteguarding.com)
  • server2.siteguarding.com, hosting2.siteguarding.com (rDNS for 198.7.59.167)

URLs:

File hashes:

  • 36085499a539d4543b1ec0f59f1ad0c7 (siteguarding_tools.php v2.4, 2026-04-08, 24,851 bytes)
  • 3eddf6d18214d0d612809efd585a2471 (siteguarding_tools.php v1.7, 2020-03-20, 13,888 bytes)

Filenames:

  • siteguarding_tools.php (the dropped backdoor, in WP root or webanalyze/)
  • webanalyze/website-security-conf.php (panel credentials — exfiltrated on every backdoor ping)
  • wp-math-captcha.dat, wp-math-captcha.dat.tmp (v1.7 dropper file in wp-advanced-math-captcha)
  • includes/advert-test-codes.php (forced-install primitive in wp-advanced-math-captcha post-2025-11)
  • CMSPlughubAPI_LicenseValidator.php (C2 validator in image-optimizer-x post-2025-12)

Code patterns:

  • SITEGUARDING_SERVER constant
  • siteguarding_tool_code (dropper variable name)
  • ADVREC_TARGET_PLUGIN, ADVREC_AdverPluginRecommendation (forced-install class)
  • CMSPlughubAPI_LicenseValidator (validator class)
  • Task_includefile, Task_savefile, Task_showfile, Task_download, Task_fileinfo, Task_deletefile, Task_copyfile (backdoor task functions)
  • $allowed_IPs, task_pgp, PGP_decrypt, rsa_private_key_primary, rsa_private_key_secondary (auth primitives)
  • IP literals: 185.72.157.169, 185.72.157.170, 185.72.157.171, 185.72.157.172 (legacy allowlist), 198.7.59.167, 198.7.59.168 (current allowlist)
  • DNS infrastructure: NS1.SITEGUARDING.COM, NS2.SITEGUARDING.COM

wp.org committer accounts (all SiteGuarding-controlled):

  • @siteguarding — Phase 1, 27 plugins (2013-2020), all closed
  • @sgdevteam — Phase 1, internal team account, surfaced on 8+ portfolio plugins
  • @lulub5592 — Phase 2 burner #1 (2020-2026), single plugin wp-advanced-math-captcha, closed 2026-04-07
  • @dalielsam — Phase 2 burner #2 (2025-2026), single plugin image-optimizer-x, closed 2026-04-07

Source materials

  • WP Beacon audit #25: wp-advanced-math-captcha — full forensic writeup of the post-2020 burner, dropped backdoor analysis (v1.7), forced-install primitive
  • WP Beacon audit #26: image-optimizer-x — second burner, CMSPlughub side-channel C2, embedded-RSA-keys analysis
  • WP Beacon audit #27 (in progress): SiteGuarding 27-plugin portfolio (2013-2020), this writeup
  • Local git mirrors: 27/27 SiteGuarding portfolio plugins reconstructed at ~/Documents/WP.org/git/<slug>/ (~191MB across all repos)
  • Live malware sample: siteguarding_tools.php v2.4, pulled from https://www.siteguarding.com/ext/panel_api/index.php?action=update

Coverage gap

This operation has had no prior public attribution or coverage:

  • The 2020 mass closure of the 27-plugin portfolio was apparently silent — no contemporaneous coverage from WP.org's Plugin Review Team, no security blog writeups, no entries in Wordfence/Patchstack/WPScan vulnerability databases attributing it to SiteGuarding, no CVE assignments
  • The 2026 supply-chain wave that took down both burner plugins on 2026-04-07 was widely covered (TechCrunch, Cybernews, designstouch.com, rswebsols.com, anchor.host, gbhackers.com) — but the coverage focused on adjacent campaigns from the same wave (anadnet/scroll-top, EP/Essential Plugin / "Kris" buyer via Flippa, the wp-advanced-math-captcha .dat dropper). The SiteGuarding lineage going back to 2013 — and the cmsplughub.com side-channel C2 — went undocumented.
  • The continuous v2.4 development of the backdoor codebase post-disclosure has likewise gone unnoticed.

This writeup is the first to connect SiteGuarding's overt 2013-2020 wp.org plugin presence with the 2020-2026 anonymous-burner phase, and the first to document cmsplughub.com as an active C2.

---

Appendix A — Corporate structure: SafetyBis Ltd. (and what it became)

The 2014-era plugin headers cite a registered legal entity. From wp-antivirus-site-protection v1.2 (2014-05-17, the first published version of the flagship):

Author: SiteGuarding.com (SafetyBis Ltd.)

SafetyBis Limited is a real Cyprus company:

FieldValue
Cyprus Registry #HE 232905
Incorporated2008-07-01
StatusDISSOLVED 2016-01-11
Registered addressΕυαγόρα Παπαχριστοφόρου 18, PETOUSSIS BROS BUILDING, Floor 3, 3030, Limassol, Cyprus
DirectorDRAFIELO LIMITED (Cyprus HE 245565)
SecretaryDRAFIELO LIMITED
DRAFIELO LIMITED's DirectorROBIDOUX EQUITIES LTD.
DRAFIELO LIMITED's other affiliations~125 Cyprus companies

Layered Cyprus nominee structure: SafetyBis Ltd → DRAFIELO LIMITED (corporate nominee director) → ROBIDOUX EQUITIES (the next layer up). The actual beneficial owner is shielded behind multiple corporate layers — classic Cyprus offshore privacy pattern. DRAFIELO LIMITED is a nominee-director service hosting hundreds of unrelated entities; tracing further would require purchased Cyprus registry reports.

What the dissolution means

SafetyBis Ltd. dissolved on 2016-01-11 — but the SiteGuarding operation kept running for another 10 years under the same brand:

  • siteguarding.com stayed registered (currently paid through 2031-06-11)
  • safetybis.com stayed registered, but was repurposed — the current homepage positions the brand as "Web Development Agency | Cyprus Web Development", not security services. Same Limassol DNA, different stated business
  • 27 wp.org plugins kept shipping new versions under @siteguarding and @sgdevteam accounts through 2020 (4 years post-dissolution)
  • siteguarding_tools.php backdoor kept being maintained — currently at v2.4 dated 2026-04-08 (10 years post-dissolution)
  • Two burner wp.org accounts (@lulub5592 from July 2020, @dalielsam from November 2022) launched after the dissolved Cyprus entity — no public attribution to any legal vehicle

Plugin author attribution survey

Across the 27-plugin portfolio, the Author: header in each plugin's main PHP file shows multiple brand variants. Crucially, the SafetyBis Ltd. attribution is dropped after the 2016 dissolution:

Author header (verbatim)Plugin countEra
SiteGuarding.com (SafetyBis Ltd.)17Pre-2016 dissolution
Technology Solutions Code (SafetyBis Ltd.)1 (grab-youtube-subtitle)Pre-2016
SiteGuarding.com (no Cyprus entity)5Post-2016
SiteGuarding (no .com, no entity)3Post-2016
SEOGuarding1 (realtime-seo)Sub-brand

Earliest portfolio commit: 2014-03-03 (wp-admin-protection). Latest: 2020-06-01 (multiple plugins, last commits 4 days before wp.org closure). The two-brand pattern (SiteGuarding for security, SEOGuarding for SEO products) was active alongside the primary brand throughout.

"Since 2005" claim

The 2014 wayback snapshot of siteguarding.com displays "since 2005" branding. SafetyBis Ltd. wasn't incorporated until 2008-07-01 — the brand pre-dates the Cyprus entity by 3 years. Either:

  • An earlier legal entity existed (Ukraine? Poland? UK?) that the brand carried over from
  • The "since 2005" claim is marketing-only with no incorporated business behind those years
  • The brand was acquired in 2008 by SafetyBis from an earlier owner

Per cybersecurityintelligence.com, SiteGuarding is currently listed as "London United Kingdom" — but no UK Companies House entity matches. Likely either a third-party data feed inaccuracy or a UK presence operating outside Companies House registration.

Continued infrastructure ownership post-dissolution

Despite SafetyBis Ltd. being formally dissolved 10 years ago, the operation's domain portfolio is still actively managed:

DomainCreatedCurrently owned byCurrently paid through
siteguarding.com2013-06-11(privacy-masked Namecheap)2031-06-11
safetybis.com2007-06-27(GDPR-masked, Cyprus state code)unknown
cmsplughub.com2025-02-11(privacy-masked, Iceland)unknown

All three share NS1.SITEGUARDING.COM / NS2.SITEGUARDING.COM for nameservers. All three resolve to or are colocated on the Leaseweb USA 198.7.59.0/24 cluster. The operator either:

  • Personally maintained domain renewals after SafetyBis dissolved (paying out-of-pocket since 2016)
  • Transferred domains to a new legal entity that's not publicly disclosed
  • Operates the domains under nominee names with no formal corporate owner

Implications for attribution

This isn't an anonymous criminal operation. It's:

  • A real Cyprus-registered company with traceable corporate history (2008-2016)
  • A public commercial brand with G2 / Trustpilot reviews and paying customers
  • A 13-year continuous operation under the SiteGuarding name
  • Currently operating WITHOUT a publicly-attributed legal entity (since the 2016 SafetyBis dissolution)

The post-2016 era — covering more than half the operation's lifespan — is corporate-veil-less. There's no registered business answering for the SiteGuarding brand today. Customers paying for siteguarding.com services since 2016 have been transacting with an entity that doesn't legally exist.

Combined with the malware findings: the dissolved Cyprus entity may have been the legitimate-services arm; the post-dissolution operation may be the malware-only arm operated by the same principals without legal cover. Or the dissolution may have been deliberate corporate restructuring to shed liability before the malware operation scaled. Without purchased Cyprus registry deep-dive reports (€65 per the cyprusregistry.com note) or further pivoting on DRAFIELO LIMITED's 125 affiliated entities, the question of WHO owns the SiteGuarding brand today remains open.

---

Appendix B — Subdomain footprint of siteguarding.com

TLS certificate Subject Alternative Names:

DNS:cpanel.siteguarding.com
DNS:cpcalendars.siteguarding.com
DNS:cpcontacts.siteguarding.com
DNS:mail.siteguarding.com
DNS:siteguarding.com
DNS:webdisk.siteguarding.com
DNS:webmail.siteguarding.com
DNS:www.siteguarding.com

Standard cPanel-managed hosting subdomains, plus the operational siteguarding.com and www.siteguarding.com. No custom subdomains exposed — the operational endpoints (apitest.siteguarding.com, the *hosting2.siteguarding.com rDNS used by the rDNS-auth-bypass) are covered by separate certs or wildcard configurations.

The cpanel/webmail subdomain pattern indicates standard shared-hosting cPanel deployment — not a custom security operations stack.

---

Appendix C — Flagship plugin (wp-antivirus-site-protection) malware-evolution timeline

50 versions across 4 years (2014-2018), then a 2-year dormancy until wp.org's 2020 mass closure. Compiled from local git reconstruction of every released version.

Version-by-version growth

DateVersionLOCFilesSignificance
2014-05-171.21,2103First wp.org release. Already ships SITEGUARDING_SERVER constant pointing to siteguarding.com/ext/antivirus/index.php. "Register your website on SiteGuarding.com" opt-in flow + PRO upsell + license check from day one.
2014-05-292.01,4113Added getreport_ver2 action. New sgantivirus.class.php and antivirus.class.php files. Architecture matures from monolithic to class-based.
2014-05-302.0.11,8084New sgantivirus.class.php split out.
2014-07-283.02,4684Major scan-engine rewrite (+396 LOC).
2014-09-264.03,0804Heuristic detection added (+351 LOC).
2015-04-075.0 / 5.0.14,7456Files jumped 4→6 (license + scanner architecture rewrite).
2016-04-066.05,7057Added sgantivirus.login.php (login-protection feature). New updateinfo action.
2016-10-076.57,7407Switched from raw file_get_contents to wp_remote_*. LOC nearly doubled in one release (5,705 → 7,740).
2017-01-037.08,9957SITEGUARDING_SERVER_IP1 (185.72.157.169) and SITEGUARDING_SERVER_IP2 (185.72.157.170) HARDCODED in main plugin file. First time the operator's static control-plane IPs appear in the plugin code itself.
2017-05-127.514,62410Major architecture rewrite. LOC nearly doubled again (9,115 → 14,624). New antivirus.php file. Added do_remote_scan action. Last touch of SITEGUARDING_SERVER references — code stabilized here.
2017-12-217.5.114,64110Minor maintenance (+17 lines).
2018-05-047.5.314,65910Minor maintenance (+18 lines).
2018-06-117.5.414,65910Final release. Then dormant 2 years until wp.org closure.
2020-06-05wp.org closes the plugin in the portfolio-wide guideline-violation sweep.

v7.0 (2017-01-03) — when the flagship became operator-accessible

The most significant version in the timeline is v7.0, which introduced two hardcoded operator IPs directly into the main plugin file:

define('SITEGUARDING_SERVER_IP1', '185.72.157.169');
define('SITEGUARDING_SERVER_IP2', '185.72.157.170');

These are two of the four IPs from the dropped siteguarding_tools.php backdoor's allowlist. They gate eight unauthenticated $_GET['task'] handlers in wp-antivirus-site-protection.php that anyone can hit by querying ?task=<name>&access_key=<key> against any installation:

$_GET['task']Auth gateCapability
cronaccess_key onlyTrigger scan; results POSTed to siteguarding.com
upgradeaccess_key onlyPlugin self-update
standaloneaccess_key onlyStandalone scan invocation
statusaccess_key onlyRead scan status
settingsaccess_key onlyRead plugin settings
get_malware_filesaccess_key onlyReturn list of files flagged as malware in last scan
view_fileaccess_key + (REMOTE_ADDR == IP1 OR IP2)Read ANY file under ABSPATH (echoes full contents + size + md5)
remove_malware_filesaccess_key + (REMOTE_ADDR == IP1 OR IP2)Delete files from disk based on the SiteGuarding-server-stored "last_scan_files" list

Two of these — view_file and remove_malware_files — are filesystem-level primitives accessible to anyone holding the right access_key from one of the two operator IPs. Effective capability: the SiteGuarding operator can read or delete any file on every wp-antivirus-site-protection install, on demand.

The access_key is per-install, assigned during the "Register your website on SiteGuarding.com" flow — but SiteGuarding's server stores every issued access_key (it IS the license-validation server). So SiteGuarding has perpetual (access_key, IP) combo for every install.

Combined with the consent-based siteguarding_tools.php drop into WordPress root (the flagship's "remote management tool" flow which adds Task_includefile for full RCE), the flagship's effective threat model matches the inline-bundled Tier A plugins — just delivered through a different code path.

Architectural arc

The plugin's 50-version history shows three distinct development phases:

Phase A (2014-05 → 2015-04, 25 versions, v1.2 → v5.0.3) — rapid feature growth from 1,210 to 4,857 LOC. Average release cadence: every ~13 days. SiteGuarding-server phone-home present from v1.2 (day one), but no operator-IP allowlist or view_file/remove_malware_files primitives yet. The SaaS-plugin baseline shape.

Phase B (2015-04 → 2017-01, 17 versions, v5.0 → v7.0) — slower iteration, deeper integrations. Average release cadence: every ~38 days. Login-protection, cron-based scanning, switch to wp_remote_*, rewrites of the scanner class. The plugin's footprint reaches ~9,000 LOC. Phase B ends with v7.0 introducing the IP-allowlisted task handlers.

Phase C (2017-01 → 2018-06, 8 versions, v7.0 → v7.5.4) — operator-access era. The plugin now exposes view_file + remove_malware_files to any caller from 185.72.157.169 or 185.72.157.170 with the install's access_key. v7.5 (May 2017) doubled the codebase to 14,624 LOC, then iteration slowed dramatically. Three minor releases (7.5.1, 7.5.3, 7.5.4) over the next 13 months added a combined 35 lines.

Phase D (2018-06 → 2020-06) — silent abandonment. Zero commits for 24 months. By contrast, during 2014-2018 the plugin shipped one new version every ~30 days on average. The 2018-2020 dormancy represents an effective 10x slowdown to zero. Other portfolio plugins continued to receive updates during this period (@sgdevteam was active through 2019-2020), so the dormancy was specific to the flagship — possibly indicating customer acquisition had moved to direct sales via siteguarding.com or development effort had shifted to the smaller portfolio plugins where the inline-bundled siteguarding_tools.php distribution shape was less likely to attract review.

The flagship sat at v7.5.4 for 2 years before wp.org's 2020 cleanup wave caught it.

Verdict

malicious

IOCs to extract

  • kind: domain, value: siteguarding.com, confidence: high
  • kind: domain, value: cmsplughub.com, confidence: high
  • kind: domain, value: safetybis.com, confidence: high
  • kind: url, value: https://www.siteguarding.com/ext/panel_api/index.php, confidence: high
  • kind: url, value: https://api.cmsplughub.com/updater.php, confidence: high
  • kind: filename, value: siteguarding_tools.php, confidence: high
  • kind: code_pattern, value: SITEGUARDING_SERVER, confidence: high
  • kind: code_pattern, value: SITEGUARDING_SERVER_IP1, confidence: high
  • kind: code_pattern, value: SITEGUARDING_SERVER_IP2, confidence: high
  • kind: code_pattern, value: Task_includefile, confidence: high
  • kind: code_pattern, value: 185.72.157.169, confidence: high
  • kind: code_pattern, value: 198.7.59.167, confidence: high
  • kind: code_pattern, value: NS1.SITEGUARDING.COM, confidence: high
  • kind: file_hash, value: 36085499a539d4543b1ec0f59f1ad0c7, confidence: high
  • kind: file_hash, value: 3eddf6d18214d0d612809efd585a2471, confidence: high