• Skip to primary navigation
  • Skip to content
  • Skip to primary sidebar
  • Skip to footer

Sucuri Blog

Website Security News

  • Products
    • Website Security Platform
    • Website Firewall (WAF)
    • Enterprise Website Security
    • Multisite Solutions
  • Features
    • Detection
    • Protection
    • Performance
    • Response
    • Backups
  • Partners
    • Agency Solutions
    • Partners
    • Referral Program
    • Ecommerce
  • Resources
    • Guides
    • Webinars
    • Infographics
    • SiteCheck
    • Reports
    • Email Courses
  • Immediate Help
  • Login
WordPress Vulnerability Detail

SQL Injection in Duplicate-Page WordPress Plugin

April 5, 2019Marc-Alexandre Montpas

Security Risk: Easy / Remote

DREAD Score: 8.4

Vulnerability: SQL Injection / PHP Object Injection

Patched Version: 3.4

FacebookTwitterSubscribe

While investigating the Duplicate Page plugin, we have discovered a dangerous SQL Injection vulnerability.

Though the plugin wasn’t abused externally, the vulnerability impacted over 800,000 sites. Its urgency is defined by the associated DREAD score that looks at damage, reproducibility, exploitability, affected users, and discoverability.

Key contributors to the criticalness of this vulnerability are that it’s easy to exploit and by any user with an account on the vulnerable site (regardless of the privileges they have – e.g., subscribers).

Current State of the Vulnerability

Duplicate-Page, as its name implies, is a plugin that makes it easy to duplicate pages on a site.

The bug has been fixed on the 3.4 release. If you use an older version, you should update as soon as possible.

Successful exploitation of this bug may allow attackers to steal sensitive user information like password hashes and in certain scenarios, lead to a complete compromise of your WordPress installation. Depending on what other plugins are active on the site, bad actors may escalate this bug into a PHP Object Injection vulnerability.

Disclosure Timeline

  • March 22nd, 2019 – Attempt to contact the author
  • March 22nd, 2019 – Author answers, we disclose the vulnerability to them
  • March 25th, 2019 – Author sends the patch for review, which we do on the same day
  • April 1st, 2019 – Fix is available on wordpress.org

Technical Details

Duplicate-page WordPress plugin
Duplicate-page WordPress plugin

If activated, the Duplicate-Page plugin adds a new link to the Pages list options, named “Duplicate this”. A quick look at its destination URL shows that it points to http://[vulnerable ite]/wp-admin/admin.php?action=dt_duplicate_post_as_draft&post=[the post id].

The action parameter is generally used by the WordPress admin_action_ hook to determine what action hook to run, very similarly to how the wp_ajax_ hook works.

WordPress admin_action_ hook
WordPress admin_action_ hook

The admin_action_ hook is executed at the very end of wp-admin/admin.php. This file is included on practically all pages in /wp-admin/ that provides a user interface, including wp-admin/index.php. As a result, it may be executed when any kind of users are on their dashboard or even editing their personal information.

Plugins relying on this feature to perform strictly administrative tasks should always be doing additional privilege and nonce check in order to make sure it is not executed by less privileged malicious users.

Privilege and nonce check
Privilege and nonce check

With that in mind, let’s look at how the action hook is implemented. From the screenshot above, we understand that the method being hooked here is dt_duplicate_post_as_draft.

dt_duplicate_post_as_draft
dt_duplicate_post_as_draft

Investigating that method reveals a few interesting points:

  1. It doesn’t apply any privilege or nonce check.
  2. It can use either of $_GET[‘post’] or $_POST[‘post’] to grab the ID of the post we want to duplicate.
  3. The only check being applied is on get_post()’s return value. If it returned anything other than NULL, it is assumed that everything worked properly and we can continue the page duplication routine.
get_post()
get_post()

Unfortunately, get_post() internally uses the get_instance() method of the WP_Post class to find posts using their IDs, which as you may see from this snippet, casts $post_id to an integer before querying the database!

This means that no matter what $post_id contains, it will always retrieve a valid post if the variable starts with that post’s ID. For example: “123 hello world” would grab a post whose ID is 123.

If this technique sounds familiar to you, we used a very similar trick in the WordPress Content Injection vulnerability patched on version 4.7.2.

The dt_duplicate_post_as_draft method
The dt_duplicate_post_as_draft method

Continuing our analysis of the dt_duplicate_post_as_draft method, we see that $post_id is directly appended to the $wpdb->get_results() query. Since $post_id contains unsanitized user input, this leads to a SQL Injection vulnerability.

Looking even further, we also see that the values returned by this vulnerable query are reused in the foreach() loop and re-appended in the subsequent INSERT SQL query. Because we can control the $meta_key variable by using SQL UNION statements in the first vulnerable query and it is not escaped by addslashes(), we may inject arbitrary values in the postmeta table.

This is a huge deal since all of the post meta in there can be unserialized when retrieved using the get_post_meta() function, which would lead to a PHP Object Injection attack under certain circumstances.

In Conclusion

If you are using vulnerable versions of this plugin, updating it should become your priority. Users of the Sucuri Firewall were protected from these issues from the very beginning.

FacebookTwitterSubscribe

Categories: Vulnerability Disclosure, Website Malware Infections, WordPress SecurityTags: Hacked Websites, WordPress Plugins and Themes

About Marc-Alexandre Montpas

Marc-Alexandre Montpas is Sucuri’s Senior Security Analyst who joined the company in 2014. Marc’s main responsibilities include reversing security patches and scavenging vulnerabilities, old and new. His professional experience covers eight years of finding bugs in open-source software. When Marc isn’t breaking things, you might find him participating in a hacking CTF competition. Connect with him on Twitter.

Reader Interactions

Primary Sidebar

Socialize With Sucuri

We're actively engaged across multiple platforms. Follow us and let's connect!

  • Facebook
  • Twitter
  • LinkedIn
  • YouTube
  • Instagram
  • RSS Feed

Join Over 20,000 Subscribers!

Sucuri Sidebar Malware Removal to Signup Page

Footer

Products

  • Website Firewall
  • Website AntiVirus
  • Website Backups
  • WordPress Security
  • Enterprise Services

Solutions

  • DDos Protection
  • Malware Detection
  • Malware Removal
  • Malware Prevention
  • Blacklist Removal

Support

  • Blog
  • Knowledge Base
  • SiteCheck
  • Research Labs
  • FAQ

Company

  • About
  • Media
  • Events
  • Employment
  • Contact
  • Testimonials
  • Facebook
  • Twitter
  • LinkedIn
  • Instagram

Customer Login

Sucuri Home

  • Terms of Use
  • Privacy Policy
  • Frequently Asked Questions

© 2023 Sucuri Inc. All rights reserved

Sucuri Cookie Policy
See our policy>>

Our website uses cookies, which help us to improve our site and enables us to deliver the best possible service and customer experience.