Home » wordpress plugin » Page 10

Tag: wordpress plugin

Tweet Wheel 0.3 Security Vulnerability

I was looking for a WordPress plugin that would add some Twitter functionality to my website last week. I ran across Tweet Wheel from Nerd Cow (awesome name BTW!)

I personally can’t use a plugin that I haven’t at least done a quick inspection on the code so I took a look and saw a minor AJAX issue. One that wouldn’t even stop me from using the code unfixed in this specific case, because nobody besides me has access to the site.

Props to Thomasz Lisiecki for taking security seriously and getting an updated version out right away, even on such a minor issue. Changelog posted here

tweetwheel-ajax

Fortunately, none of the actions are ‘nopriv’ so you at least require a valid WordPress user account to use the functionality.

tweetwheel-ajaxtweet

Of all of the actions, this was the worst and it is pretty minor. The result would just be spamming Twitter with the same tweets over and over. Without further access you can’t even adjust what the Tweet says.

Timeline

  • 3/1/2015 11:43am Initial disclosure email sent
  • 3/1/2015 11:46am Reply received
  • 3/4/2015 Plugin updated on wordpress.org

IgnitionDeck 1.1.6 Vulnerability

Yesterday I noticed this tweet from IgnitionDeck ignitiontweet

I’d never heard of them before so I decided to take a quick look at their page and see what code was available to look at. They have several paid plugins but also a free plugin on wordpress.org.

I spent a couple minutes looking at the code while I was eating breakfast. Right away I noticed a couple of issues and sent off an email. They were quick to respond and within a few hours had released an update version.

Analysis

One of the first things I search for is AJAX handlers, often developers forget to verify if the user is actually allowed to do the action especially if the page that links to the action is behind an admin interface that requires a login.

Here a simple POST lets an un-authenticated user change the active theme.

ignitiontheme

This one lets an un-authenticated user activate an installed plugin. Right away I thought some directory traversal would be fun, but since the same variable is used for the directory and filename it won’t work.

ignitionextension

Next up I noticed a function that runs during the ‘init’ action that acts on user input.

ignitionaddmedia

If ‘create_project’ or ‘edit_project’ are passed as GET variables or in the HTTP_REFERER then idc_add_upload_cap is called. This would of course require the user to be logged in.

ignitionuploadcap

Look at all those fun capabilities we’ve got now. The capabilities will be removed by the idc_remove_upload_cap() function call if the variables aren’t passed.

 
Please developers, trust but verify!

WP All Import 3.2.3 (Pro 4.0.3) Vulnerability Breakdown

The continuing saga of the WP All Import Vulnerability

I wanted to give enough time for everyone to update before releasing more information about this vulnerability. According to the newly updated WordPress plugin repository, the WP All Import free version has 20,000+ active installs. The code is out there so anyone would be able to figure out what the big deal is.  I won’t distribute my exploit code, so please stop asking!

I will be referencing version 3.2.3 of the free plugin in this post, if you are looking at the paid version the line numbers and filenames might be different.

There were two distinct vulnerabilities for getting access to the plugin and they have been exploited time and time again so I won’t spend time covering them.

First off are ajax requests that don’t verify the user has permissions, in this case they are not the ‘ajax_nopriv’ type so you at least need to have an account on the system to use them, but even the lowest account would work.

The second type is assuming that the ‘admin_init’ action only happens for admins. Which isn’t the case, it is called for any action that starts up the admin interface. Which could be the user profile editor or the AJAX interface.
admininit1

“If this isn’t Nice, What Is?”

So now that we’re behind enemy lines without permission, what can we do?

  • Retrieve any file on the system that ends in .txt
  • Retrieve any file on the system that ends in .html
  • Retrieve any value from the postmeta table
  • Upload arbitrary files to system

Once I have the keys to the kingdom I stop looking for unlocked windows.  There were likely other things you could do, but once you’ve got full access to the system who cares?

“Trust thyself only, and another shall not betray thee”

admininit2
The helpful function $input->getpost(‘page’, ”)) here takes the ‘page’ variable from a HTTP POST and sticks it in $page. If page starts with ‘pmxi_’ then we keep on rolling and set $action to HTTP POST ‘action’.

admininit3Now we’re cooking.  We can arbitrarily call any class that is an instanceof PMXI_Controller_Admin and starts with ‘pmxi_’ (there are 8 of them).

Find your favorite function and work with it, I’m sure you will find something fun.  When you find one that lets you transfer a file into uploads you’re starting to see the light at the end of the tunnel.

Of course, someone was trying to keep people from guessing the location (or maybe just trying to keep from overwriting previous uploads). So there is a function to return a ‘secure’ directory/file.

securefileLooks good, right? Just last week Securi wrote an advisory about another plugin that used md5( time() ) to generate a ‘secret’ key. In this case the naming happens at time of upload and the HTTP Protocol happily returns a timestamp, so you have a pretty small window to search for the ‘secret’ directory.

“You keep using that word. I do not think it means what you think it means.”

So we’ve now managed to upload a file to a ‘secret’ directory. In my experience most systems will happily execute php code from the ‘wp-content/uploads’ directory, so now we can run whatever code we want. My example just ran phpinfo() and exited, but I don’t think the next guy will be quite as nice.

Lessons Learned

  • “Always… no, no… never… forget to check your references.”
  • Set your uploads directory to not execute php, cgi, or any other handlers
  • Disable indexes on uploads directory (not an issue here because it creates an index.php, but to be continued in another post)
  • Keep your plugins updated!
  • If you are a plugin developer, think like an attacker!

I tested the updates to WP All Import and WP All Import Pro and could no longer have fun inside the code base.  A few simple lines of code fixed these major vulnerabilities.

Update