Today, Karim El Ouerghemmi discloses a critical WordPress vulnerability allowing any author, editor, administrator to delete any file of the installation, in any folder, without any tool.
In less than 1 minute, a website can be gone. The flaw is known from WordPress Core Security Team since about 7 months but still no patch has been released, this is why Karim disclosed it.
Why disclose this if it’s critical!?
The answer is in the question: because it’s critical and if a security researcher could find it, a hack could find it too. We (me, you) have to spread the world about the vulnerability to show everyone how easy is it to hack a WordPress website if you have any author/editor/administrator (other than you) on your website.
Where is the flaw?
The function wp_delete_attachment()
is guilty here:
[pastacode lang=”php” manual=”function%20wp_delete_attachment(%20%24post_id%2C%20%24force_delete%20%3D%20false%20)%20%7B%0A%09%E2%8B%AE%0A%09%24meta%20%3D%20wp_get_attachment_metadata(%20%24post_id%20)%3B%0A%09%E2%8B%AE%0A%09if%20(%20!%20empty(%24meta%5B’thumb’%5D)%20)%20%7B%0A%09%09%2F%2F%20Don’t%20delete%20the%20thumb%20if%20another%20attachment%20uses%20it.%0A%09%09if%20(!%20%24wpdb-%3Eget_row(%20%24wpdb-%3Eprepare(%20%22SELECT%20meta_id%20FROM%20%24wpdb-%3Epostmeta%20WHERE%20meta_key%20%3D%20’_wp_attachment_metadata’%20AND%20meta_value%20LIKE%20%25s%20AND%20post_id%20%3C%3E%20%25d%22%2C%20’%25’%20.%20%24wpdb-%3Eesc_like(%20%24meta%5B’thumb’%5D%20)%20.%20’%25’%2C%20%24post_id))%20)%20%7B%0A%09%09%09%24thumbfile%20%3D%20str_replace(basename(%24file)%2C%20%24meta%5B’thumb’%5D%2C%20%24file)%3B%0A%09%09%09%2F**%20This%20filter%20is%20documented%20in%20wp-includes%2Ffunctions.php%20*%2F%0A%09%09%09%24thumbfile%20%3D%20apply_filters(%20’wp_delete_file’%2C%20%24thumbfile%20)%3B%0A%09%09%09%40%20unlink(%20path_join(%24uploadpath%5B’basedir’%5D%2C%20%24thumbfile)%20)%3B%0A%09%09%7D%0A%09%7D%0A%09%E2%8B%AE%0A%7D” message=”” highlight=”11″ provider=”manual”/]
The unlink()
statement will delete the file contained in the media’s metadata named thumb
. But, how is this meta filled? Let’s see that in /wp-admin/post.php
:
[pastacode lang=”php” manual=”%E2%8B%AE%0Aswitch(%24action)%20%7B%0A%E2%8B%AE%0A%09case%20’editattachment’%3A%0A%09%09check_admin_referer(‘update-post_’%20.%20%24post_id)%3B%0A%09%09%E2%8B%AE%0A%09%09%2F%2F%20Update%20the%20thumbnail%20filename%0A%09%09%24newmeta%20%3D%20wp_get_attachment_metadata(%20%24post_id%2C%20true%20)%3B%0A%09%09%24newmeta%5B’thumb’%5D%20%3D%20%24_POST%5B’thumb’%5D%3B%0A%0A%09%09wp_update_attachment_metadata(%20%24post_id%2C%20%24newmeta%20)%3B%0A%E2%8B%AE” message=”” highlight=”9,11″ provider=”manual”/]
The metadata is just the raw value of the user’s input from a form, no sanitization, no filter, no escaping, nothing.
Is it exploitable yet? Easily?
Sadly yes, in less than 1 minute an author can delete any file from the website like wp-config.php
(one of the worst right?) but also an attacker could remove the main file of a security plugin to prevent it to be loaded, and then, perform deepest and more discreet attacks, because let’s say it, breaking a website as a hacker doesn’t worth it most of the time, defacing is a thing, stealing data is a thing, breaking is not.
Let’s see that in a 55 sec video:
You may already saw a video of the exploit, using the JavaScript console to inject hexadecimal code leading to create and call new JS functions and calling a new AJAX url, etc, WAY TOO MUCH, you only have to change 2 values + a last one for the file path you want to delete, that’s it.
How can I secure my website now?
If you’re already using SecuPress (free or pro version) 1.4.5.1 of more, your website is already secure because we included the following hotfix from Karim (with another function name to prevent duplicate names):
[pastacode lang=”php” manual=”add_filter(%20’wp_update_attachment_metadata’%2C%20’rips_unlink_tempfix’%20)%3B%0A%0Afunction%20rips_unlink_tempfix(%20%24data%20)%20%7B%0A%20%20%20%20if(%20isset(%24data%5B’thumb’%5D)%20)%20%7B%0A%20%20%20%20%20%20%20%20%24data%5B’thumb’%5D%20%3D%20basename(%24data%5B’thumb’%5D)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20return%20%24data%3B%0A%7D” message=”” highlight=”” provider=”manual”/]
Install SecuPress now and secure your website in a minute!