← All audits

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

WP Advanced Math Captcha Closed on WP.org · 6k+ installs · baseline 2.1.8 → head 2.1.9.1 · by austin · closed 9h ago

Show full summary

Two distinct supply-chain attack chains in a single 6,000-install plugin, both operated by SiteGuarding (siteguarding.com) through two anonymous wp.org committer accounts. wp.org Plugin Review Team (PRT, plugin-master) closed the plugin on 2026-04-07 and stripped the older payload, but the second chain (forced-install of a sibling plugin) remains live in trunk on every existing install.

wp-advanced-math-captcha (6,000 active installations) was published 2020-12-03 by @lulub5592 (display name "CaptchaMaster" — anonymous wp.org account, no bio/website/employer, member since 2020-07-01, sole author). The plugin had two distinct malicious primitives ship from the same SVN account:

Chain 1 — wp-math-captcha.datsiteguarding_tools.php dropper (since 2020-12-03)

Bundled since the very first wp.org release. wp-math-captcha.dat is a zlib-compressed PHP dropper (~7KB compressed → ~19KB decompressed) that, when included, decodes a base64-embedded siteguarding_tools.php and writes it to ABSPATH/siteguarding_tools.php — directly into the WordPress installation root, outside the plugin folder. After dropping the file, the dropper deletes itself (unlink(__FILE__)) and POSTs the website URL + plugin slug to https://apitest.siteguarding.com/plugin_api/index.php?action=inform.

The dropped siteguarding_tools.php (advertised as "SiteGuarding tools installer for customer's panel, ver. 1.7, Date: 20 Mar 2020") is a full PHP RCE / file-management backdoor:

  • Authentication: hardcoded IP allowlist (185.72.157.169, 185.72.157.170, 185.72.157.171, 185.72.157.172) AND a 512-bit RSA private key embedded in the file. Requests originating from a non-allowlisted IP can still execute provided they include a task_pgp POST field encrypting the task_id with the embedded key.
  • C2 endpoint: http://www.siteguarding.com/ext/panel_api/index.php (HTTP, falls back to HTTPS on failure). Fetches a JSON task list and dispatches.
  • Task primitives (full RCE):
  • Task_savefile — base64-decode and write arbitrary file to webroot, with optional skip flag for if-not-exists semantics
  • Task_showfile — base64-encode and exfiltrate any file under webroot
  • Task_download — stream any file under webroot as application/octet-stream
  • Task_includefile — write attacker-supplied PHP code to a randomly-named .tmpcode file under webanalyze/ and include() it (arbitrary PHP execution), then unlink
  • Task_fileinfo — return existence/size/ctime/md5 for any file
  • Built-in update action that overwrites siteguarding_tools.php itself with content fetched from the C2 (auto-updating backdoor)
  • Persistence: Task_savefile with create_folder directive creates a webanalyze/ directory under webroot. The dropped backdoor copies itself to webanalyze/siteguarding_tools.php if the backup is missing/older. A recovery action restores the root copy from the webanalyze/ copy without authentication.
  • Operational hygiene: Disables PHP error reporting (error_reporting(0), ini_set('error_log', NULL), ini_set('log_errors', 0)), sets 7200-second execution time, sets timezone to Europe/London, ignores user abort.

The 2020 ship date and "ver. 1.7 / Date: 20 Mar 2020" comments inside the backdoor itself indicate this is established SiteGuarding infrastructure, not a 2025-era injection. The backdoor pre-dates the wp-math-captcha plugin by ~8 months.

Chain 2 — includes/advert-test-codes.php forced-install primitive (added 2025-11-16)

Added in r3396781 (@lulub5592, commit message: 'wp-advanced-math-captcha'). Single 32KB file containing the ADVREC_AdverPluginRecommendation class:

  • Hardcoded target: define('ADVREC_TARGET_PLUGIN', 'image-optimizer-x')
  • Three admin_post_advrec_* action handlers: hide_recommendation, show_recommendation, install_plugin
  • Admin nag (admin_notices hook) and admin bar menu (admin_bar_menu priority 100) pushing the user to install the target
  • handle_install_plugin() requires current_user_can('install_plugins') + nonce, then calls plugins_api() for the target slug and Plugin_Upgrader::install($api->download_link) — installs the sibling plugin from wp.org's official CDN

The install path is properly authenticated, but the target plugin is attacker-controlled, which makes this a delivery vehicle: every admin who clicks "Install" pulls down image-optimizer-x from wp.org, and from that point the sibling plugin's side-channel update endpoint (see Linkage section) lets the attacker rotate the payload remotely without needing wp.org access.

This file is still in the wp.org-served trunk as of 2026-05-02 — the 2026-04-07 PRT cleanup release stripped only the .dat file, not the forced-install primitive.

Linkage to image-optimizer-x and SiteGuarding attribution

image-optimizer-x (the forced-install target):

  • Author: @dalielsam (display name "Daniel X" — anonymous wp.org account, no bio/website/employer, member since 2022-11-17, sole author)
  • wp.org publish date: 2025-05-07 (six months before lulub5592 added the forced-install primitive)
  • Closed by wp.org: 2026-04-07 (same day as wp-advanced-math-captcha — same wp.org cleanup wave)
  • Side-channel update mechanism: ships CMSPlughubAPI_LicenseValidator.php with a hardcoded base URL https://api.cmsplughub.com and an updater_endpoint that downloads + extracts a remote zip via wp_remote_get + file_get_contents. Same architectural primitive as scroll-top (audit #12) and ultimate-social-media-plus (audit #24): a plugin-shipped update channel pointing at attacker infrastructure, bypassing wp.org's review.

The decisive attribution evidence: cmsplughub.com (image-optimizer-x's update C2) is registered with nameservers NS1.SITEGUARDING.COM and NS2.SITEGUARDING.COM. SiteGuarding owns the DNS infrastructure that the image-optimizer-x update endpoint resolves through. Combined with the wp-math-captcha.dat dropper that hardcodes the siteguarding.com C2, both attack chains in this audit terminate at SiteGuarding-controlled infrastructure.

Both wp.org accounts (lulub5592, dalielsam) are anonymous shells — no public identity, no portfolios, single plugin each, distinct join dates (2020-07 and 2022-11) staggered to look unrelated. The shared infrastructure is the only public link.

Domain registration timeline

  • siteguarding.com — registered 2013-06-11 (established, 12-year-old company front)
  • cmsplughub.com — registered 2025-02-11, 86 days before image-optimizer-x's wp.org launch (2025-05-07). Purpose-built C2 staged in advance.

PRT response (2026-04-07, r3500482, plugin-master)

  • Tagged 2.1.9.1 from trunk
  • D /trunk/wp-math-captcha.dat (removed Chain 1 dropper) ✓
  • M /trunk/wp-math-captcha.php (modifications — likely removing the .dat include)
  • M /trunk/readme.txt (closure notice)
  • Closed plugin on wp.org permanently (closure_date = 2026-04-07)

What PRT missed: includes/advert-test-codes.php (Chain 2 forced-install) is untouched. Existing 6,000 installs still have the forced-install primitive locally — wp.org closing the plugin only stops new downloads; it does not remediate sites that already pulled an infected version. Any admin clicking the "Recommended" nag still pulls down image-optimizer-x from wp.org's CDN (the plugin was wp.org-closed same day, but the closure does not retroactively pull down the wp.org-archived versioned zip — the cdn URL pattern still resolves).

Public coverage and prior researcher

  • rswebsols.com (2026-04-19) — credits Austin Ginder; lists wp-advanced-math-captcha as part of an April 2026 supply-chain wave alongside the EP/essentialplugin suite. IOC fragment: wp-comments-posts.php (typosquat, plural variant of legit wp-comments-post.php), suspicious wp-config.php >9KB, generic admin accounts (officialwp, superadmin).
  • designstouch.com (2026-04-16) — confirms 8-month dormant primitive, April 5–6 2026 activation, RCE backdoor, and lists artifacts including wp-math-captcha.dat and wp-math-captcha.dat.tmp.

The .tmp variant referenced in the public coverage suggests Chain 1 had a staged-update mechanism (the dropper + a temp variant fetched at activation), consistent with the MaxualUpdate() function in siteguarding_tools.php that overwrites the backdoor itself with C2-supplied content keyed by md5 hash.

🛑
6k+ installs are running compromised code right now.

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

If you run wp-advanced-math-captcha on your site

Verify your install matches the wp.org canonical version:

wp plugin verify-checksums wp-advanced-math-captcha

Install the patched build:

⬇ Download patched zip — or install directly via WP-CLI:

wp plugin install https://plugins.captaincore.io/wp-advanced-math-captcha-2.1.9.1-patched.zip --force

The patched zip strips the malicious code while preserving the plugin's normal functionality. Hosted at plugins.captaincore.io.

Or remove the plugin entirely:

wp plugin deactivate wp-advanced-math-captcha
wp plugin delete wp-advanced-math-captcha

If you're the plugin author

The wp.org PRT cleanup release 2.1.9.1 (2026-04-07) only fixed half the malware. PRT removed the older wp-math-captcha.dat Chain-1 dropper and added a defensive MATH_CAPTCHA_PRT_incidence_response() function that unlinks the dropped siteguarding_tools.php on every plugin load, BUT they did NOT remove the Chain-2 forced-install primitive — includes/advert-test-codes.php is still in the trunk and still actively include_once'd by wp-math-captcha.php. Existing 6,000 installs still ship the admin nag pushing the SiteGuarding-controlled image-optimizer-x plugin.

A drop-in patched build is available with the Chain-2 primitive removed:

wp plugin install https://plugins.captaincore.io/wp-advanced-math-captcha-2.1.9.1-patched.zip --force --skip-themes --skip-plugins

What changed vs. wp.org 2.1.9.1:

  • Deleted includes/advert-test-codes.php (Chain-2 forced-install: 32KB file containing the ADVREC_AdverPluginRecommendation class with the hardcoded image-optimizer-x target slug, three admin_post_advrec_* actions, admin-bar nag, and admin_notices push)
  • wp-math-captcha.php: removed the include_once(MATH_CAPTCHA_PATH . 'includes/advert-test-codes.php'); line (PRT's oversight) and bumped the Version: header to 2.1.9.1-patched
  • readme.txt: bumped Stable tag to 2.1.9.1-patched

Kept unchanged: PRT's defensive MATH_CAPTCHA_PRT_incidence_response() cleanup function, the user-facing incident notice, and the entire legitimate captcha core (includes/class-core.php, class-settings.php, class-cookie-session.php, class-update.php, class-geo.php, geo.mmdb, integrations).

Independent of installing this patched build, site owners should also (per the audit's full remediation checklist):

  • Search the WordPress root for siteguarding_tools.php and webanalyze/siteguarding_tools.php — PRT's defensive cleanup runs only when the plugin loads, so a deactivated plugin won't sweep these. Delete them if found.
  • Check for wp-comments-posts.php typosquat (plural) in the WP root.
  • Inspect wp-config.php for unexplained size growth (>9KB warrants review).
  • Audit Users → All Users for unfamiliar admin accounts (officialwp, superadmin, or any post-2025-11 additions).
  • If image-optimizer-x was installed via the nag, delete it — it has a side-channel update endpoint at api.cmsplughub.com (NS = NS1.SITEGUARDING.COM, same operator).
  • Block outbound to siteguarding.com, apitest.siteguarding.com, cmsplughub.com, api.cmsplughub.com.
  • Rotate WordPress admin, database, and SFTP/SSH credentials.

Verification: wp plugin get wp-advanced-math-captcha --field=version should report 2.1.9.1-patched.

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

Plugins under the same committer's SVN access

lulub5592 holds push access to 1 plugin totalling 6k+ active installs.

WP Advanced Math Captcha — COMPROMISED — this audit
6k+

IOCs extracted (22)

Kind Value Confidence
code_pattern $allowed_IPs medium
code_pattern 185.72.157.169 high
code_pattern 185.72.157.170 high
code_pattern 185.72.157.171 high
code_pattern 185.72.157.172 high
code_pattern ADVREC_AdverPluginRecommendation high
code_pattern ADVREC_TARGET_PLUGIN high
code_pattern NS1.SITEGUARDING.COM high
code_pattern SITEGUARDING_SERVER high
code_pattern siteguarding_tool_code high
code_pattern Task_includefile medium
domain api.cmsplughub.com high
domain apitest.siteguarding.com high
domain cmsplughub.com high
domain siteguarding.com high
filename advert-test-codes.php high
filename CMSPlughubAPI_LicenseValidator.php high
filename siteguarding_tools.php high
filename webanalyze/siteguarding_tools.php high
filename wp-math-captcha.dat high
url http://www.siteguarding.com/ext/panel_api/index.php high
url https://apitest.siteguarding.com/plugin_api/index.php high

Plugin version history

Every release on wp.org for this plugin, color-coded by relationship to the incident. wp.org closed this plugin rather than deleting the malicious tags — every Malicious — on wp.org release below is still re-installable today and remains a live exposure for any site running it.

  1. Clean 14 earlier releases before the incident
    • 1.2.11
    • 1.2.12
    • 1.2.15
    • 1.2.20
    • 2.0
    • 2.0.01
    • 2.1
    • 2.1.1
    • 2.1.2
    • 2.1.3
    • 2.1.4
    • 2.1.5
    • 2.1.6
    • 2.1.7
  2. 2.1.8 Last clean Last clean release before incident
  3. 2.1.9 Clean Clean (post-cleanup)
  4. 🛑 Compromise window

    wp.org closed this plugin during the compromise window. The malicious tags below remain visible on wp.org and re-installable until each site manually upgrades to the rescue release.

  5. 2.1.9.1 Malicious (head) First malicious release (head of audit)

Timeline

  1. siteguarding.com registered
  2. siteguarding_tools.php ver 1.7 timestamp (per backdoor's internal version comment)
  3. @lulub5592 wp.org account created
  4. plugin-master (wp.org) initial commit creating the plugin slot for wp-advanced-math-captcha
  5. @lulub5592 first author commit, wp-math-captcha 1.0 published with wp-math-captcha.dat already bundled (Chain 1 ships from day 1)
  6. @dalielsam wp.org account created
  7. cmsplughub.com registered (purpose-built C2 staged 86 days before image-optimizer-x launch)
  8. image-optimizer-x published on wp.org by @dalielsam
  9. r3396781 by @lulub5592 adds includes/advert-test-codes.php (Chain 2 — forced-install primitive linking the two accounts operationally)
  10. plugin-master (wp.org PRT) cleanup release 2.1.9.1 removing wp-math-captcha.dat only; image-optimizer-x closed same day; wp-advanced-math-captcha closed same day
  11. recent_prt_intervention event #2058 fires; this audit opens

Audit #25 — wp-advanced-math-captcha

  • Plugin: wp-advanced-math-captcha (WP Advanced Math Captcha)
  • Active installs: 6,000
  • Event: #2058 recent_prt_intervention · medium · 2026-05-02 20:04:59
  • Baseline version: 2.1.8 (last clean release before malicious-add)
  • Head version: 2.1.9.1

Summary

Two distinct supply-chain attack chains in a single 6,000-install plugin, both operated by SiteGuarding (siteguarding.com) through two anonymous wp.org committer accounts. wp.org Plugin Review Team (PRT, plugin-master) closed the plugin on 2026-04-07 and stripped the older payload, but the second chain (forced-install of a sibling plugin) remains live in trunk on every existing install.

wp-advanced-math-captcha (6,000 active installations) was published 2020-12-03 by @lulub5592 (display name "CaptchaMaster" — anonymous wp.org account, no bio/website/employer, member since 2020-07-01, sole author). The plugin had two distinct malicious primitives ship from the same SVN account:

Chain 1 — wp-math-captcha.datsiteguarding_tools.php dropper (since 2020-12-03)

Bundled since the very first wp.org release. wp-math-captcha.dat is a zlib-compressed PHP dropper (~7KB compressed → ~19KB decompressed) that, when included, decodes a base64-embedded siteguarding_tools.php and writes it to ABSPATH/siteguarding_tools.php — directly into the WordPress installation root, outside the plugin folder. After dropping the file, the dropper deletes itself (unlink(__FILE__)) and POSTs the website URL + plugin slug to https://apitest.siteguarding.com/plugin_api/index.php?action=inform.

The dropped siteguarding_tools.php (advertised as "SiteGuarding tools installer for customer's panel, ver. 1.7, Date: 20 Mar 2020") is a full PHP RCE / file-management backdoor:

  • Authentication: hardcoded IP allowlist (185.72.157.169, 185.72.157.170, 185.72.157.171, 185.72.157.172) AND a 512-bit RSA private key embedded in the file. Requests originating from a non-allowlisted IP can still execute provided they include a task_pgp POST field encrypting the task_id with the embedded key.
  • C2 endpoint: http://www.siteguarding.com/ext/panel_api/index.php (HTTP, falls back to HTTPS on failure). Fetches a JSON task list and dispatches.
  • Task primitives (full RCE):
  • Task_savefile — base64-decode and write arbitrary file to webroot, with optional skip flag for if-not-exists semantics
  • Task_showfile — base64-encode and exfiltrate any file under webroot
  • Task_download — stream any file under webroot as application/octet-stream
  • Task_includefile — write attacker-supplied PHP code to a randomly-named .tmpcode file under webanalyze/ and include() it (arbitrary PHP execution), then unlink
  • Task_fileinfo — return existence/size/ctime/md5 for any file
  • Built-in update action that overwrites siteguarding_tools.php itself with content fetched from the C2 (auto-updating backdoor)
  • Persistence: Task_savefile with create_folder directive creates a webanalyze/ directory under webroot. The dropped backdoor copies itself to webanalyze/siteguarding_tools.php if the backup is missing/older. A recovery action restores the root copy from the webanalyze/ copy without authentication.
  • Operational hygiene: Disables PHP error reporting (error_reporting(0), ini_set('error_log', NULL), ini_set('log_errors', 0)), sets 7200-second execution time, sets timezone to Europe/London, ignores user abort.

The 2020 ship date and "ver. 1.7 / Date: 20 Mar 2020" comments inside the backdoor itself indicate this is established SiteGuarding infrastructure, not a 2025-era injection. The backdoor pre-dates the wp-math-captcha plugin by ~8 months.

Chain 2 — includes/advert-test-codes.php forced-install primitive (added 2025-11-16)

Added in r3396781 (@lulub5592, commit message: 'wp-advanced-math-captcha'). Single 32KB file containing the ADVREC_AdverPluginRecommendation class:

  • Hardcoded target: define('ADVREC_TARGET_PLUGIN', 'image-optimizer-x')
  • Three admin_post_advrec_* action handlers: hide_recommendation, show_recommendation, install_plugin
  • Admin nag (admin_notices hook) and admin bar menu (admin_bar_menu priority 100) pushing the user to install the target
  • handle_install_plugin() requires current_user_can('install_plugins') + nonce, then calls plugins_api() for the target slug and Plugin_Upgrader::install($api->download_link) — installs the sibling plugin from wp.org's official CDN

The install path is properly authenticated, but the target plugin is attacker-controlled, which makes this a delivery vehicle: every admin who clicks "Install" pulls down image-optimizer-x from wp.org, and from that point the sibling plugin's side-channel update endpoint (see Linkage section) lets the attacker rotate the payload remotely without needing wp.org access.

This file is still in the wp.org-served trunk as of 2026-05-02 — the 2026-04-07 PRT cleanup release stripped only the .dat file, not the forced-install primitive.

Linkage to image-optimizer-x and SiteGuarding attribution

image-optimizer-x (the forced-install target):

  • Author: @dalielsam (display name "Daniel X" — anonymous wp.org account, no bio/website/employer, member since 2022-11-17, sole author)
  • wp.org publish date: 2025-05-07 (six months before lulub5592 added the forced-install primitive)
  • Closed by wp.org: 2026-04-07 (same day as wp-advanced-math-captcha — same wp.org cleanup wave)
  • Side-channel update mechanism: ships CMSPlughubAPI_LicenseValidator.php with a hardcoded base URL https://api.cmsplughub.com and an updater_endpoint that downloads + extracts a remote zip via wp_remote_get + file_get_contents. Same architectural primitive as scroll-top (audit #12) and ultimate-social-media-plus (audit #24): a plugin-shipped update channel pointing at attacker infrastructure, bypassing wp.org's review.

The decisive attribution evidence: cmsplughub.com (image-optimizer-x's update C2) is registered with nameservers NS1.SITEGUARDING.COM and NS2.SITEGUARDING.COM. SiteGuarding owns the DNS infrastructure that the image-optimizer-x update endpoint resolves through. Combined with the wp-math-captcha.dat dropper that hardcodes the siteguarding.com C2, both attack chains in this audit terminate at SiteGuarding-controlled infrastructure.

Both wp.org accounts (lulub5592, dalielsam) are anonymous shells — no public identity, no portfolios, single plugin each, distinct join dates (2020-07 and 2022-11) staggered to look unrelated. The shared infrastructure is the only public link.

Domain registration timeline

  • siteguarding.com — registered 2013-06-11 (established, 12-year-old company front)
  • cmsplughub.com — registered 2025-02-11, 86 days before image-optimizer-x's wp.org launch (2025-05-07). Purpose-built C2 staged in advance.

PRT response (2026-04-07, r3500482, plugin-master)

  • Tagged 2.1.9.1 from trunk
  • D /trunk/wp-math-captcha.dat (removed Chain 1 dropper) ✓
  • M /trunk/wp-math-captcha.php (modifications — likely removing the .dat include)
  • M /trunk/readme.txt (closure notice)
  • Closed plugin on wp.org permanently (closure_date = 2026-04-07)

What PRT missed: includes/advert-test-codes.php (Chain 2 forced-install) is untouched. Existing 6,000 installs still have the forced-install primitive locally — wp.org closing the plugin only stops new downloads; it does not remediate sites that already pulled an infected version. Any admin clicking the "Recommended" nag still pulls down image-optimizer-x from wp.org's CDN (the plugin was wp.org-closed same day, but the closure does not retroactively pull down the wp.org-archived versioned zip — the cdn URL pattern still resolves).

Public coverage and prior researcher

  • rswebsols.com (2026-04-19) — credits Austin Ginder; lists wp-advanced-math-captcha as part of an April 2026 supply-chain wave alongside the EP/essentialplugin suite. IOC fragment: wp-comments-posts.php (typosquat, plural variant of legit wp-comments-post.php), suspicious wp-config.php >9KB, generic admin accounts (officialwp, superadmin).
  • designstouch.com (2026-04-16) — confirms 8-month dormant primitive, April 5–6 2026 activation, RCE backdoor, and lists artifacts including wp-math-captcha.dat and wp-math-captcha.dat.tmp.

The .tmp variant referenced in the public coverage suggests Chain 1 had a staged-update mechanism (the dropper + a temp variant fetched at activation), consistent with the MaxualUpdate() function in siteguarding_tools.php that overwrites the backdoor itself with C2-supplied content keyed by md5 hash.

Verdict

malicious

Added files (1 between 2.1.8 and 2.1.9, 0 between 2.1.9 and 2.1.9.1)

  • includes/advert-test-codes.php (32KB, added in r3396781 by @lulub5592 on 2025-11-16) — Chain 2 forced-install primitive

The .dat dropper (wp-math-captcha.dat) was present in every release from 2020-12-03 through 2.1.9 (2025-11-16) and was removed by PRT in 2.1.9.1 (2026-04-07).

Suspicious pattern hits (3 categories beyond the scaffold)

dropper_to_abspath_writes — Chain 1

  • wp-math-captcha.dat — zlib-compressed PHP that decodes a base64 blob and writes ABSPATH/siteguarding_tools.php, then unlink(__FILE__) to self-delete. The decoded siteguarding_tools.php ships a hardcoded RSA private key, IP allowlist 185.72.157.169-172, and full RCE primitives keyed by JSON-fetched task_id from siteguarding.com/ext/panel_api/index.php.

forced_install_with_admin_nag — Chain 2

  • includes/advert-test-codes.php:46-48 — three admin_post_advrec_* actions including advrec_install_plugin that calls Plugin_Upgrader::install against a hardcoded sibling slug
  • includes/advert-test-codes.php:14define('ADVREC_TARGET_PLUGIN', 'image-optimizer-x') (hardcoded attacker-controlled target)
  • Admin notice + admin bar menu hooks pushing the user toward the install action

shared_infrastructure_attribution

IOCs to extract

  • kind: domain, value: siteguarding.com, confidence: high
  • kind: domain, value: apitest.siteguarding.com, confidence: high
  • kind: domain, value: cmsplughub.com, confidence: high
  • kind: domain, value: api.cmsplughub.com, confidence: high
  • kind: url, value: http://www.siteguarding.com/ext/panel_api/index.php, confidence: high
  • kind: url, value: https://apitest.siteguarding.com/plugin_api/index.php, confidence: high
  • kind: filename, value: siteguarding_tools.php, confidence: high
  • kind: filename, value: wp-math-captcha.dat, confidence: high
  • kind: filename, value: webanalyze/siteguarding_tools.php, confidence: high
  • kind: filename, value: advert-test-codes.php, confidence: high
  • kind: filename, value: CMSPlughubAPI_LicenseValidator.php, confidence: high
  • kind: code_pattern, value: ADVREC_TARGET_PLUGIN, confidence: high
  • kind: code_pattern, value: ADVREC_AdverPluginRecommendation, confidence: high
  • kind: code_pattern, value: SITEGUARDING_SERVER, confidence: high
  • kind: code_pattern, value: siteguarding_tool_code, confidence: high
  • kind: code_pattern, value: $allowed_IPs, confidence: medium
  • kind: code_pattern, value: 185.72.157.169, confidence: high
  • kind: code_pattern, value: 185.72.157.170, confidence: high
  • kind: code_pattern, value: 185.72.157.171, confidence: high
  • kind: code_pattern, value: 185.72.157.172, confidence: high
  • kind: code_pattern, value: Task_includefile, confidence: medium
  • kind: code_pattern, value: NS1.SITEGUARDING.COM, confidence: high

Attribution

  • Operator: SiteGuarding (siteguarding.com) — Ukrainian/Russian-language WordPress security service. Owns the DNS infrastructure (NS1/NS2) for both siteguarding.com and cmsplughub.com, indicating direct administrative control of both attack chains' C2 endpoints.
  • wp.org account 1: @lulub5592 (display name "CaptchaMaster") — joined 2020-07-01, sole plugin wp-advanced-math-captcha, anonymous (no bio/website/employer/social).
  • wp.org account 2: @dalielsam (display name "Daniel X") — joined 2022-11-17, sole plugin image-optimizer-x, anonymous (no bio/website/employer/social).
  • Allowlisted IP block: 185.72.157.169-172 (4 sequential IPs in same /29) — operator's static control plane for direct backdoor access.

Timeline

  • 2013-06-11 — siteguarding.com registered
  • 2020-03-20 — siteguarding_tools.php ver 1.7 timestamp (per backdoor's internal version comment)
  • 2020-07-01 — @lulub5592 wp.org account created
  • 2020-11-27 — plugin-master (wp.org) initial commit creating the plugin slot for wp-advanced-math-captcha
  • 2020-12-03 — @lulub5592 first author commit, wp-math-captcha 1.0 published with wp-math-captcha.dat already bundled (Chain 1 ships from day 1)
  • 2022-11-17 — @dalielsam wp.org account created
  • 2025-02-11 — cmsplughub.com registered (purpose-built C2 staged 86 days before image-optimizer-x launch)
  • 2025-05-07 — image-optimizer-x published on wp.org by @dalielsam
  • 2025-11-16 — r3396781 by @lulub5592 adds includes/advert-test-codes.php (Chain 2 — forced-install primitive linking the two accounts operationally)
  • 2026-04-05/06 — Mass activation event across the April-2026 supply-chain wave (per designstouch.com and rswebsols.com)
  • 2026-04-07 — plugin-master (wp.org PRT) cleanup release 2.1.9.1 removing wp-math-captcha.dat only; image-optimizer-x closed same day; wp-advanced-math-captcha closed same day
  • 2026-05-02 — recent_prt_intervention event #2058 fires; this audit opens

Sibling plugin and post-PRT exposure

  • image-optimizer-x — closed wp.org 2026-04-07 (no install count published — PRT removed metric on closure)
  • Existing wp-advanced-math-captcha installs (≥6,000): still vulnerable to Chain 2 (forced-install primitive in advert-test-codes.php is in trunk that those installs received)
  • Sites that already installed image-optimizer-x via the nag: still have the side-channel update endpoint (api.cmsplughub.com) wired up — operator can rotate payload remotely without wp.org involvement

Cleanup instructions for affected sites

The wp.org cleanup release (2.1.9.1) is incomplete. Site owners running this plugin should:

1. Deactivate and delete wp-advanced-math-captcha entirely. The plugin is permanently closed on wp.org; there is no fix release coming. 2. Search the WordPress root for siteguarding_tools.php — if present, the older .dat dropper executed at some point. Delete it. Also check for a webanalyze/siteguarding_tools.php backup copy. Also search for wp-comments-posts.php (note plural — legit file is singular wp-comments-post.php) per the rswebsols disclosure. 3. Inspect wp-config.php size. Per the public coverage, files >9KB warrant inspection for injected content. 4. Audit Users → All Users for unfamiliar admin accounts (officialwp, superadmin, or any post-2025-11 additions). 5. If image-optimizer-x is also installed, delete it. The CMSPlughub side-channel update mechanism in CMSPlughubAPI_LicenseValidator.php allows the operator to rotate the plugin payload remotely. 6. Rotate WordPress admin passwords, database credentials, and SFTP/SSH keys. 7. Block outbound traffic to siteguarding.com, apitest.siteguarding.com, cmsplughub.com, api.cmsplughub.com at the firewall level.

References