Attorney-Client Privilege and Cybersecurity: What’s Changed and How to Adapt

What does the recent Eastern District of Virginia decision mean for your company when you need incident response services?

What would have been a fairly straightforward question changed on May 26, 2020, with a court order issued in the Eastern District of Virginia?

The Interpretation of Attorney-Client Privilege in Cybersecurity Is Changing

In response to a March 2019 data breach, the breached company, which had an existing IR retainer with an incident response firm, decided to hire outside counsel. Outside counsel then executed a contract with the same IR vendor to conduct incident response services.

This had been standard practice for years. Until this ruling, in working with outside counsel, the report and all other work product would have been protected by the attorney-client privilege. However, the court ruled that the report must be disclosed. Prior to this decision, this was unheard of.

IR Reports Must Be Prepared in Response to Litigation for Privilege to Apply

From the ruling, the deciding issue was “whether the [IR company’s] report would have been prepared in substantially similar form but for the prospect of that litigation.” The court clarified its reasoning, stating that in order to receive protection under the work product doctrine, “the material must be prepared because of the prospect of litigation.”

While this was clearly the case, the court took the unusual position that this particular work would have been done in the ordinary course of business regardless of the prospect of litigation and was therefore not covered.

Existing Incident Response Engagements May Prohibit Attorney-Client Privilege

The published opinion indicates that the court weighed a number of factors in making that determination. Chief among these was an existing Master Service Agreement (MSA) the company had with the same IR vendor. The existing MSA dated back to 2015 and was supplemented with ongoing statements of work for similar services performed.

Pending appeal of this decision, this leaves companies who need incident response services in an awkward position.

Many Companies Have Long-Standing Incident Response Contracts

Companies that use incident response services often develop long-standing relationships with one or more IR firms. In some cases, cyber breach insurance companies demand it.

There is also an economic incentive for this kind of relationship as the IR firm learns the details of the company and can provide better service since it is familiar with the company’s environment. This decision, if upheld, would stand those established relationships on end.

It would also create a perverse incentive for the company to hire a separate IR firm through outside counsel to react to the most critical breaches where time is of the essence.

How Should You Adapt Your Incident Response Strategy?

So what can you do to limit the impact of the decision until the appeal is resolved? Below are some key items to ensure you work into your strategy.

Engage Outside Firms

In the event of a cyberattack or data breach, engage with outside counsel or forensic investigators, even when there is an existing relationship between your company and the forensics firm(s).

Clearly Delineate Separate IR Engagements

Make it clear internally that outside counsel is directing the incident response engagement and that such investigations are being conducted separately from any pre-existing cyber consulting activities with the forensic firm(s).

Ensure that it is clear in the Statement of Work for the specific engagement that the report is being prepared with the prospect of litigation in mind.

Employ the Principle of Least Privilege

The more widely the forensic report is distributed, the more likely it becomes that the court will not provide attorney work-product protection. The principle of least privilege (PoLP) can help safeguard against this.

The forensic firm should only share the report with those for whom access is necessary. In most cases, this means outside counsel. Outside counsel can then share the report with your company at their discretion.

Review the Contracts of Any Existing Relationships

If there is one overarching MSA, consider rewriting the MSA into separate agreements for consulting services and incident response services.

Ensure agreements covering the provision of such services make explicit that incident response services will be covered by an independent, unrelated agreement.

As part of this, ensure that the billing for the work is expressly billed as a legal expense.

Rely on Facts, Not Opinions

Ensure that the forensic firm writes a fact-based – not opinion-based – report for distribution from counsel to the company.

While it may well be necessary for the forensics firm to provide opinions, speculation, background, and technical explanation to provide the best advice to the company, those opinions should not be in the final report.

Create an attorney report separate from the client report to make clear that this work was done with the intent to prepare for litigation.

Exploiting Kaseya Unitrends Backup Appliance – Part 1

Multiple vulnerabilities were discovered in the Unitrends Backup appliance and client software. An attacker with network access to the management interface or backup ports on the client or server could be exploited to compromise the machine. Both suffer from critical remote code execution vulnerabilities.

Continue reading

How To Reverse Engineer the SolarWinds Hack

Author: Quentin Rhoads-Herrera, Director of Professional Services

When it comes to security incidents involving malware, most of us rely on the information provided by the investigating firm to understand what the malware does, why it does it, and how to find it in our own environment. However, if you are interested in more in-depth details like us, you also want to know how to find that data for yourself.

With that in mind, Charles Dardaman, a Senior Adversarial Engineer of TEAMARES, and I have outlined the basic steps you can use to reverse engineer malware by showing you how it can be done on currently the biggest malware topic in the industry, the SolarWinds backdoor.

How It’s Done:

When looking at any form of malware, you first want to investigate its starting point, including what first landed on disk, memory, or in someone’s inbox that led to the rest of the compromise. In this case, that was the SolarWinds Orion DLL backdoor named SolarWinds.Orion.Core.BusinessLayer.DLL (b91ce2fa41029f6955bff20079468448), also called the SUNBURST Backdoor by many. For our sake, we used the excellent writeup provided by FireEye.

The first task a reverse engineer needs to do is to determine the type of binary or file they are working with. Luckily for us, the SUNBURST DLL is a .NET library so we can leverage several different tools to reverse out the contents of the .NET assembly to as close to the original source code as possible. The tool we used in this walkthrough is dotPeek from JetBrains.

When you initially load the SUNBURST DLL into the dotPeek application, it displays some basic information along with metadata, references, and classes as seen in the below screenshot.

Figure 1: SUNBURST DLL in dotPeek

With this now loaded, we can do a few different things; we can either export it to a Visual Studio project or just directly navigate the decompiled code through the dotPeek application.

If you wish to export for the simplicity of using grep or other command-line tools, either right-click the imported DLL or highlight it on the assembly explorer toolbar and select the icon with Visual Studio on it. This will export the whole DLL into a Visual Studio project folder and convert these different classes into .cs files.

Figure 2: Export function on Visual Studio project

Moving on to the backdoor discovered by FireEye and others working on the SolarWinds investigation. FireEye stated that the malware resided in the class SolarWinds.Orion.Core.BusinessLayer.OrionImprovementBusinessLayer, which you should be able to find that class if you extend the SolarWinds.Orion.Core.BusinessLayer section in dotPeek.

Figure 3: Finding the backdoor class in dotPeek

Double-clicking the backdoor class will cause dotPeek to decompile the source as closely as possible to its original value. Keep in mind that it will not be a one-for-one translation, but you will still have enough data to continue your investigation.

If you are like us, you will want to comment in-line on any code that looks malicious, or suspicious, but dotPeek does not give you that ability, unfortunately. You can however copy all of the decompiled code and save it to a new file with the .cs extension.

With the decompiled code, it’s easy to begin to get a handle on what it is doing. To start with, we can see a large number of obfuscated strings that appear to be base64 encoded.

In order to know the value of these strings, you can jump down to the Unzip method shown below to look at the try-catch block.

As you can see, the Unzip function is converting from base64, decompressing (by deflating the data), and then encoding it into UTF-8. With this knowledge in hand, we can either write a quick script to deobfuscate this data or just throw it into CyberChef here.

The tool easily decodes the strings and you can now have a better idea of what the malicious code is attempting to do. By deobfuscating all the encoded strings inside the malware, you can already see the points called out by FireEye, including the domain that the malware phones home to.

With this extra data, you can now investigate the core functionality of the malware. In this case, we navigated to the Initialize() function which is used to start the malware by doing a number of checks and tricks in order to bypass sandboxes while not running on every machine.

To start, the malware will verify that its process name is “solarwinds.businesslayerhost” by hashing the lowercase name of the process and comparing it with the hardcoded hash. It will then only execute if the file write time was roughly two weeks prior. It does this because sandboxes have a significantly shorter runtime and the malicious code will not run inside of the sandbox. This can give people a false sense of security if they never dig any further.

The malware will then create a named pipe in order to ensure that it doesn’t run multiple instances.

After which, it will read the configuration file by the same name in the folder. As long as the number is either a 4 or 5 and not a 3, it will continue to run.

To see how that works, you can jump down to the ReadReportStatus() method and take note of which report status is being returned and how the Initiate() function is looking for the return value of Truncate or 3 in order to fail.

The malware then gets its domain name.

And creates a UserID based on the machine’s network interface, the domain name, and the GUID.

Now that we know the checks the malware will do before it runs, you can look for some other interesting functionalities. One thing that we like to look for is what kinds of jobs or commands the malware might be able to act upon.

In this sample, we can easily see what the malware is capable of by looking at the JobEngine.

From here, it’s easy to find the corresponding function and understand exactly how it works, such as jumping to ReadRegistryValue as shown below.

Understanding the malware’s capabilities is obviously very important, but we also want to discern how it communicates with the attacker’s Command and Control (C2). For this, you can look at the update function that is the main loop inside of the malware. This logic shows the malware creating a cryptoHelper object which it then uses to generate the DNS domains it reaches out to.

The UpdateNotification() below is called to validate that the malware has an Internet connection by checking if it can reach api.solarwinds.com.

While checking the Internet connection, it will call the TrackProcesses() function which contains a long list of AV/EDR tools to avoid. You can then dig further into it by brute-forcing the hashes that it compares with.

With these blocklists passed, the malware will reach out to the partially randomized domain and check-in with the C2 by starting a thread to handle the communication and job requests that the C2 responds with.

You can then follow this to the http.Initialize function that builds the JSON payload and acts on any job that might be received from the C2 server. Inside this function, we noticed a CreateUploadRequest that creates the actual JSON request sent to the server. Partway down the code where we commented, the json that it uses for the request is visible.

Even further down the http.Initalize function, you can see where the malware parses the response from the C2 server and acts on any jobs passed down to it.

While there is a lot more functionality to this malware, we hope this basic reverse engineering overview and examples can help you get started reversing the binaries. These techniques are not unique to this sample and can be used with other malware.

About the Author: 

Quentin Rhodes-Herrera, Cyber One’s director of professional services, leads the offensive and defensive teams known as TEAMARES. He is an experienced security professional with expertise in security analysis, physical security, risk assessment, and penetration testing. Quentin’s diverse background is built from a variety of staff and leadership positions in IT, with specific experience in threat and vulnerability management, penetration testing, network operations, process improvement, standards development, and interoperability testing. Follow him on Twitter at @paragonsec.

References and links: