Summary
From a 2008 Web Server to Every Customer Record: How One Upload Took Down an Entire Hosting Business A walkthrough of a full-scope penetration test against a small business that thought its old but secure setup was fine. All sensitive details redacted with client permission. The engagement took under two days. The compromise took twenty minutes. The Target A small computer-repair business in Western Canada. Ten years of customer trust. One website that handles repair requests, data-recovery quotes, and job applications. A couple of other domains hosted on the same box — because why pay for separate hosting when one machine can do it all? The client authorized full-scope testing with one caveat: “we don’t really have anything sensitive on there.” Spoiler: they did. Recon: The First Red Flag Is Free Every engagement starts the same way — passive enumeration. Subdomain discovery, certificate transparency logs, Wayback Machine scraping, JavaScript extraction. All standard tools: amass , subfinder , assetfinder , gau , waybackurls . Nothing exotic came back. Five subdomains. Mail records. A remote-support link. A Joomla site. Then the first request hit the server, and the response headers told a story: Server: Apache/2.2.8 (Win32) DAV/2 mod_ssl/2.2.8 OpenSSL/0.9.8g mod_autoindex_color PHP/5.2.5 X-Powered-By: PHP/5.2.5 For the non-nerds: Apache 2.2.8 was released in January 2008. PHP 5.2.5 in November 2007. The server was a teenager. TLS 1.0 only. On Windows. But old software alone isn’t a vulnerability — a lesson this test hammered home repeatedly. So we started testing, not assuming. Mapping the Attack Surface The site ran Joomla 1.5 — end-of-life since 2012. Two third-party components stood out in the URL corpus:
- ArtForms — a form builder handling repair requests, employment applications, and data-recovery quotes
- com_poll — a poll The Joomla 1.5 core SQL injection that mass-exploited thousands of sites in 2012? Tested it properly — boolean differentials, time-based probes with SLEEP(5) , sqlmap. The id parameter was integer-cast. Dead. A good reminder: old version is a lead, never a finding. We also confirmed reflected XSS in the ArtForms form fields — payloads came back raw in the HTML, and the site’s WAF blocked
- Old but secure is a contradiction you can’t audit your way out of. The stack was old, the credentials reused, the backups exposed, the upload filter broken. Any one of these is survivable. All of them together is not.
- Your browser is not an identity provider. MIME-type filtering on uploads is theatre. Validate extensions server-side, rewrite filenames, store uploads outside the web root, disable script execution in upload directories — all four, or don’t accept uploads.
- You have more sensitive data than you think. Every form submission, every old backup, every config file. If a customer typed it into your website, an attacker can probably read it.
- Assume a previous compromise. The rogue admin account sat there for eight years. If you don’t audit your own user tables, someone else will.
- Hire testers who prove, not assert. Every finding in this engagement was demonstrated with a working request, not a version number. Old software gets you a conversation; a working upload gets you a fix. Timeline
- Day 1, hour 1: Recon complete; ancient stack fingerprinted
- Day 1, hour 2: SQLi leads tested and eliminated; XSS confirmed
- Day 1, hour 3: MIME filter bypass identified
- Day 1, hour 4: RCE achieved; database credentials extracted
- Day 2: Full post-exploitation: 8 DBs, customer PII, backups, credentials, remote-access identity
- Day 2, end: Complete evidence package delivered to client; all test artifacts removed Toolbox
- Recon: amass ,subfinder ,assetfinder ,gau ,waybackurls ,curl
- Vulnerability discovery: manual parameter testing, sqlmap ,nuclei ,dalfox ,ffuf
- Exploitation: hand-crafted curl requests, custom PHP payloads - Post-exploitation: PHP-based file/DB access, john /hashcat for hash cracking,hydra for credential verification - Reporting: every finding with reproduction steps and raw evidence This engagement was performed with full authorization from the system owner. All credentials, customer data, IP addresses, and identifying details have been redacted. If you run a small business and haven’t had a test like this, the cheapest way to find out what your server is worth to an attacker is to ask someone to look at it before they ask you to look at the bill.