Getting access to an internal network is always great, keeping this access can be a whole other challenge. At times we want to fly below the radar and ensure our access doesn’t get detected or blocked by traditional network based solutions. To this end, communicating directly through an Exchange server can be very beneficial and solve both challenges.
Ruler provides us with a means of getting a shell on an internal network. This is all done through Exchange and ensures our “trigger” for getting a shell back is usually only an email away. To a large degree this gives us the desired persistence we may want, however, we are still dependent on our traditional communication channels, be it DNS, HTTP(s) or TCP. This means our tools can need to traverse the traditional network boundary, aka, the web-gateway. Defenders place all their in-line defences here and should be able to detect and block our traffic. Exchange usually falls outside of this monitoring, as it should only be sending and receiving email. Sure there can be DLP and in-line scanning for malicious mail attachments, but this is usually aimed at the actual email messages. Do you have or have you seen in-line inspection of the Exchange/Outlook transport? Not the IMAP/SMTP traffic, the MAPI/HTTP or the RPC/HTTP channel that external Outlook clients use to communicate with the Exchange server. In my experience, the answer is usually no, there is no inspection of these transports.
Email in itself is a pretty good communication channel and will allow you to get away with establishing a low and slow communication channel. This has been proven by Immunity Inc with their Innuendo Outlook Channel (https://vimeo.com/album/3385044/video/110185867) As you’ll hear Dave say in the video, this gets through most Fortune50 companies. The only downside I can see (based on the video) is that emails are being sent, this means you’ve got messages arriving in the Inbox (see 3:14 where an email message is seen arriving and the notification is displayed to the user). Emails also leave the mailbox and get sent to an address under the attackers control, possibly giving you away if you set your control mailbox as email@example.com.
Can we extend the work that has already been done and make the Exchange channel more stealthy?
The Exchange server sits on the network boundary and can communicate internally and externally with Outlook clients. Emails can be created and stored on the Exchange server. There is no need for these emails to actually be sent if we have the ability to read these directly off of the Exchange server.
A nice feature provided by Exchange is the ability to create “hidden” folders. These folders do not show up in the Outlook UI or the OWA UI. Actually, they only show up if you know where to look for them programatically.
Could we create our control channel to work through one of these hidden folders? The idea being our Empire agent, running on the compromised host, creates a check-in message in the folder. Our channel manager then reads this message, converts it into a format that Empire understands (HTTP request) and forwards this to our Listener. The response is then read, and converted back into a mail message object and stored back into the hidden folder on Exchange.
This should provide a stable, low and slow channel that does not go over our traditional network boundary. And there are no emails that actually leave the network/Exchange server. On a network layer, all activity should appear to be Outlook synchronisation traffic. This has the added benefit of being wrapped in a protocol we know is allowed into/out-of the network. Futhermore, this has HTTPS and in the case of RPC/HTTP, NTLM encrypted data within HTTPS.
Extend the Ruler
What the development of Ruler led to was the creation of a pretty solid transport factory, meaning we can easily communicate with the Exchange server through MAPI/HTTP or RPC/HTTP, just as an Outlook client would. To extend what Ruler can do requires us to add a few additional MAPI Remote Operations and string together the logical order these should be used in.
Using the existing Ruler “library” I was able to add the additional MAPI operations required to manage folders, read messages and delete these messages. The rest of the functionality already existed in Ruler!
The next step was to create a custom listener and agent for Empire. Fortunately with Empire 2.0 this is super straight forward. You essentially need to create the listener, I modified the existing HTTP one, in this case to contain the logic for generating our launcher and agent that is able to communicate through Exchange rather than HTTP. The agent was is straight forward as you simply plugin the transport details into the generate function within the listener. This leaves the stager, which was also a bit of modification of the existing HTTP stager.
The extra development went pretty smoothly and an initial PoC was created. This has now been updated and stabilised a bit, and is available for public consumption.
Because videos speak louder than words, a demo of Liniaal in action is available here:
You’ll notice that the channel is rather slow to get setup initially, but once running you should have a check-in every 30s – 1min. This is also configurable in the Empire listener, meaning you can set your agent to check-in once a day/week/month, depending on how stealthy you are trying to be.
The github page contains setup details to get everything up and running. The important thing to note is that you need Empire 2.0 (it’s still the 2.0_beta branch on github). You’ll also require Ruler, unless you are using the pre-built binaries.
Caveats: There are a few important caveats to using Liniaal. This is not an “exploit” or a means to get code execution. You need to have a way of getting shell on the host already. Secondly, your target will have to have Outlook open and running. This is required as the Powershell agent uses Office Interop assembly to interact with the Exchange server. Finally, you will need valid credentials for the target user’s Exchange mailbox. This is a drawback and means you need to ensure you have a method for catching password changes by your target (monthly or so?) – given that you have code-exec on the host already, getting the initial password shouldn’t be too much of an issue.
This is mostly a PoC to show that it’s do-able. The channel is stable and should work in most cases. Feedback is always welcome, and extensions, fixes, improvements are most welcome.