ClickFix attack via SQL injection CMS: analysis of the Ghost CMS campaign (CVE-2026-26980) and detection equipment

Depov

Moderator
Staff member
MODERATOR
ULTIMATE
SUPREME
PREMIUM
MEMBER
Joined
Feb 18, 2025
Messages
242
Reaction score
305
Deposit
0$
One HTTP request to the public Content API – and the attacker takes Admin API Key without a single credential. Do not crumble anything, do not need to tribute admin, do not even know that the site on Ghost. Just crafted request to the endpoint that sticks out by design.

In the three months after the release of the patch, more than 700 domains – including Harvard, Oxford and DuckDuckGo – have become a platform for distributing infostlers through the ClickFix chain. According to QiAnXin XLab, at least two independent groups of attackers compete for control over infected sites: they delete each other’s scripts and implement their own code, sometimes several times a day on the same domain. Just like two graffitisters on the same wall.

CVE-2026-26980 - CVSS 9.4 Critical, EPSS 0.70 (Top 1% by probability of operation). One unparameterized line in CMS runs a chain from blind SQLi to PowerShell on the end user machine. Let’s see how it works and how to catch.
The business logic of the attack: why to turn blogs into a weapon
Why would an attacker a university blog or a SaaS-company technical platform? Trust of the domain. Classic phishing through a random domain is filtered by mail gateways and suspicious users. Fake CAPTCHA on Harvard website - no. The browser does not swear, the URL looks legitimate, the SSL certificate is valid.

The attacker monetizes the chain through two vectors.

The first - Massive Distribution of Stylish. A trusted domain visitor performs a PowerShell-team via ClickFix bait, an infoseller gets to the car. Next - theft of session tokens, passwords from the browser, authentication material. The second – Reusing the compromised infrastructure. Stolen Admin API Key and Ghost CMS configuration can be used for lateral movement to other business systems of the same organization. Loader on the infected pages refers to C2 - payload changes without re-burglary: today the style, tomorrow is a miner, the day after tomorrow browser exploit kit.

For the owner organization, this is reputational damage, leakage of visitor data, regulatory consequences. For a penester on the project - a ready-made initial access vector with full administrative control over the content of the client site.
CVE-2026-26980: anatomy of SQL injection in Ghost CMS
Technical mechanics Ghost CMS SQL injection
Ghost CMS - Node.js-platform with open source, 50 000+ stars on GitHub, popular among universities, media and technical companies. Vulnerability CVE-2026-26980 (CWE-89, Injection, category OWASP A03:2021 - Injection) affects the versions from 3.24.0 to 6.19.0 inclusive. corriged at 6.19.1, released on February 19, 2026.
CVSS-vector analysis: network access (AV:N), low operating complexity (AC:L), privileges are not required (PR:N), user interaction is not required (UI:N). Impact - High compromising confidentiality and integrity (C:H, I:H), low exposure to accessibility (A:L). In short, anyone can come in, without a password, from the Internet.

According to the Cloud Security Alliance, the vulnerability is in the module slug-filter-order.js - Input series of Content API. The value of slug from the query parameter was substituted directly in the SQL-construction ORDER BY through lines concatenation instead of parameterized binding. The content API on the Ghost architecture is public and does not require authentication - Content API Key is built directly into HTML topics. Operation does not require any accounting data or preliminary reconnaissance - one crafted HTTP request is enough to public endpoint.

The attacker sends a request with blind SQLi payload in the slug/order parameter and sympathizes with arbitrary data from the database. The main goal is Admin API Key.

Public PoC is available in repository n0bitaemon/CVE-2026-26980-PoC on GitHub. The exploit is also registered in Exploit-DB under the number EDB-52555 (authored by Maksim Rogov, publication date - May 7, 2026). GitHub Security Advisory - GHSA-w52v-v783-gw97 from February 16, 2026.
Why Admin API Key is the only point of failure
There are two types of keys in the Ghost architecture. Content API Key - read-only, for front-end, reads published content only. Admin API Key - full administrative access: creation, editing, posting, user management, themes and settings of the site. Through endpoint PUT /ghost/api/admin/posts/:id/ You can modify articles directly - without entering the dashboard, without MFA, without any interactive interaction.

Architectural problem: Admin API Key is stored in the same database that the public Content API serves. Any vulnerability to reading data in the Content API automatically compromises the administrative credential. A classic violation of the principle of separation of credential storage and publicly available query paths - OWASP A01:2021 (Broken Access Control). In fact, the key to the safe lies in the hallway.

Context of Applicability: [External pentest, black box] Any self-hosted Ghost CMS 3.24.0.0. Ghost(Pro) has aid hosting is updated automatically and is not subject to attack. WAF with generic SQLi signatures can block base payloads, but blind SQLi via ORDER BY parameter bypasses many WAFs that are not tuned to filtering the content API. In practice, Cloudflare WAF in the default configuration missed this vector - the ordering parameters simply did not fall into rules.
CMS attacks through vulnerabilities: full chain from SQLi to lumarium

The two-stage loader should be disassembled separately. The first stage is the minimum JS fragment sewn into the body of an article through the Admin API. It encodes the origin of the site through btoa(window.location.origin) and appeals to the C2. In the first wave of attacks was used endpoint clo4shara[.]xyz/11z77u3.php, in the second wave (since May 16) - com-apps[.]cc. C2 returns distribution script - a typical cloaking mechanism that collects the fingerprint visitor and decides whether to show payload or not.

The updated version of the loader uses localStorage browser for tracking - a cloaking script is performed only once on the device. This reduces the likelihood of re-detector and complicates the life of analysts: he came a second time - nothing happens. For the attacker, the profile is obvious: the change of payload to C2 does not require a re-call of the site. One loader, 700+ infected domains, endless load rotation.

According to SentinelOne, the active operation of CVE-2026-26980 was recorded since the end of February 2026 - 8 days after the release of the patch. The temporary compilation label of one of the DLL files is dated February 16 - three days before the publication of the patch. Someone knew about the bug before the fix came out.
ClickFix attack on website: how social engineering works through a trusted domain
ClickFix is a technique in which the visitor is offered to “confirm that he is a person” performing the action on his car. Chain in this campaign: the visitor opens an article on the trusted Ghost website → JS-loader loads the cloaking script → that fingerprint browser → when filters are passed, displays an iframe with a fake Cloudflare versioning on top of the content. The user is asked to open a Run (Win + R) dialog, insert the provided command and press Enter. The command loads and triggers the malicious load.

This is MITRE ATT&CK T1204.004 (Malcious Copy and Paste, Execution) - the victim herself performs a malicious command. Browser-level protections are bypassed, most endpoint solutions are silent because the execution is initiated by the user. The technique works precisely because millions of people are accustomed to legitimate Cloudflare inspections and do not perceive them as a threat. We have trained users to click on these checkboxes.

According to XLab, the campaign used three types of payloads. DLL-loaders (installer.dll) - with valid code-signing certificates PuTTY client, which makes it difficult to detect on endpoint. JavaScript Droppers (notepadplusplus.js) Electron-based infostealer (UtilifySetup.exe) - collection of in-session tokens, credential from browsers and authentication material from infected Windows systems. On May 16, XLab recorded a new installer.dll with zero detecting on VirusTotal. Zero of 70+ engines.

There are a few unpleasant moments for the blue team. ClickFix bypasses the standard email security gateway (the attack goes through the web, not via mail). Bypasses browser oclosure (the command is performed outside the browser). Bypasses endpoint detection if the user himself has started the process. Detecting is possible at the network level - DNS-setolfilling C2-domains - and through the analysis of running processes: PowerShell with suspicious arguments after Win + R.
ClickFix campaign detection: practical methods for SQL injections in CMS
Analysis of logs on the server side
If Ghost CMS worked on any version from 3.24.0 to 6.19.0 after February 2026 - consider it compromised, even if in the admin panel everything is clean. The loader injection is performed through the Admin API, not through the editor. You won’t see anything in the visual interface.

The first step is to check the Admin API. Look for challenges PUT /ghost/api/admin/posts/:id/ from non-standard IP addresses:
Bash:
grep "PUT /ghost/api/admin/posts" /var/log/nginx/access.log \
| awk '{print $1, $4, $7}' \
| sort | uniq -c | sort -rn | head -20
Anomaly - mass PUT requests for different post IDs with one IP in a short period. The legitimate editor rules one or two articles, the attacker modifies all posts by the bulk. If you see 50+ PUTs per minute from one address, that's it.

Additionally, check the Content API for abnormal queries with ordering parameters - it was through them that SQLi was operated. In Nginx-logs are requests to /ghost/api/content/ with unusually long query string in parameters filter or order.
Content audit at the database level
It is necessary to check the content at the level of the DB, not through the Ghost editor. Injected JS usually sits at the end of an HTML body article and can be invisible in a visual editor. For MySQL/MariaDB:
SQL:
SELECT id, title, updated_at FROM posts
WHERE html LIKE '%<script%clo4shara%'
OR html LIKE '%<script%com-apps%'
OR html LIKE '%btoa(window.location.origin)%';
Substitute the current IoC from the XLab report. Results - direct confirmation of compromise. Pay attention to the field updated_at: It will show when exactly the article was modified. Compare with your latest legitimate editing.
Detective on the network level
On the side of the corporate network ClickFix-activity is caught on the outgoing requests to the cleaking domains. Key IoC according to XLab:

Threat Actor A: Domains clo4shara[.]xyz and com-apps[.]cc. Threat Actor B: XLab identified a second group with a separate set of injectable characteristics - IoC is published in the full XLab technical report.

For Elastic 8.x+ with Network Module - monitoring of DNS-sliping of these domains through the correlation rule. CrowdStrike Falcon with DNS-monitoring will cover the same vector. For Splunk will require the correlation of DNS-legs with proxy-legals by timetable and source IP.

Restriction of the detect: cloaking script filters visitors by browser fingerprint. If your traffic analyzer or SIEM-sensor is recognized as a bot - ClickFix payload is not given. To verify, redirect the query with a realistic User-Agent and a typical set of browser titles. Headless Chrome with default settings will not roll - cloaking sees it.
Checklist: CMS protection from SQL injections and response to Ghost CMS vulnerability CVE
Ready-made checklist - you can include in the report on the pentest or transfer to the administrator as it is:
1. Update Ghost CMS to version 6.19.1 or higher. Check the current version: ghost versionin the CLI.
2. Rotate all keys: Admin API Key, Content API Key, administrator password, all active session tokens. Previously considered active keys compromised.
3. Audit of all published articles at the level of the database - look for injected <script>at the end of HTML-body (SQL query above).
4. Check the Admin API logs from February 2026: mass PUT requests for endpoints from atypical IP.
5. If mass modifications are detected, restore from a pure backup dated to the first suspicious record.
6. Configure WAF (ModSecurity, Cloudflare WAF) with SQLi locking rules in ordering/flitering Content API settings.
7. Enable Admin API logging calls with a stay of at least 30 days.
8. Notify visitors - if compromising is confirmed, users could execute malicious commands through ClickFix.
9. Check other systems of the organization - stolen credential can be used for the lateral movement.
 
Top Bottom