id: CVE-2026-22200

info:
  name: osTicket - Arbitrary File Read
  author: DhiyaneshDk
  severity: high
  description: |
    Enhancesoft osTicket versions 1.18.x prior to 1.18.3 and 1.17.x prior to 1.17.7 contain an arbitrary file read vulnerability in the ticket PDF export functionality. A remote attacker can submit a ticket containing crafted rich-text HTML that includes PHP filter expressions which are insufficiently sanitized before being processed by the mPDF PDF generator during export. When the attacker exports the ticket to PDF, the generated PDF can embed the contents of attacker-selected files from the server filesystem as bitmap images, allowing disclosure of sensitive local files in the context of the osTicket application user. This issue is exploitable in default configurations where guests may create tickets and access ticket status, or where self-registration is enabled.
  impact: |
    Remote attackers can read sensitive local files, leading to information disclosure within the osTicket application context.
  remediation: |
    Update to a version later than 1.18.2 or the latest available version.
  reference:
    - https://horizon3.ai/attack-research/attack-blogs/ticket-to-shell-exploiting-php-filters-and-cnext-in-osticket-cve-2026-22200/
    - https://github.com/horizon3ai/CVE-2026-22200/blob/main/check.py
    - https://nvd.nist.gov/vuln/detail/CVE-2026-22200
  classification:
    cve-id: CVE-2026-22200
    epss-score: 0.73125
    epss-percentile: 0.99384
    cwe-id: CWE-74
  metadata:
    verified: true
    max-request: 2
    vendor: osticket
    product: osticket
    shodan-query: html:"osTicket"
  tags: cve,cve2026,osticket,lfi,passive

flow: http(1) && http(2)

http:
  - raw:
      - |
        GET /open.php HTTP/1.1
        Host: {{Hostname}}

    extractors:
      - type: regex
        name: topic_id
        regex:
          - (?is)<option[^>]*\bvalue=["'](\d+)["'][^>]*>\s*([^<]+)\s*</option>
          - (?is)\bname=["']topicId["'][^>]*\bvalue=["'](\d+)["']
        group: 1
        internal: true

      - type: regex
        name: csrf_token
        regex:
          - name=["\']__CSRFToken__["\'][^>]*value=["\']([^"\']+)["\']
          - name=["\']csrf_token["\'][^>]*value=["\']([^"\']+)["\']
          - <input[^>]*type=["\']hidden["\'][^>]*name=["\'][^"\']*token[^"\']*["\'][^>]*value=["\']([^"\']+)["\']
        group: 1
        internal: true

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

        a=open&subject=Test+Ticket+Submission&message=%3Cimg+src%3D%22doesnotexist.jpg%22+srcset%3D%22http%3A%2F%2FPATCH_DETECT_7f3a9b2e.example.com%2Fimage-400.jpg+400w%2C+http%3A%2F%2FPATCH_DETECT_7f3a9b2e.example.com%2Fimage-800.jpg+800w%2C+http%3A%2F%2FPATCH_DETECT_7f3a9b2e.example.com%2Fimage-1200.jpg+1200w%2C+http%3A%2F%2FPATCH_DETECT_7f3a9b2e.example.com%2Fimage-1600.jpg+1600w%22+alt%3D%22Office+landscape%22+width%3D%22800%22+height%3D%22600%22+data-image%3D%22vgmd0ykzb2uq%22%3E&name=Test+User&__CSRFToken__={{csrf_token}}&topicId={{topic_id}}

    matchers:
      - type: dsl
        dsl:
          - status_code == 200
          - contains_all(body, 'srcset','http://PATCH_DETECT_7f3a9b2e.example.com')
        condition: and
# digest: 4a0a00473045022100a40cec589e833ca45ca64ae12436502e57f73848ee04f759b64216e4908f192a022002092b9452070099d32d42725d98630149a52e4ad648efb2744d481b34bc0eca:922c64590222798bb761d5b6d8e72950