Our site was compromised through an SQL injection vulnerability in the Pools extension included with our Shimmie 2.11.0 installation. The vulnerable code was in ext/pools/main.php: a pool_id value extracted from the request path was interpolated into an SQL query without strict validation or parameterization.
The attackers used this flaw to read the booru database, obtain an administrator password hash, and gain administrative access. They then abused Shimmie's administrative setup and upload functionality to place a PHP webshell under data/. That webshell executed as the web server user and was used to install a recurring cron job that opened a reverse shell. Because our applications were insufficiently isolated, this account could reach the imageboard, booru, and wiki databases. The attackers subsequently modified or deleted boards, posts, users, booru content, and wiki data.
We found no evidence of root SSH compromise. The intrusion remained within the web application and its service account, but that account had access to more of the server than it should have.
We have taken the following steps:
- Removed the webshell, reverse-shell cron job, and associated processes.
- Restored the databases and media from the latest clean backup.
- Patched the Pools extension to accept only numeric pool IDs and cast them before database use.
- Rotated database credentials, application secrets, administrator credentials, and session keys.
- Invalidated existing login sessions.
- Placed the imageboard, booru, and wiki in separate PHP-FPM pools running as different Unix users.
- Restricted each application's access to the other applications' files and configuration.
- Added firewall blocks and monitoring for the infrastructure observed during the incident.
- Updated PHP and the database server to security-supported vendor packages.
Operators running Shimmie—especially Shimmie 2.11.0 with the Pools extension enabled—should inspect ext/pools/main.php for SQL queries constructed from request-path pool_id values. Enforce a numeric format, cast the value to an integer, and preferably use parameterized queries. You should also inspect writable directories such as data/ for unexpected PHP files, review the web server user's crontab, check outbound connections, rotate credentials, and isolate separate web applications under different service accounts.
Password hashes and other stored account information may have been exposed. Users should change any password they reused on another service. Some content created after our latest clean backup could not be recovered.