Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/auxiliary/scanner/oracle/sid_brute.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::TNS7include Msf::Auxiliary::Report8include Msf::Auxiliary::Scanner9include Msf::Auxiliary::AuthBrute # Actually, doesn't use much here, but there's a couple handy functions.1011def initialize(info = {})12super(update_info(info,13'Name' => 'Oracle TNS Listener SID Bruteforce',14'Description' => %q{15This module queries the TNS listener for a valid Oracle database16instance name (also known as a SID).17Any response other than a "reject" will be considered a success.18If a specific SID is provided, that SID will be attempted. Otherwise,19SIDs read from the named file will be attempted in sequence instead.20},21'Author' => [ 'todb' ],22'License' => MSF_LICENSE23))2425register_options(26[27OptPath.new('SID_FILE', [ false, "File containing instance names, one per line", File.join(Msf::Config.data_directory, "wordlists", "sid.txt") ]),28OptString.new('SID', [ false, 'A specific SID to attempt.' ]),29Opt::RPORT(1521)30])3132deregister_options(33"USERNAME", "PASSWORD", "USER_FILE", "PASS_FILE", "USERPASS_FILE",34"BLANK_PASSWORDS", "USER_AS_PASS", "REMOVE_USER_FILE", "REMOVE_PASS_FILE",35"REMOVE_USERPASS_FILE"36)37end3839def build_sid_request(sid,ip)40connect_data = "(DESCRIPTION=(CONNECT_DATA=(SID=#{sid})(CID=(PROGRAM=)(HOST=__jdbc__)(USER=)))(ADDRESS=(PROTOCOL=tcp)(HOST=#{ip})(PORT=#{rport})))"41pkt = tns_packet(connect_data)42end4344def hostport45[target_host,rport].join(":")46end4748def check_sid(sid,ip)49pkt = build_sid_request(sid,ip)50sock.put(pkt)51data = sock.get_once || ''52parse_response(data)53end5455def parse_response(data)56return unless data57len,sum,type,r,hsum,rest = data.unpack("nnCCnA*")58type # 2 is "accept", 11 is resend. Usually you get 11, then 2. 4 is refuse.59end6061def do_sid_check(sid,ip)62begin63connect64response_code = check_sid(sid,ip)65if response_code.nil?66print_status "#{hostport} Oracle - No response given, something is wrong."67return :abort68elsif response_code != 469print_good "#{hostport} Oracle - '#{sid}' is valid"70report_note(71:host => ip,72:proto => 'tcp',73:port => rport,74:sname => 'oracle',75:type => "oracle.sid",76:data => sid,77:update => :unique_data78)79return :success80else81vprint_status "#{hostport} Oracle - Refused '#{sid}'"82return :fail83end84rescue ::Rex::ConnectionError, ::Errno::EPIPE85print_error("#{hostport} Oracle - unable to connect to a TNS listener")86return :abort87ensure88disconnect89end90end9192# Based vaguely on each_user_pass in AuthBrute93def each_sid(&block)94@@oracle_sid_fail = []95@@oracle_sid_success = []96if datastore['SID'].nil? || datastore['SID'].empty?97sids = extract_words(datastore['SID_FILE']).map {|s| s.to_s.strip.upcase}.uniq98else99sids = [datastore['SID'].to_s.strip.upcase]100end101print_status "Checking #{sids.size} SID#{sids.size != 1 && "s"} against #{hostport}"102sids.each do |s|103userpass_sleep_interval unless (@@oracle_sid_fail | @@oracle_sid_success).empty?104next if @@oracle_sid_fail.include?(s) || @@oracle_sid_success.include?(s)105ret = block.call(s)106case ret107when :abort108break109when :success110@@oracle_sid_success << s111break if datastore["STOP_ON_SUCCESS"]112when :fail113@@oracle_sid_fail << s114end115end116end117118def run_host(ip)119each_sid do |sid|120vprint_status "#{hostport} Oracle - Checking '#{sid}'..."121do_sid_check(sid,ip)122end123end124end125126127