↓ Skip to main content
Rebuilding samarthya.me, part 1: The day the blog fell

Rebuilding samarthya.me, part 1: The day the blog fell

Rebuilding samarthya.me - This article is part of a series.
Part 1: This Article
On 10 October 2026 my blog stopped being mine. This series is the diary of getting it back, and of moving to something simpler: from shared hosting and WordPress to a static site on GitHub Pages behind Cloudflare.

What I found
#

The site had been running WordPress on shared hosting since 2019. When things started to look wrong, a closer look turned up the classic signs of a compromise:

  • Backdoor files in the uploads folder. Two small PHP files, each a few lines that eval() whatever arrives in a request. Uploads is a favourite hiding place: it’s writable, and nobody looks there.
  • A rogue administrator account with a registration date in 1970. A date that’s obviously wrong is the giveaway that it was inserted straight into the database, not created through WordPress.
  • Plugins I didn’t install, including a file manager and a “code snippets” plugin. Both are perfectly legitimate tools, and perfect for an attacker who wants to keep coming back.
  • Posts I never wrote, published under my account. That was the most sobering find: it meant my credentials had been used, not just a vulnerable plugin.
  • Four copies of a “Protect Uploads” plugin in folders with random names (zqwaarh, ivalpno, …), all at an ancient version. A familiar disguise: a harmless-sounding plugin name as cover for a loader.

The timeline
#

The database dump turned out to be a better witness than any log file. WordPress quietly records when plugins are switched off and when snippets are created, and the login-protection plugin kept its own record:

When (UTC)What the evidence shows
8 Oct, 10:1615 failed logins for my username through xmlrpc.php, 5 lockouts. Someone was guessing passwords
9 Oct, 00:59:4120 plugins deactivated in the same second, including the brute-force protection and the cache. Only an administrator can do that
9 Oct, 18:44A code-snippets plugin installed; three seconds later a snippet called content-cache-support
10 Oct, 08:29A second content-cache-support snippet
10–11 OctBackdoors in uploads, the 1970 administrator, posts under my name, a throwaway site-tools-… plugin

Read top to bottom, it’s a textbook takeover: get in, switch off the defences, install tools, dig in.

Was it a known vulnerability?
#

My first instinct was to blame an outdated plugin, so I checked. WordPress itself was the latest release. Ten of 27 plugins had updates waiting, so I looked up every installed version in the public vulnerability databases (checked 25 Oct 2026):

Plugin, installed versionKnown issuesPublishedExplains this break-in?
LiteSpeed Cache 7.9.1CVE-2026-113499, -113500 (XSS, 7.5), -113501 (3.1)23 Oct 2026No: published two weeks after, and they need a victim to click a link
LiteSpeed Cache 7.9.1CVE-2026-84761 (SSRF), CVE-2026-76579 (XSS)3 and 19 Sep 2026No: both already fixed in 7.9.1
Elementor 4.2.4A CSRF in 4.3.0–4.3.1 only; two XSS fixed in 4.3.5Sep–Oct 2026No: the XSS needs a logged-in contributor, and there were no other users
Contact Form 7, the login-protection plugin, the file manager I’d usedNone for the installed versionsNo

No published vulnerability fits the window. What fits is the login record: a week of failed attempts from 30 September, then the first successful logins on 7 October, then more in one day than in the previous eleven months. The most likely explanation is credential stuffing. My admin password had also been used on a few unrelated sites. If any one of them leaked it, the pair “email + password” was all an attacker needed. Add an old remote-publishing endpoint (xmlrpc.php) the site didn’t need, and an account without two-factor authentication.

Not an exotic exploit. That’s almost more uncomfortable, because no plugin update would have prevented it.

Shared responsibility: what the platform didn’t catch
#

The password was my part. But I was on shared hosting with a typical hosting provider, and I had assumed that security there was partly implicit: that the platform watched for the obvious. Looking at the evidence, several layers that a hosting setup can provide either weren’t there or didn’t speak up:

What happenedWhat a hosting platform can do about it
A week of password guessing, then logins from nine different addresses in three daysRate-limit or block brute force on wp-login.php/xmlrpc.php at the server, and flag logins from unusual places. Ironically, the firewall later blocked my home connection for a few retries; the rotating attackers never tripped it
PHP files written into the uploads folderA common hardening default: uploads is for images, so PHP isn’t allowed to run there
A new administrator account, 20 plugins switched off in one second, a file manager installedNotify the account owner about new admins and mass plugin changes
Backdoors that sat on the server for daysScan automatically and alert. The host’s malware scanner did find more infected files, but only when I ran it myself

None of this excuses a reused password. Without that, there was no way in. But security on a shared host is shared responsibility. Each side tends to assume the other has it covered, and that’s exactly the gap an attacker walks through. So the honest conclusion is both: my weakest link was the password, and the platform’s safety nets didn’t catch what came after.

The first hours
#

If this ever happens to you: contain first, investigate second, rebuild third. Don’t try to “clean” a compromised WordPress in place and keep running it.
  1. Take it offline. Not pretty, but it stops the site from being used against visitors.
  2. Change every password that touched it: hosting panel, database, mail accounts, and the registrar. Turn on two-factor authentication wherever it exists.
  3. Keep evidence before deleting anything: a content export, a database dump and a copy of the uploads folder. You’ll need them to recover, and to understand what happened.
  4. Scan, then remove the planted files and the extra accounts. Then assume you missed something.

But one thing decided the rest of this story: after a takeover like this, I could never be sure I’d found every backdoor. I could spend weeks hardening a PHP application on a host I no longer trusted. Or I could move the writing somewhere with nothing to break into.

The decision
#

A personal blog doesn’t need a database, a login page or plugins. It needs pages. A static site generator turns Markdown into plain HTML files, and a static host serves them. There’s no server-side code left to exploit.

So the plan became:

BeforeAfter
WordPress + PHP + MySQL on shared hostingHugo building plain HTML
Plugins for everythingA theme (Blowfish) and a few small templates
Edit in a browserWrite Markdown, commit to git
Host serves PHPGitHub Pages serves files
DNS at the hostCloudflare

Lessons for me
#

  • My password was the weakest plugin. I’d reused it on a few unrelated sites. I never thought of that as connected to a blog until one of them, somewhere, leaked.
  • I wasn’t watching the signs. A burst of 141 failed logins in one hour, a week before the break-in, sat in a dashboard I never opened. The protection worked; I just never looked.
  • 27 plugins was 26 too many. Every one was code I didn’t read, running with full access. Half of them I couldn’t have named.
  • Backups saved me, by accident. The copy that rescued most of my images was one I’d forgotten I had.
  • “The host handles security” was an assumption, not a fact. I never asked what my plan actually included.

Tips for you
#

Five minutes today beats five weekends later.
  1. Turn on two-factor authentication for your email, your bank, and any site with an admin login. With 2FA, a leaked password alone isn’t enough.
  2. Use a password manager and a unique password per site. Reuse is how one company’s breach becomes yours. If a password ever leaks, change it everywhere it was used, email and finance first.
  3. Check haveibeenpwned.com for your email addresses. It’s free and takes a minute.
  4. Running WordPress? No user called admin; disable xmlrpc.php if you don’t post from apps; keep only the plugins you actually use; and look at your security plugin’s dashboard once a month.
  5. Ask your host what they actually protect, in writing: brute-force limits on login pages, PHP blocked in upload folders, automatic malware scans with alerts, notifications for new admin accounts. Whatever the answer is “no”, add yourself (a security plugin, a few server rules), choose a host that does it, or go static.
  6. If you’re hit: contain, preserve, then rebuild. Take the site offline, keep a copy of everything, change passwords, and rebuild somewhere clean rather than “cleaning” in place.

The hardest part wouldn’t be the new site. It would be getting six years of posts out of the old one intact. That’s part 2.

Author
Samarthya
Engineer, learner, tinkerer. This is my trophy shelf of everyday work and leisure.
Rebuilding samarthya.me - This article is part of a series.
Part 1: This Article

Related

A copy of the crime scene

·1 min
Took the first full copy of the old site’s database today. It was a strange thing to read. My own account was gone. Every post, all 207 of them, belonged to the attacker’s account, the one “registered” on 10 October 1970. 46 of my posts were sitting in drafts.

The blog went down

·1 min
The old WordPress blog was compromised today. Someone got in, left files behind that had no business being there, and the site stopped being something I could trust. First moves: take it offline, change every password that touched it, and keep a copy of everything for later. Six years of posts were in there. Tomorrow’s problem is what can be saved.

The defences went off

Written on 26 October from the old site’s own records. At the time, I didn’t know any of this. Just after midnight (UTC), an administrator account “registered in 1970” logged in. A minute later, 20 plugins were switched off in the same second, including the one that blocks password guessing.