CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/scanner/oracle/sid_brute.rb
Views: 11784
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Auxiliary
7
include Msf::Exploit::Remote::TNS
8
include Msf::Auxiliary::Report
9
include Msf::Auxiliary::Scanner
10
include Msf::Auxiliary::AuthBrute # Actually, doesn't use much here, but there's a couple handy functions.
11
12
def initialize(info = {})
13
super(update_info(info,
14
'Name' => 'Oracle TNS Listener SID Bruteforce',
15
'Description' => %q{
16
This module queries the TNS listener for a valid Oracle database
17
instance name (also known as a SID).
18
Any response other than a "reject" will be considered a success.
19
If a specific SID is provided, that SID will be attempted. Otherwise,
20
SIDs read from the named file will be attempted in sequence instead.
21
},
22
'Author' => [ 'todb' ],
23
'License' => MSF_LICENSE
24
))
25
26
register_options(
27
[
28
OptPath.new('SID_FILE', [ false, "File containing instance names, one per line", File.join(Msf::Config.data_directory, "wordlists", "sid.txt") ]),
29
OptString.new('SID', [ false, 'A specific SID to attempt.' ]),
30
Opt::RPORT(1521)
31
])
32
33
deregister_options(
34
"USERNAME", "PASSWORD", "USER_FILE", "PASS_FILE", "USERPASS_FILE",
35
"BLANK_PASSWORDS", "USER_AS_PASS", "REMOVE_USER_FILE", "REMOVE_PASS_FILE",
36
"REMOVE_USERPASS_FILE"
37
)
38
end
39
40
def build_sid_request(sid,ip)
41
connect_data = "(DESCRIPTION=(CONNECT_DATA=(SID=#{sid})(CID=(PROGRAM=)(HOST=__jdbc__)(USER=)))(ADDRESS=(PROTOCOL=tcp)(HOST=#{ip})(PORT=#{rport})))"
42
pkt = tns_packet(connect_data)
43
end
44
45
def hostport
46
[target_host,rport].join(":")
47
end
48
49
def check_sid(sid,ip)
50
pkt = build_sid_request(sid,ip)
51
sock.put(pkt)
52
data = sock.get_once || ''
53
parse_response(data)
54
end
55
56
def parse_response(data)
57
return unless data
58
len,sum,type,r,hsum,rest = data.unpack("nnCCnA*")
59
type # 2 is "accept", 11 is resend. Usually you get 11, then 2. 4 is refuse.
60
end
61
62
def do_sid_check(sid,ip)
63
begin
64
connect
65
response_code = check_sid(sid,ip)
66
if response_code.nil?
67
print_status "#{hostport} Oracle - No response given, something is wrong."
68
return :abort
69
elsif response_code != 4
70
print_good "#{hostport} Oracle - '#{sid}' is valid"
71
report_note(
72
:host => ip,
73
:proto => 'tcp',
74
:port => rport,
75
:sname => 'oracle',
76
:type => "oracle.sid",
77
:data => sid,
78
:update => :unique_data
79
)
80
return :success
81
else
82
vprint_status "#{hostport} Oracle - Refused '#{sid}'"
83
return :fail
84
end
85
rescue ::Rex::ConnectionError, ::Errno::EPIPE
86
print_error("#{hostport} Oracle - unable to connect to a TNS listener")
87
return :abort
88
ensure
89
disconnect
90
end
91
end
92
93
# Based vaguely on each_user_pass in AuthBrute
94
def each_sid(&block)
95
@@oracle_sid_fail = []
96
@@oracle_sid_success = []
97
if datastore['SID'].nil? || datastore['SID'].empty?
98
sids = extract_words(datastore['SID_FILE']).map {|s| s.to_s.strip.upcase}.uniq
99
else
100
sids = [datastore['SID'].to_s.strip.upcase]
101
end
102
print_status "Checking #{sids.size} SID#{sids.size != 1 && "s"} against #{hostport}"
103
sids.each do |s|
104
userpass_sleep_interval unless (@@oracle_sid_fail | @@oracle_sid_success).empty?
105
next if @@oracle_sid_fail.include?(s) || @@oracle_sid_success.include?(s)
106
ret = block.call(s)
107
case ret
108
when :abort
109
break
110
when :success
111
@@oracle_sid_success << s
112
break if datastore["STOP_ON_SUCCESS"]
113
when :fail
114
@@oracle_sid_fail << s
115
end
116
end
117
end
118
119
def run_host(ip)
120
each_sid do |sid|
121
vprint_status "#{hostport} Oracle - Checking '#{sid}'..."
122
do_sid_check(sid,ip)
123
end
124
end
125
end
126
127