# Inject All the Things

Well, its 2017 and I’m writing about DLL injection. It could be worse. DLL injection is a technique used by legitimate software to add/extend functionality to other programs, debugging, or reverse engineering. It is also commonly used by malware in a multitude of ways. This means that from a security perspective, it’s imperative to know how DLL injection works.

I wrote most of the code of this small project, called ‘injectAllTheThings’, a while ago when I started developing custom tools for Red Team engagements (in order to emulate different types of threat actors). If you want to see some examples of threat actors using DLL injection have a look here. You may also find this project useful if you want to learn about DLL injection. The internet is full of crap when you look for this kind of information/code, and my code might not be better. I’m not a programmer, I just hack code when I need to. Anyway, I’ve put together in a single Visual Studio project multiple DLL injection techniques (actually 7 different techniques) that work both for 32 and 64 bits, in a very easy way to read and understand. Some friends showed interested in the code, so it might interest you too. Every technique has its own source file to keep things simple.

Below is the output of the tool, showing all the options and techniques implemented.

According to @SubTee, DLL injection is lame. I tend to agree, however DLL injection goes way beyond simply loading a DLL.

You can load DLLs with signed Microsoft binaries indeed, but you won’t attach to a certain process to mess with its memory. The reason why most of the Penetration Testers don’t actually know what DLL injection is, or how it works, is because Metasploit has spoiled them too much. They use it all the time, blindly. The best place to learn about this ‘weird’ memory manipulation stuff is actually game hacking forums, I believe. If you are into Red Teaming you might have to get ‘dirty’ and play with this stuff too. Unless you are happy to just run some random tools other people have written.

Most of times we start a Red Team exercise using highly sophisticated techniques, and if we stay undetected we start lowering the level of sophistication. That’s basically when we start dropping binaries on disk and playing with DLL injection.

This post attempts to give an overview of DLL injection in a very simple and high level way, and at the same time serves as “documentation” support for the project hosted at GitHub.

## Introduction

DLL injection is basically the process of inserting/injecting code into a running process. The code we inject is in the form of a dynamic linked library (DLL). Why? DLLs are meant to be loaded as needed at run time (like shared libs in UNIX). In this project I’ll be using DLLs only, however we actually can ‘inject’ code in many other forms (any PE file, shellcode/assembly, etc. as commonly seen in malware).

Also, keep in mind that you need to have an appropriate level of privileges to start playing with other processes’s memory. However, I won’t be talking about protected processes and Windows privilege levels (introduced with Vista). That’s a completely different subject.

Again, as I said above DLL injection can be used for legitimate purposes. For example, antivirus and endpoint security solutions use these techniques to place their own software code/hooks into “all” running processes on the system. This enables them to monitor each process while it’s running, and better protect us. There are also malicious purposes. A common technique often used was injecting into the ‘lsass’ process to obtain password hashes. We all have done that. Period. Obviously, malware also uses code injection techniques extensively. Either to run shellcode, run PE files, or load DLLs into the memory of another process to hide itself, among others.

## The Basics

We’ll be using the MS Windows API for every technique, since it offers a considerable number of functions that allow us to attach and manipulate other processes. DLLs have been the cornerstone of MS Windows since the first version of the operating system. In fact, all the functions in the MS Windows API are contained DLLs. Some of the most important are ‘Kernel32.dll’ (which contains functions for managing memory, processes, and threads), ‘User32.dll’ (mostly user-interface functions), and ‘GDI32.dll’ (functions for drawing graphics and text display).

You might be wondering why such APIs exist, why would Microsoft give us such a nice set of functions to play and mess with other processes memory? The main reason is to extend the features of an application. For example, a company creates an application and wants to allow other companies to extend or enhance the application. So yes, it has a legitimate usage purpose. Besides, DLLs are useful for project management, conserve memory, resource sharing, and so on.

The diagram below tries to illustrate the process flow of almost every DLL injection technique.

As you can see above, I would say DLL injection happens in four steps:

All these steps are accomplished by calling a certain set of API functions. Each technique will require a certain setup and options to be set. I would say that each technique has their positives and negatives.

### Techniques

We have multiple options to instruct a process to execute our DLL. The most common ones are maybe ‘CreateRemoteThread()’ and ‘NtCreateThreadEx()’. However, it’s not possible to just pass a DLL as parameter to these functions. We have to provide a memory address that holds the execution starting point. For that, we need to perform memory allocation, load our DLL with ‘LoadLibrary()’, copy memory, and so on.

The project I called ‘injectAllTheThings’ (because I just hate the name ‘injector’, plus there are already too many crappy ‘injectors’ on GitHub, and I couldn’t think of anything else), includes 7 different techniques. I’m not the original author of any of the techniques. I just compiled, and cleaned, these seven techniques (yes, there are more). Some are well documented (like ‘CreateRemoteThread()’), others use undocumented APIs (like ‘NtCreateThreadEx()’). Here’s a complete list of the techniques implemented, all working for both 32 and 64 bits.

• QueueUserAPC
• SetWindowsHookEx()
• Reflective DLL

You might know some of these techniques by other names. This isn’t a complete list of every DLL injection technique around. As I said, there are more, I might add them later if I have to play with them for a certain project. Until now this the list of techniques I used in some projects. Some are stable, some aren’t. Maybe the unstable ones are because of my own code, you have been warned.

As stated on MSDN, the ‘LoadLibrary()’ function “loads the specified module into the address space of the calling process. The specified module may cause other modules to be loaded”.

In other words, it takes a filename as its only parameter and everything works. That is, we only need to allocate some memory for the path of our DLL and set our execution starting point to the address of ‘LoadLibrary()’ function, passing the memory address of the path as a parameter.

As you may, or may not know, the big issue here is that ‘LoadLibrary()’ registers the loaded DLL with the program. Meaning it can be easily detected, but you might be surprised that many endpoint security solutions still fail at this. Anyway, as I said before, DLL injection has legitimate usage cases too, so… Also, note that if a DLL has already been loaded with ‘LoadLibrary()’, it will not be executed again. You might work around this, but I didn’t do it for any of the techniques. With the Reflective DLL injection you don’t have this problem of course, because the DLL is not registered. The Reflective DLL injection technique instead of using ‘LoadLibrary()’, loads the entire DLL into memory. Then determines the offset to the DLL’s entry point to load it. Call it more stealthy if you want. Forensics guys will still be able to find your DLL in memory, but it won’t be that easy. Metasploit uses this massively, still most of endpoint solutions are happy with all this anyway. If you feel like hunting for this kind of stuff, or you are in the ‘blue’ side of the game, have a look here and here.

As a side note, if you are really struggling with your endpoint security software being fine with all this… you might want to try to use some gaming anti-cheating engine instead (note, I’m only trying to be funny in case you didn’t get it). The anti-rootkit capabilities of some anti-cheating games is way more advanced than some AVs. There’s a really cool interview with Nick Cano, author of the “Game Hacking” book, on reddit that you must read. Just check what he has been doing and you’ll understand what I’m talking about.

## Attach to the target/remote process

For a start, we need a handle to the process we want to interact with. For this we use the ‘OpenProcess()’ API call.

If you read the documentation on MSDN you’ll see that we need to request a certain set of access rights. A complete list of access rights can be found here.

These might vary across MS Windows versions. The following is used across almost every technique.

## Allocate memory within the target/remote process

In order to allocate memory for the DLL path we use ‘VirtualAllocEx()’. As stated in MSDN, ‘VirtualAllocEx()’ “reserves, commits, or changes the state of a region of memory within the virtual address space of a specified process. The function initializes the memory it allocates to zero.”

Basically, we’ll do something like this:

Or you could be a bit smarter and use the ‘GetFullPathName()’ API call. However, I don’t use this API call on the whole project. Just a matter of preference, or not being smart.

If you want to allocate space for the full DLL, you’ll have to do something like:

## Copy the DLL Path, or the DLL, into the target/remote process' memory

Now it’s just a matter of copying our DLL Path, or the full DLL, into the target/remote process by using the ‘WriteProcessMemory()’ API call.

That is something like…

If we want to copy the full DLL, like in the Reflective DLL injection technique, there’s a bit more code, as we need to read it into memory before we copy it into the target/remote process.

As I mentioned before, by using the Reflective DLL injection technique, and copying the DLL into memory, the DLL won’t be registered with the process.

It gets a bit complex because we need to obtain the entry point to the DLL when it is loaded in memory. The ‘LoadRemoteLibraryR()’ function, which is part of the Reflective DLL project, does it for us. Have a look at the source if you want.

One thing to notice is that the DLL we’ll be injecting needs to be compiled with the appropriate includes and options so it aligns itself with the ReflectiveDLLInjection method. The ‘injectAllTheThings’ project includes a DLL called ‘rdll_32.dll/rdll_64.dll’ that you can use to play with.

## Instruct the process to execute the DLL

We can say that ‘CreateRemoteThread()’ is the classic and most popular DLL Injection technique around. Also, the most well documented one.

It consists of the steps below:

If you look at ‘CreateRemoteThread()’ documentation on MSDN, we can see that we need a “pointer to the application-defined function of type LPTHREAD_START_ROUTINE to be executed by the thread and represents the starting address of the thread in the remote process.”

Which means that to execute our DLL we only need to instruct our process to do it. Simple.

See below all the basic steps listed above.

For the complete source code see ’t_CreateRemoteThread.cpp'.

Another option is to use ‘NtCreateThreadEx()’. This is an undocumented ‘ntdll.dll’ function and it might disappear or change in the future. This technique is a bit more complex to implement as we need a structure (see below) to pass to it and another to receive data from it.

For the complete source code see ’t_NtCreateThreadEx.cpp'.

### QueueUserAPC()

An alternative to the previous techniques, that doesn’t create a new thread in the target/remote process, is the ‘QueueUserAPC()’ call.

As documented on MSDN, this call “adds a user-mode asynchronous procedure call (APC) object to the APC queue of the specified thread.”

Here’s the definition.

So, if we don’t want to create our own thread, we can use ‘QueueUserAPC()’ to “hijack” an existing thread in the target/remote process. That is, calling this function will queue an asynchronous procedure call on the specified thread.

We can use a real APC callback function instead of ‘LoadLibrary()’. The parameter can actually be a pointer to the filename of the DLL we want to inject.

There’s a little gotcha that you might notice if you try this technique, which is related to the way MS Windows executes APC’s. There’s no scheduler looking at the APC queue, meaning the queue is only examined when the thread becomes alertable.

Because of this we basically hijack every single thread, see below.

As a side note, it was nice to see this technique being used by DOUBLEPULSAR.

For the complete source code see ’t_QueueUserAPC.cpp'.

### SetWindowsHookEx()

In order to use this technique the first thing we need to understand is how MS Windows hooks work. Basically, hooks are a way to intercept events and act on them.

As you may guess, there are many different types of hooks. The most common ones might be WH_KEYBOARD and WH_MOUSE. You guessed right, these can be used to monitor, the keyboard and mouse input.

The ‘SetWindowsHookEx()’ “installs an application-defined hook procedure into a hook chain.”

An interesting remark on MSDN states that:

“SetWindowsHookEx can be used to inject a DLL into another process. A 32-bit DLL cannot be injected into a 64-bit process, and a 64-bit DLL cannot be injected into a 32-bit process. If an application requires the use of hooks in other processes, it is required that a 32-bit application call SetWindowsHookEx to inject a 32-bit DLL into 32-bit processes, and a 64-bit application call SetWindowsHookEx to inject a 64-bit DLL into 64-bit processes. The 32-bit and 64-bit DLLs must have different names.”

Keep this in mind.

Here’s a simple extract of the implementation.

We need to understand that every event that occurs will go through a hook chain, which is a series of procedures that will run on the event. The setup of ‘SetWindowsHookExe()’ is basically how we put our own hook procedure into the hook chain.

The code above takes the type of hook to be installed (WH_KEYBOARD), the pointer to the procedure, the handle to the DLL with the procedure, and the thread id to associate the hook to.

In order to get the pointer to the procedure we need to first load the DLL using the ‘LoadLibrary()’ call. Then we call ‘SetWindowsHookEx()’ and wait for the event that we want (in our case pressing a key). Once that event happens our DLL is executed.

Note that even the CIA guys are, potentially, having some fun with ‘SetWindowsHookEx()’ as we can see on Wikileaks.

For the complete source code see ’t_SetWindowsHookEx.cpp'.

The ‘RtlCreateUserThread()’ is an undocumented API call. Its setup is, almost, the same as ‘CreateRemoteThread()’, and subsequently as ‘NtCreateThreadEx()’.

As you might know, among others, mimikatz and Metasploit both use ‘RtlCreateUserThread()’. If you are curious, have a look here and here.

So, if mimikatz and Metasploit are using ‘RtlCreateUserThread()’… and yes, those guys know their stuff… follow their “advice”, use ‘RtlCreateUserThread()’. Especially if you are planning to do something more serious than a simple ‘injectAllTheThings’ program.

For the complete source code see ’t_RtlCreateUserThread.cpp'.

This is actually a very cool method. A specially crafted code is injected into the target/remote process by allocating a chunk of memory in the target/remote process. This code is responsible for loading the DLL.

Here’s the code for 32 bits.

For 64 bits I couldn’t actually find any assembly working code and I kinda wrote my own. See below.

Before we inject this code into the target process some placeholders need to be filled/patched with:

• The DLL path name

And that’s when the game of hijacking, suspending, injecting, and resuming a thread comes into play.

We need first to attach to the target/remote process, of course, and allocate memory into the target/remote process. Note that we need to allocate memory with read and write privileges to hold the DLL path name and to hold our assembly code that will load the DLL.

Next, we need to get the context of one of the threads running on the target/remote process (the one that is going to be injected with our assembly code).

To find the thread, we use the function ‘getThreadID()’, you can find it on the file ‘auxiliary.cpp’.

Once we have our thread id, we need to set the thread context.

Next, we need to suspend the thread to capture its context. The context of a thread is the state of its registers. We are particularly interested in EIP/RIP (call it IP - instruction pointer, if you want).

Since the thread is suspended, we can change the EIP/RIP value and force it to continue its execution in a different path (our code cave).

So, we suspend the thread, we capture the context, and from there we extract the EIP/RIP. This is saved to resume the execution when our injected code finishes. The new EIP/RIP is set as our injected code location.

Once the thread starts executing, our DLL will be loaded and once it finishes it will return back to the point it was suspended at and resume its execution there.

If you feel like debugging this technique as a learning exercise, here’s how to do it. Launch the application you want to inject into, let’s say ‘notepad.exe’. Run ‘injectAllTheThings_64.exe’ with ‘x64dbg’ as shown below.

Set a breakpoint on the call to ‘WriteProcessMemory()’ as shown below.

Let it run and when the breakpoint is hit take note of the memory address at the register RDX. If you are asking yourself why RDX is time to read about the calling convention used in x64. Have fun and come back once you finish.

Step over (F8) the call to ‘WriteProcessMemory()’, launch another instance of x64dbg and attach to ‘notepad.exe’. Go to the address copied before (the one at RDX) by pressing ‘Ctrl + g’ and you will see our code cave assembly as shown below.

Cool, huh!? Now set a breakpoint at the beginning of this shellcode. Go to the ‘injectAllTheThings’ debugged process and let it run. As you can see below our breakpoint is hit and we can now step over the code for fun and enjoy this piece of code working.

This is so beautiful…

For the complete source code see ’t_suspendInjectResume.cpp'.

### Reflective DLL injection

I also incorporated Stephen Fewer’s (pioneer of this technique) code into this ‘injectAllTheThings’ project, and I also built a reflective DLL to be used with this technique. Note that the DLL we’re injecting must be compiled with the appropriate includes and options, so it aligns itself with the Reflective DLL injection method.

Reflective DLL injection works by copying the entire DLL into memory, so it avoids registering the DLL with the process. All the heavy lifting is already done for us. To obtain the entry point to our DLL when it’s loaded in memory we only have to use Stephen Fewer’s code. The ‘LoadRemoteLibraryR()’ function included within his project does it for us. We use the ‘GetReflectiveLoaderOffset()’ to determine the offset in our processes memory, then we use that offset plus the base address of the memory in the target/remote process (where we wrote the DLL) as the execution starting point.

Too complex? Yes, it might be. Here are the main 4 steps to achieve this.

This technique offers a great level of stealth in comparison to the other methods, and is massively used in Metasploit.

If you want to know more just go to the official GitHub repository. Also, make sure to read Stephen Fewer’s paper about it here.

## Code

There are some more obscure and complex injection methods around. So I’ll eventually update the ‘injectAllTheThings’ project in the future. Some of the most interesting ones I’ve seen lately are:

• The one used by DOUBLEPULSAR
• The one written by @zerosum0x0, Reflective DLL injection using SetThreadContext() and NtContinue() described here and code available here.

All of the techniques I described above are implemented in one single project I made available at GitHub. It also includes the required DLLs for each of the techniques. The table below makes it easy to understand what’s actually implemented and how to use it.

Method 32 bits 64 bits DLL to use
CreateRemoteThread() + + dllmain_32.dll / dllmain_64.dll
NtCreateThreadEx() + + dllmain_32.dll / dllmain_64.dll
QueueUserAPC() + + dllmain_32.dll / dllmain_64.dll
SetWindowsHookEx() + + dllpoc_32.dll / dllpoc_64.dll
RtlCreateUserThread() + + dllmain_32.dll / dllmain_64.dll
SetThreadContext() + + dllmain_32.dll / dllmain_64.dll
Reflective DLL + + rdll_32.dll / rdll_64.dll

Needless to say, to be on the safe side, always use injectAllTheThings_32.exe to inject into 32 bits processes or injectAllTheThings_64.exe to inject into 64 bits processes. Although, you can also use injectAllTheThings_64.exe to inject into 32 bits processes. And actually, I didn’t implement it, but I might have to give it a try later, you can go from WoW64 to 64 bits. Which is basically what Metasploit ‘smart_migrate’ does. Have a look here.

The code for the whole project, including DLLs is available at GitHub. Compile for 32 and 64 bits, with or without debugging and have fun.

# Kcshell: Assembly/disassembly Shell

I was a bit bored of switching between metasm_shell and nasm_shell every time I had to play with assembly instructions and opcodes during exploit development or reversing code. Also, switching between x86 and x64 wasn’t possible. Since I was already playing with the triforce Keystone, Capstone and Unicorn Python bindings, in a different project, I decided to write a small interactive assembly/disassembly shell for various architectures powered by Keystone/Capstone.

It’s extremely easy to use, and install. To install just type:

You may be wondering, pip3? Yes, I wrote it in Python3 and I really didn’t care about Python2. Why? Well, Python2 will be unsuported in more or less 3 years, so I decided to use Python3.

### Usage

By default kcshell starts in ‘assembler’ mode (x86 32 bits). You can change modes with ‘setmode’.

You can also change the default architecture for both the ‘assembler’ and ‘disassembler’ with ‘setarch’.

To assemble instructions just type the instructions in the command line.

To go from opcodes to instructions just type them in the command line.

For help just use ‘?’ or ‘help ’.

To list all the supported architectures just go to the desired mode and use ‘lsarchs’.

### TODO

I plan to implement a feature to read assembly instructions or opcodes from files soon. So if you find kcshell useful just keep an eye on github. In the meantime, have fun.

# Hunting (L)users Using WinAPI Calls Only

During Red Team engagements it is common to track/hunt specific users. Assuming we already have access to a desktop as a normal user (no matter how, always “assume compromise”) in a Windows Domain and we want to spread laterally. We want to know where the user is logged on, if he is a local administrator in any box, to which groups he belongs, if he has access to file shares, and so on. Enumerating hosts, users, and groups will also help to get a better understanding of the Domain layout.

You might be thinking, “use Powerview”. Lately, one of the most common problems I encounter during Red Team exercises is the fact that PowerShell is heavily monitored. If you use it, you’ll get caught, sooner or later. By now everyone is well aware how powerful PowerShell is, including Blue Teams and Security Vendors.

There are multiple ways to work around this. To avoid using multiple old school tools (psloggedon.exe, netsess.exe, nltest, netview, among others) and to reduce the amount of tools uploaded to compromised systems I created a simple tool that doesn’t require Administrative privileges to run and collect the information listed below, and relies only on the Windows API.

You might end up dealing with white list bypass (however, based on my experience, its easier to find an environment with PowerShell properly locked down and heavily monitored than an environment with proper whitelisting implemented) and process evasion (there are some security tools that collect information about processes running, however, this leads us to a different discussion), but I’ll leave that for another day because this discussion will end in long sequence of if’s and … let’s keep this post short.

If you are asking yourself, “wouldn’t these queries also trigger security events”? Yes, they will. However, at the moment they will most likely slip under the radar when compared with PowerShell, since PowerShell is getting a lot of attention these days.

In the meantime, is not new that Microsoft is taking security seriously and it is funny that they just released the following PowerShell script. Here’s the description:

 "SAMRi10" tool is a short PowerShell (PS) script which alters remote SAM access default permissions on Windows 10 & Windows Server 2016. This hardening process prevents attackers from easily getting some valuable recon information to move laterally within their victim's network. 

Basically, a script that changes some ‘registry’ values. Nothing special though.

Blue Teams with Advanced Threat Analytics (ATA) can also see Red Teams enumerating sessions via ‘net session’, PowerShell, or (l)user hunter. However, ATA architecture is a bit complex and in some setups you may need to install the ‘ATA Lightweight Gateway’ directly on the domain controllers (which removes the requirement for port mirroring). Additionally, ATA can leverage Windows events (forwarded directly from the domain controllers or from a SIEM and analyze the data). Again, I haven’t found that many organizations using ATA yet. I’ve seen a lot of organizations using SIEMs, but either they aren’t collecting the right logs or they are completely overwhelmed with logs that inexperienced security analysts (most of the time juniors) can’t make sense of. Also common is companies running default SIEM setups and without a clue on how to set it up properly.

Anyway, these are all valid reasons why I would like to eventually rewrite the ‘min’ and ‘max’ values delay between queries. In the meantime though we can still keep enumerating users, sessions, etc. low and slow.

### Features

• Retrieves current configuration information for the specified server (via list of hosts or domain enumeration).
• - OS Version
- Server Type (DC, Backup DC, Workstation or Server, Terminal Server, MSSQL Server)
• Lists information about all users currently logged on to the workstation.
• - interactive, service and batch logons.
• Lists information about sessions established on a server.
• Retrieves information about each shared resource on a server.
• - checks if current user as read access.
• Returns results for the NS_DNS namespace, IPv4 protocol.
• Checks if current user is an Administrator on a server.
• Retrieves information about all user accounts on a server or DC.
• Retrieves a list of global groups to which a specified user belongs on a server or DC.
• Retrieves information about each global group in the security database, SAM database or Active Directory.
• Retrieves a list of the members in a particular global group in the security database, SAM database or Active Directory.
• Retrieves information about a particular user account on a server or DC.
• Enumerate the domain controllers in the local domain.

Additionally, for hosts enumeration there’s a minimum and maximum delay value in seconds you can add to avoid detection/noise.

Expect further developments, specially on the ‘error handling’ side and ‘look and feel’. I have a few more ideas that I would like to incorporate.

### Usage

For usage examples refer to the GitHub repository, where I added some screenshots.

# Lurking Around Revenge-RAT

Two days ago the tweet below caught my attention, 1/54 at virustotal. A RAT is always an interesting topic for me since it’s a common practice to use some form of RAT to establish C&C in Red Team Exercises. So there’s always something to learn even if it’s done in a complete wrong way.

I opened the virustotal report, 1/54 indeed. Is Fortinet really good or are the others really bad, I wondered. Even after looking at the sample I still don’t know the answer.

I downloaded the ‘Revenge-RAT v.0.1’ and extracted the rar file. Here’s the whole contents of the zip file.

My first surprise was…

A potentially malicious .net assembly and only one AV flagged it?! I loaded it in CFF Explorer. All looks pretty normal…

‘Revenge-RAT v.0.1.exe’
SHA256: f1fc15082123a79f5350a6bf7897f4ac9c7474619f96efc556754918f3926ae7

I loaded the assembly in ILSpy and surprise, surprise… no signs of packing or obfuscation.

Then I tried to load one of the DLLs in CFF Explorer, and first surprise. No, now I really mean it. ‘Unknown format’.

PEiD confirms this is not a valid PE file.

File to the rescue.

I think I’ve seen this before.

Ok, now makes sense. I opened it on ILSpy and once again, no packing or code obfuscation.

By looking at the code we can see the author simply reads the registry, nothing special. I decided to run it inside my VM to see how advanced was the almost FUD, fully undetected, ‘Revenge-RAT v.0.1’. A very basic builder that simply makes a few a changes to the ‘Stub.exe’ file.

If we look at the ‘Stub.exe’ code we can see there’s nothing special and the keylogger is also quite basic.

Even though it works, another surprise.

The following screens show more or less the features that ‘Revenge-RAT v.0.1’ includes.

I went through most of the ‘Revenge-RAT v.0.1’ features and files and found it to be a very basic and unstable RAT written apparently in Visual Basic.

The ‘IP Tracker’ uses the web site addgadgets.com to find the location of the infected machine. In my test lab it found my location accurately, as I was in a dark room ‘hacking’.

Besides, only some common features also usually seen in this kind of basic malware. ‘Process Manager’, ‘Registry Editor’, ‘Remote Connections’, ‘Remote Shell’, system information, among a few others.

Maybe the most interesting one, the ability of running files on the remote computer.

Which indeed launches ‘procmon’ on the remote victim.

Besides nothing really interesting to show.

### Lessons learned

I feel like I wasted my time based on a 1/54 virustotal score. The author doesn’t try to hide what his code does in any way, the architecture is common and weak. As a good thing the author is not trying to sell the RAT and might only be trying to learn how to code. Even though learning C or C++ would be a better investment than learning any managed code language. Anyway, it might be, or it might not be, quite surprising that these types of basic tools are still used successfully to compromise some systems, as we can see in one of the YouTube videos posted by the author. In the video at some point we can see eventually 15 systems compromised, it is not that much, but it is still something. Even though the features are basic they are still enough, in 2016, to cause enough harm to ‘random’ users.

I sent the ‘Server.exe’ to virustotal, which is basically the ‘Stub.exe’ that was on the rar file initially submitted to virustotal and now, after two days, we can see that the detection rate is 41/57. Even though well-known and widely used AVs still don’t flag this file as malicious. Anyway, this only shows how much the AV industry is broken.

### IOCs

For IOCs check the links below:

# Cracking Orcus RAT

After my previous post here, I got a message from an anonymous source asking me if I would like to have a look at another piece of malware written in managed code (that was also on the news recently). More precisely at the ‘Orcus RAT’. I follow KrebsonSecurity blog closely and I recognized the name. If you didn’t read Brian Krebs post about who’s behind ‘Orcus RAT’ read it here. Not long after ‘Palo Alto Networks’ Research Group published a follow-up, read it too. Based on the small research I did about this tool I think ‘Palo Alto’ got their facts right.

At first I thought I could be dealing with someone trying to ‘phish’ me, but the offer was legit. Challenge accepted. The zip file I got is for version 1.4.2 (which is the latest version available at the ‘Orcus RAT’ website, at the time of this writing). The zip file is massive. Here’s the whole contents of the zip file.

Interesting to notice that the author includes the .pdb files on the package. According to wikipedia, Program database (PDB) is a proprietary file format (developed by Microsoft) for storing debugging information about a program (or, commonly, program modules such as a DLL or EXE). PDB files commonly have a .pdb extension. A PDB file is typically created from source files during compilation.

I started by loading ‘Orcus.Administration.exe’ in CFF Explorer. As you can see it is a very recent build.

SHA256: 4056ee5b23e47d172b48c84ceb5b6eca5ee68cf839dc7e5f28e984005ed7dcea

### Dynamic Analysis

As usual I started by running it inside a VM without Internet access and I was presented with the following screens.

Without a license it seems I can’t do anything else. While monitoring the DNS I observed queries to ‘collector.exceptionless.io’.

### Reverse Engineering Managed Code

The first thing I noticed when I loaded ‘Orcus.Administration.exe’ in CFF Explorer was that the assembly was signed. See bellow the fields ‘StrongNameSignature RVA’ and ‘StrongNameSignature Size’.

Meaning it wouldn’t be possible to change it (I read a little bit about it while researching for my previous post). Well, I can change it, but it won’t load. This signing process is best known as ‘Strong Names’. Usually you use ‘Strong Names’ to verify an assembly publisher’s identity. When you add a ‘Strong Name’ to an assembly you use a private key (part of an asymmetric public/private key pair) to generate a cryptographic hash and the public key is included in the assembly, along with the hash. I’m not an expert on this. I advise you read the ‘References’ at the end of this post if you want to know more. Which is actually what I did too. Anyway, more on this later.

The first surprise was that at the first glance no code obfuscation was used. Apparently I could browse the whole code without any problem. With one exception. As you can see in the picture above the DLL ‘Orcus.Administration.Licensing’ wasn’t loaded properly. So, I opened it on CFF Explorer and noticed a few things. The MetaData had two GUID’s, instead of one.

The Assembly Tables were two also, instead of one, and the ‘Culture’ field had what it looked like Chinese characters. First sign of obfuscation.

And by looking at the GUID’s Blobs I could see this DLL was obfuscated with ConfuserEX.

I prayed a bit (unpacking ‘Confuser’ can be a nightmare) and launched ‘UnConfuserEx v1.0’, you can find this tool in some Reverse Engineering Forums. Usually it is not that simple… but surprisingly it worked.

No more signs of code obfuscation (well this isn’t entirely true as you will see later). Only a group of assemblies signed.

And the complete list of signed assemblies was:

### Cracking Orcus RAT

I started looking at code trying to find a good place to bypass the Registration/License process. You might be wondering, what about the fact that the assemblies are signed to avoid tampering? Don’t worry, I’ll get there.

After a while, I found what I thought it would be the best place to bypass the licensing process. By looking at the ‘Administration’ class code and the method ‘OnStartup(StartupEventArgs)’ I’ve found the following lines of code:

I thought, if I remove the ‘Environment.Exit(0);’ call inside the if statement that checks if the License is valid, the application should proceed whatever is inside the file ‘license.orcus’, assuming it exists.

Cool, so I only need to figure out how to bypass the signed assemblies ‘thing’. To start, and avoid the risk of introducing errors by making the wrong changes in the IL code, I decided to change only the contents of the MessageBox that should be shown if the license is invalid. So, I changed it as shown below.

And here comes the trick. ILSpy, or actually the ‘Reflexil’ plugin, will say that it can’t save the file because the assembly is signed. It gives you multiple options though.

1. Register it for verification skipping (on this computer)
2. Re-sign with key
3. Remove Strong Name
4. Cancel and keep it delay signed

To be honest my first approach was ‘Remove Strong Name’. If you look online you will find this as a possible solution, and in fact it is. However, I couldn’t make it work with ‘Orcus RAT’. The usual examples and ‘crackmes’ you find online apply only to one executable file (see the article in References) and not to complex/big projects as ‘Orcus RAT’. I tried to remove the ‘Strong Name’ not only for ‘Orcus.Administration.exe’ but also all the DLLs listed above (as signed), plus all the ‘References’ I could find in all these files. I still couldn’t launch ‘Orcus.Administration.exe’ successfully, as it fails to load with a ‘System.IO.FileLoadException’ due to tampered signature.

After some frustrating attempts I decided to take a different approach. Even though it is possible to do it the way I was trying. If you know what I could be missing please let me know. I’m pretty sure we can do this in multiple different ways anyway.

The second option, ’Re-sign with key' doesn’t apply as we don’t have the private key. The first and second on the screen below aren’t available because I don’t have ‘sn.exe’ in my PATH variable (sn.exe is shipped with the Windows SDK kit), it doesn’t matter because I can do it manually.

The first option ‘Register it for verification skipping (on this computer)’ means we can actually disable windows ‘Strong Name’ validation (see the ‘References’). Note that disabling the strong name verification may introduce a vulnerability. A malicious assembly could use the assembly name, version, culture, and public key token of the assembly added to the skip verification list to fake its identity. Which would allow the malicious assembly to also skip verification. I advise you to do it only in a non production environment.

To accomplish this task we will use the ‘sn.exe’ utility. As we saw before we can use ‘sn.exe -Tp ’ to view the public key token, so what we are going to do now to drop the assembly verification is running ‘sn.exe’ the following way (as administrator).

Now if you look at the registry you will see a new entry for ‘Strong Name’ verification skipping. Basically what we just did manually was the first option ‘Reflexil’ gave us before.

As you can see only the assemblies with the public key ‘851aa33cb9b88f1c’ will be skipped, if you feel lazy or you don’t care just run ‘sn.exe’ as follows:

An entry for all assemblies (*.*) will be added. By the way if you want to bring back your previous settings ‘sn.exe -Vu ’ is your friend.

Now the interesting thing, if you select option ‘4. Cancel and keep it delay signed’ when saving your patched file with ‘Reflexil’ it will remove the ‘Strong Name’ and replace it with a delay signature, but most of the time this does not prevent the assembly from loading. And in fact it does not. Forget all the ‘sn.exe’ kung fu above, you don’t need it.

If we run our patched ‘Orcus.Administration.exe’ now it will run without any problems. Well, more or less.

It seems my thought about simply create an empty ‘license.orcus’ file was wrong. So, I went back to the code. I was definitely in the right place to bypass the ‘Registration/License’ mechanism, so I decided to do the following changes instead:

Basically I replaced the IL instructions below (3 and 4) with nops (above). Note: I later found this isn’t really necessary, you actually can keep these instructions.

And then I deleted all the IL instructions between lines 63 and 108 (sorry too many to list them here). I gave it a try again, and…

It works! Mission Accomplished?!

Not really. While I can bypass the registration and create the server when trying to create the ‘bot’ it fails with a ‘System.NullReferenceException’ under ‘Orcus.Administration.Build.Builder.ApplySettings’. So, I started looking at the code again… and by looking at the code below I could see why. A reference to something that we bypassed earlier, ‘App.License.get_HardwareId()’.

The license mechanism was bypassed so this is definitely not initialized. I tried to look at the code of this method.

Not really helpful. While still lurking around this ‘Orcus.Administration.Licensing’ dll code I spotted another method also called ‘get_hardwareId’ but under ‘HardwareIdGenerator’.

However, it seems even though we were able to use ‘UnConfuserEx’ to unpack the code it seems that’s still a layer of obfuscation here. Or am I too tired to even try to understand what this method does?

After looking around and around I’ve found that this method is used if you launch the application via the command line, as:

Which will open the following window.

There are a few more command line options as you can see below.

None looks useful. But, we have the code to generate the ‘HardwareId’ inside the same dll. So if I change the code below…

To the code below… I might not get the same ‘System.NullReferenceException’ any more.

I tried and… yes, now it works!

Well, it wasn’t that easy, I struggled a bit to get it right. Anyway, ‘Mission Accomplished’. I’m not sharing the sample, sorry (unless it is for research purposes and I can easily verify your intentions are legit). Otherwise, don’t ask.

I’m pretty sure I could have ‘cracked’ this software in a different way, if you feel like sharing your approach please e-mail me.

### Orcus RAT Features

I’m not selling the RAT so I’ll not go into detail about ‘Orcus RAT’ features. Anyway, I played a bit with the RAT and I must say that there are multiple hours of development here. What I’ve found most interesting was actually the architecture. See below (picture from ‘Palo Alto’ blog post).

More or less what I would do if I was writing a RAT, for ‘Red Team’ exercises of course. Basically a three-part infrastructure model. An administration panel, the client (call it ‘bot’ or whatever), and an intermediary server. This will increase resilience and make it harder to detect/erradicate/take down. You must assume that some of your servers are going to be found and you need to be able to redirect ‘bots’ to other servers. Both the infected victim and the ‘Orcus RAT’ operator will use the server as a proxy to exchange commands and relay information. If you want to know more read the ‘Palo Alto’ blog post and there’s a small tutorial on hackforums and even a video on YouTube.

# Cracking HawkEye Keylogger Reborn

I had never heard of ‘HawkEye Keylogger’ until I’ve read the following blog post from Trustwave. I’ve found the amount of features quite interesting and I was curious to have a closer look at the source code. After some research it seems this Keylogger has been successfully used in some campaigns in the past and it is still being actively used.

Actually ‘HawkEye’ is best known in the AV industry by ‘Golroted’. In fact it seems that ‘HawkEye’ was using a different name before, ‘Predator Keylogger’, as you can see in this post from stopmalvertising. I’m not sure if the author(s) behind them are the same. The source code might have been shared/sold among some malicious software writers.

After a bit of digging I could also find some previous versions of ‘HawkEye’ cracked. However, it seemed, at first, that the previous versions were a bit different from the latest ‘Reborn’ version. ‘HawkEye’ didn’t look an advanced piece of malware and the authors/sellers apparently are doing a sloppy job. The lesson here is even a sloppy malware writers can make a profit without hiding themselves that much.

While searching the web I’ve found a few ‘HawkEye’ technical analysis (see references at the end of this blog post), and while poking around I ended on the home page of ‘HawkEye’. It is sold for more or less \$35, depending on each type of license you are interested in. At the time of this writing the home page is down, it should come up again at some point. During the last month I noticed that it goes down and comes back from time to time.

I noticed one interesting thing though. Maybe due to a misconfiguration (or not) I could download ‘HawkEye Keylogger Reborn’ and some other malicious software that the same author is selling. From http://hawkspy.net/hawkeye-keylogger-reborn/ I was redirected to http://selfypay.org/HawkSpy/ and… guess what? All their software belongs to us…

‘HawkEye Keylogger - Reborn.exe’
SHA256: c8164521267263190900e1f62494068e994b053ae720d678da542e80286b5f46

So I had access to the “potential” builder and not only to the samples that were collected on the wild and mentioned on the technical articles I’ve found. So I decided to have a look and opened it in CFF Explorer.

CFF Explorer is like PEStudio for .net assemblies and it tells us that this file is indeed a .net binary.

### Dynamic Analysis

So I downloaded it and ran it on a VM. No anti-VM techniques were in use, at least none able to detected my VMware based virtual lab. If ‘HawkEye’ doesn’t have access to the Internet the program will throw an Exception and writes a file ‘loader.log’ on the same directory from where the exe was launched.

Since I was monitoring the DNS queries I could see that it tries to resolve the host ‘seal.nimoru.com’. Ok, I fired up my Tor Proxy VM and this time I was presented with a login form, as shown below.

I did a quick search for ‘Net Seal’ (shown in the title bar of the login dialog box) but at this time I didn’t find anything (more on this later).

### Reverse Engineering Managed Code

Managed code decompilers are the way to go when analysing .NET assemblies since they allow us to decompile the binary into source code. However, if the binary is obfuscated, this process can be a nightmare. Besides the managed code decompilers are not as amazing as you may think if you are dealing with complex projects. Almost all of them allow you to export the code, even to Visual Studio projects. Getting this projects to compile is a complete different story though. Based on my experience 99% of times it will not build and you have to deal with too many errors. Most of the errors are completely ‘alien’. Still, decompilers are great.

So I loaded ‘HawkEye Keylogger - Reborn.exe’ in ILSpy, I could see the file was encrypted/obfuscated with a module called ‘MindZero v0.5.0-custom’.

I looked around but I couldn’t find any reference to MindZero .net code packer/obfuscator or anything close on the Internet. I tried a couple of tools in order to try to identify the packer/obfuscator used. Some wrongly indicated that Confuser was used.

The only methods exposed, as you can see bellow, were ZeroMind(), Zero(), Mind(), Decompress(), and a few others.

The method Zero() and ZeroMind() were quite interesting. One of the immediate things I noticed was the use of Reflection and LoadModule. More on this later.

After reading quite a lot about .net binaries Reverse Engineering (see the ‘References’) I decided to use first a memory dumper and then go from there.

So I used ‘MegaDumper 1.0 by CodeCracker / SnD’. You can find it in some Reverse Engineering Forums. Basically I executed ‘HawkEye Keylogger - Reborn.exe’, fired ‘MegaDumper’, selected the process corresponding to ‘HawkEye’ (stuck on the ‘Net Seal’ login prompt) and selected the option to dump the loaded assembly.

The result was an interesting collection of executable and dll files.

I loaded almost every file in ILSpy and found some interesting things. The ‘Cure.exe’ was the vacine to ‘HawkEye’. Meaning if you infected a computer and you want to clean it you should run this file. Here’s the interesting code showing some of the IOCs already mentioned in some of the articles I mentioned before.

Bellow is the code with the most interesting methods for Blue Teams.

Other interesting file was ‘License.dll’. I loaded it in ILSpy and got the following message:

So it seems ‘SmartAssembly 6.9.0.114 obfuscator’ was used, at least in some PE files that are part of the whole package. However, even after cleaning it I couldn’t make much sense of the code… The amount of goto’s indicates that the file is still obfuscated, so or either SmartAssembly was incorrectly detected or the deobfuscator didn’t work. I didn’t spend much time with this though.

One of the dumped ‘HawkEye Keylogger - Reborn.exe’ files was smaller than the original, however after loading it in ILSpy I could see it was still packed and all his functionality appeared the same. By running it I was again stuck in the ‘Net Seal’ login prompt.

It is interesting to notice that if this file was using some evasion techniques it would have exited long before we have finished. So this behaviour led me to conclude that if this ‘HawkEye’ version was using evasion techniques they were most likely not implemented correctly.

### WinDBG to the rescue

In order to debug .net assemblies the best option is WinDBG with SOS and SOSEX together. However there is no IL code steping and it might be a bit hard to get into it. The IL opcodes are a bit scary, at least at first. Besides reversing .net malware is not well documented on the internet.

Before you start make sure you load Microsoft debugging symbols. Set your symbol path to Microsoft symbol server or just download the symbols locally. I usually have the symbols installed locally for obvious reasons, but it is completely up to you. I’m not going to show how to do it since this is widely documented. However this step is not optional.

The SOS extension is part of the .net framework and the SOSEX extension can be downloaded from here. You can install it anywhere you want, after firing WinDBG you need to load it the following way:

I’ll skip the steps to load and use SOS because you can do everything with SOSEX. However in a initial phase it was quite useful to get a better insight of this .net assembly.

As I mentioned before, one of the things I noticed when I first looked at the .net assembly in ILSpy was the use of Reflection and LoadModule. This method loads a Byte Array, hopefully deofuscated I thought. So with the help of SOSEX is quite easy to set a breakpoint on any method matching a pattern. So I decided to set a breakpoint on any method matching the pattern Assembly.Load:

When we run the binary CLR is initialized and WinDBG places breakpoints on all methods matching the pattern above. After the first breakpoint is hit you can see a complete list of breakpoints with:

After some hits and some exceptions we land exactly where we want.

If we check ECX register we should have our Byte Array ready to be dumped. The second DWORD (003e0400) corresponds to size of the Byte Array and the third DWORD (00905a4d) corresponds to the .net assembly. To dump this assembly we can use the ‘writemem’ command as follows:

But there’s an easier and 1337 way by using the poi() function. Pointer of integer function is used to get pointer-sized data. Think about the * operator for C and C++. By using poi() we just provide ecx+4 as its parameter and it will automatically take the value at that address and use it, rather than just using the value of ecx+4:

I loaded the assembly in ILSpy and Bingo.

I now have access to the whole code. Under ‘Keylogger’ we can find the code for the ‘Builder’ of the samples that have been collected on the wild. As we can see, by looking only at the methods, the ‘Builder’ has loads of ‘cool’ stuff. ‘NewsFeed’, ‘Tutorial’, ‘BugReport’, ‘Bazaar’… it almost looks like a legit software.

After running the new binary I’m still stuck at the ‘Net Seal’ prompt login though. But now I have access to the code!

In case you missed something here’s the full WinDBG session.

### Cracking HawkEye Keylogger Reborn

So I need to bypass this login prompt which I guess it validates the license. Which options do I have? I can try to export the code and build it on Visual Studio…

Well, I tried… 738 errors! Good luck with that…

The only option is to patch the binary. Even though I’ll be dealing with IL code and not assembly code… it looks more fun than fix 738 build errors. Luckily there’s a really nice plugin for ILSpy and Reflector called Reflexil that allows you to binary patch the IL code “easily”.

After poking around the code for a while I’ve found an interesting method inside the class ‘License’ called ‘Initialize()’. It seems I’ll need to modify it.

There are two ways you can modify the code with Reflexil. An easy one and a hard one. The easy one allows you to modify directly the code in C# (or Visual Basic). The hard one allows you to modify directly the IL opcodes.

Of course I went for the easy one! But that didn’t work quite well…

It looks I’ll have to learn some IL code. I have tried to build some really small PoCs on Visual Studio to figure out the IL opcodes for simple things like:

Which is basically:

However Reflexil makes it really easy, after poking around the code for a little while it looked like I only needed to delete instructions and not actually write any IL code.

So I deleted all the IL instructions from the methods ‘Initialize()’ and ‘Initialize(string)’ and saved the new file.

I’ve run it and… voila. Cracked?

Well… kind of. Because, if you try to use the ‘builder’… it does’t work.

The newest version of ‘HawkEye Keylogger’ has one big difference to the older ones that makes it a bit harder to crack. While the other cracked versions of ‘HawkEye Keylogger’ that I could find on-line (I mean the ones that work, because some don’t…) have the actual keylogger embedded as a Resource. However this ‘Reborn’ version doesn’t have the keylogger binary embedded as a Resource any more. Instead, during runtime the keylogger executable is downloaded from ‘http://seal.nimoru.com/Base/getFile.php’. The author’s intention is clearly avoid cracking. Look at the following ‘builder’ code under the ‘Menu’ class.

As we can see the download of the file depends on code from the ‘Net Seal’ authentication mechanism that we bypassed since we don’t have an account. Anyway we can see what’s going on here by looking at the ‘Cloud’ method.

I started looking around the code again to see what I could do. I though the easiest way was using a local sample of the keylogger and read its bytes directly into ‘MyProject.Forms.Keylogger.stubBytes’. To do this I need to find a proper place and write some IL code. It seems I can’t go away without writing IL code. Fun.

I used the same approach as before, launched Visual Studio and wrote more or less what I needed:

Then I loaded it on ILSpy and looked at the IL instructions.

Then I started looking at the IL instructions of ‘GetStub’ method from the ‘Menu’ class…

I’ve found what it looked like a possible place for my IL code at ‘Menu_Load’ method on the ‘Menu’ class and rewrote it as shown bellow:

Saved the new file and gave it a try…

Yes, now it works. You need to place the ‘keylogger’ sample on ‘C:\pwned.exe’, you can change it but I’ll leave that as an exercise for you. Note that you also need ‘Mono.Cecil.dll’ installed on your system or simply on the same directory as our final cracked version or the program will crash with an ‘System.IO.FileNotFoundException’. If you use Procmon you can easily identify what’s missing…

You already have ‘Mono.Cecil.dll’, look at the dumps from ‘MegaDumper’ so… Mission Accomplished!

I’m not sharing the cracked version. However, you can visit the links I mention above and with all the information here you should be able to get the ‘job done’ or even do a better job.

### HawkEye Builder Features and Code

The builder presents the user with multiple options. We can contact support via email as shown bellow.

Here’s the code from sending an email and “ask a favour”!

You can check the status of your subscription too.

There’s even a news feed. Where I think the author publishes some… news!?

The vaccine to clean the infected machine as we saw earlier.

The lovely and caring Bug Report feature.

As you can see code reuse is not mandatory…

The must read option simply opens the browser and redirects the user to the ‘HawkEye’ home page.

The tutorial displays the only video the author has for ‘HawkEye Keylogger Reborn’. That you can also see on YouTube.

The Bazaar has more software for interested buyers. More keyloggers in case one is not enough, crypters, and apparently a RAT and an MS Word exploit are in the works.

Lastly and the actual relevant feature… the keylogger builder.

The code for the builder is quite big and basically replaces some assemblies with the configuration the user chooses.

Nothing really new.

### Keylogger

Most of this ‘HawkSpy Keylogger Reborn’ features and IOCs have already been discussed on the technical articles I point on the ‘References’ section, so I’ll not waste too much time going over them again.

However, one interesting thing to notice is that even after having his keylogger exposed and cracked on the Internet the author is too lazy to change simple things as the secret key and salt used for configuration settings encryption. Well, to be fair it will not make any difference anyway.

As you can see the secret is still the same as in previous versions.

And the salt too.

With all this information is trivial to decrypt the keylogger settings.

You can use the following small decryption method I wrote in C# to get the configuration.

Since getting access to the configuration of the samples being used in the wild is pretty easy I would avoid using it for ‘serious’ stealthy operations.

Note that ‘bob@mail.lab.org’ is just a local e-mail of my internal lab mail server (mail.lab.org).

For more details and IOCs I recommend you to read the Trustwave, Malwaredigger and blog.idiom.ca, all listed in the ‘References’ section. There’s no point describing the same thing that have already been described since the only thing that as really changed in this ‘Reborn’ version is the fact that the actual keylogger is now being downloaded from the Internet in real time and it is not embedded as a ‘Resource’ any more.

### People behind ‘HawkEye Keylogger’ and other variants

Apparently many eventually “talented” software developers think they can get away with writing, selling and supporting malicious software. The true is it seems that some of the people behind this keylogger have been around for quite some time. Before ‘HawkSpy.net’ the domain hawkeyeproducts.com was used and it is not hard to track their operations back to 2013/2014 but I’ll leave that for you as an exercise if you feel like it.

One thing I later found is that this ‘Net Seal’ software is/was also being distributed on hackforums as you can see here and here. You might want to look at it if you have some free time.

# PowerOPS: PowerShell for Offensive Operations

Update: PowerOPS got some public attention. My company asked me to write a blog post about it, which has been published here. It is pretty much what I have written here before and on the github project’s page, so nothing new really. In the meantime I changed only a few bits and added the Amsi Bypass technique. So now it should work without any problems on systems with PowerShell v5.

Lately I’ve been involved in multiple restrictive environment breakouts where powershell.exe was blocked and where other “security” mitigations to restrict execution of scripts where in place. Even though the last never was a problem the first one “was”.

Since I’ve been using, a lot, some PowerShell scripts finding powershell.exe blocked is annoying. Besides some AVs are starting to incorporate signatures to detect some of those well known PowerShell scripts. The bypass is trivial but I find it annoying anyway. Some time ago a friend showed me an interesting tool, p0wnedShell. I tried it, I loved it, but I wanted more. Specially more flexibility and I didn’t really need all the other features p0wnedShell incorporates. At least not for what I had in mind. I wanted a tool which could include the usual PowerShell scripts I use but with a lot more flexibility. I wanted to use the scripts with the same freedom level as if I was running powershell.exe.

And that’s how PowerOPS was born. Sorry about the lame name but I couldn’t come up with another one.

### What is PowerOPS

PowerOPS is an application written in C# that does not rely on powershell.exe but runs PowerShell commands and functions within a powershell runspace environment (.NET). It intends to include multiple offensive PowerShell modules to make the process of Post Exploitation easier.

It tries to follow the KISS principle, being as simple as possible. The main goal is to make it easy to use PowerShell offensively and help to evade antivirus and other mitigations solutions. It does this by:

• Doesn't rely on powershell.exe, it calls PowerShell directly through the .NET framework, which might help bypassing security controls like GPO, SRP and App Locker.
• The payloads are executed from memory and never touch disk, evading most antivirus engines.

### What’s inside the runspace

#### The following PowerShell tools/functions are included:

Additionally you can run any valid PowerShell command.

Powershell functions within the Runspace are loaded in memory from Base64 Encoded Strings.

### Where to Get it

Source code is available at GitHub: https://github.com/fdiskyou/PowerOPS

### How to Compile it

To compile PowerOPS you need to import this project within Microsoft Visual Studio or if you don’t have access to a Visual Studio installation, you can compile it as follows:

To Compile as x86 binary:

To Compile as x64 binary:

PowerOPS uses the System.Management.Automation namespace, so make sure you have the System.Management.Automation.dll within your source path when compiling outside of Visual Studio.

### How to use it

Just run the binary and type ‘show’ to list available modules.

PowerUp and PowerView are loaded as modules, so Get-Command -module will show you all available functions.

Yes, all your PowerShell fu applies. PowerOPS is basically a PowerShell shell with some modules/functions pre-loaded. So Get-Help is your friend and will help to find how to use the modules.

Let’s say you want to see examples on how to use Invoke-Mimikatz.

Or simply look at the whole help available for Invoke-DllInjection.

You can play around with the output…

Save the output of your commands the way you want…

Do some math…

Browse the filesystem…

And so on…

### Credits

PowerOPS was inspired by Cn33liz/p0wnedShell, and basically consists of work from Nikhil Mittal of Nishang, mattifiestation of PowerSploit and sixdub, engima0x3 and harmj0y of Empire.

# Sandbox Detection: Pafish Overview

After an internal Pafish source code analysis my company asked me to write a blog post about it. You can find the original article published here: https://labs.portcullis.co.uk/blog/sandbox-detection-pafish-overview/

Bellow is a just a local mirror for future reference.

## Sandbox detection: Pafish overview

Here at Portcullis, we are frequently involved in “red team” exercises, which means we subject an organisation’s information security systems to rigorous testing and analysis. The opposite of a red team is a “blue team”. A blue team attempts to identify and stop the red team from compromising systems. One of the techniques used when red teaming is to write malicious code to test the security systems of our clients. One of the issues we face resides in the fact that we need to bypass sandbox systems that analyse our files in real-time to identify if the potentially malicious file should be blocked and Indicators Of Compromise (IOCs) generated or if the files are benign and safe. At the same time, blue teams that catch our files will try to reverse engineer them in order to understand how we may be compromising systems. Even though the last point is not really relevant for us (ultimately we’re not the bad guys), the first point is.

In order to be able to mitigate this issue, our code needs to be able to detect if it is being run inside a debugger, a Virtual Machine (VM) or a sandbox. There are some well known open source projects that are able to achieve this that are often used by malware writers. One of the most well known is called Pafish, Paranoid Fish, the code for which can be found in the Pafish GitHub repo. So I decided to take a look at the code and go through all the tricks Pafish has in order to assess if they should be incorporated in to our exercises. If our code is running inside a debugger, VM or sandbox it should deviate from it’s original path and do something legitimate or terminate immediately. If it isn’t running in any of these environments it should run it’s malicious code and infect the system.

Pafish is written in C and can be built with MinGW (gcc + make) as it says on its official GitHub web site.

To build pafish you will basically need to install mingw-w64 and make. After unziping the Pafish source code, we can see the project source has different source code files, each one used for different detection purposes.

• Detect a debugger: debuggers.c
• Detect a sandbox: gensandbox.c
• Detect hooked functions: hooks.c
• Detect VirtualBox: vbox.c
• Detect VMWare: vmware.c
• Detect Qemu: qemu.c
• Detect Bochs: bochs.c
• Detect Cuckoo: cuckoo.c
• Detect Sandboxie: sandboxie.c
• Detect Wine: wine.c

In the next sections I’ll take a quick look at each one of these files. As you can see some sandboxes are missing, like FireEye, AMP Threat Grid from Cisco, Maltracker from AnubisNetworks, among others. By looking at these techniques we might find insights on how to bypass them if we find one in use at our clients during our engagements.

## debuggers.c

By opening debuggers.c, we can see the first method implemented by Pafish. The IsDebuggerPresent() function is a Win32 API function that can be used to determine whether the calling process is being debugged by a debugger.

Still on debuggers.c we can see another function called debug_outputdebugstring(). This uses another function from the Win32 API, OutputDebugString(). According to MSDN, this function “sends a string to the debugger for display”. This is exactly what this code does. If the application is not running under a debugger the string will be sent to system’s debugger to be displayed with the DbgPrint() function from the Windows Driver Kit (WDK). If the application is not running inside a debugger and there is no system debugger then the OutputDebugString() does nothing. If the function doesn’t return an error the process is not being debugged. Otherwise it concludes it is running inside a debugger.

## gensandbox.c

Another interesting file for us is gensandbox.c. This file contains 12 functions that it uses to detect a sandbox. The first one, gensandbox_mouse_act() uses GetCursorPos() to determine the position of the mouse cursor and whether it is actively being used. According to MSDN this function “retrieves the position of the mouse cursor, in screen coordinates”. Now if you look at the function code that does the actual detection, you can see that the function first calls the GetCursorPos() function in order to receive cursor co-ordinates and saves them into the position1 variable. After that it sleeps for 2000 milliseconds (i.e. 2 seconds), and then calls the same function again, this time saving the coordinates into the position2 variable. Afterwards, the two samples of the x and y coordinates of the mouse cursor are compared to one other. This determines whether the mouse cursor has changed between the two GetCursorPos() function calls. If the position of the mouse cursor has not changed then there was no mouse activity during the sleep function. Under such circumstances, the code will conclude that it is being run within a sandbox.

Another interesting function in this file is gensandbox_username(). It uses the GetUserName function that retrieves the name of the user associated with the current thread. After that all the lower case letters are converted to upper case letters and the name is compared with the following strings:

• SANDBOX
• VIRUS
• MALWARE

The strstr() function is used to detect any occurrence of the presented strings in the username. If one of the strings above is found, it means that the program is being run inside a sandbox. Otherwise it returns FALSE. This method is highly questionable but gives us some insights on how one might either bypass it (if one was part of the “red team”) or create a better sandbox (if playing for the “blue team”).

The next function, called gensandbox_path(), is using GetModuleFileName(). According to MSDN this function “retrieves the fully qualified path for the file that contains the specified module. The module must have been loaded by the current process”.

Here, the strstr() function is used to check whether the retrieved path contains any of the strings:

• \\SAMPLE
• \\VIRUS
• SANDBOX

If that’s the case it concludes that it is running within a sandbox. Again, we can see multiple ways to improve this code and also get some ideas on how to apply this thinking to detect other environments even though, as you can see, it is a pretty basic technique.

gensandbox_common_names(), takes a similar approach but looks for the following strings instead:

• sample.exe
• malware.exe

Another interesting function is gensandbox_drive_size(). This checks if the first physical drive is larger than 60GB by using the CreateFile() and DeviceIoControl() functions. As we can read on MSDN, the CreateFile() function “creates or opens a file or I/O device. The most commonly used I/O devices are as follows: file, file stream, directory, physical disk, volume, console buffer, tape drive, communications resource, mailslot, and pipe. The function returns a handle that can be used to access the file or device for various types of I/O depending on the file or device and the flags and attributes specified”. Using a handle retrieved using the CreateFile() function call, the DeviceIoControl() function is used to send a control code directly to a specified device driver, causing the corresponding device to perform the IOCTL_DISK_GET_LENGTH_INFO operation.

Once again, this is tricky but it is almost always true these days. People don’t like to allocate that much disk space for their testing VMs.

Pafish also has a second function that plays with the size of the C drive, gensandbox_drive_size2(). It basically checks for the amount of free space on drive C. Again, this can be tricky, I’ve seen production servers (mostly databases) running out of space due to a lack of good sysadmin practices and bad planning. And yes… this happens a lot.

Another interesting function is gensandbox_uptime(). It uses GetTickCount() function to retrieve the number of milliseconds that have elapsed since the system was started (up to 49.7 days).

Once again, the assumption done here might be wrong if we think about laptops. Remember, the whole purpose of this analysis is to apply this code to our “red team” exercies, where desktop users are usually the target.

There are some more small functions inside gensandbox.c that I’d recommend you to have a look. These can also give some good insights to detect other sandboxes.

• gensandbox_sleep_patched()
• gensandbox_one_cpu()
• gensandbox_one_cpu_GetSystemInfo()
• gensandbox_less_than_onegb()
• gensandbox_IsNativeVhdBoot()

## hooks.c

The hooks.c source code only contains four small functions. Their aim is detect if any of the following functions have been hooked:

• DeleteFileW
• ShellExecuteExW
• CreateProcessA

Here’s the whole code:

Basically each one of the functions store the the address of the funtion (either DeleteFileW, ShellExecuteExW or CreateProcessA) into the dwAddress variable of the check_hook_m1() function.

Then it checks whether the first two bytes of the function are 0xff8b, which represent the assembly instruction for jump back instruction. Usually the functions create a new stack frame upon being called, but the jmp instruction at the beginning of a function clearly indicates the function has been hooked.

## vbox.c/vmware.c/qemu.c

The code to detect VirtualBox is quite extensive and there are multiple function that look for Windows Registry keys. Here are those functions.

The names and the code is prety self explanatory. The code is mostly based on the functions pafish_exists_regkey_value_str() and pafish_exists_regkey() and it can be foud on utils.c. Basically, it uses RegOpenKeyEx. If the function finds the specified registry entry it will return ERROR_SUCCESS. Otherwise a value of nonzero will be returned. As stated on MSDN, the RegOpenKeyEx() function “opens the specified registry key. Note that key names are not case sensitive”.

In the VirtualBox code there’s also some other interesting tricks. Like the function vbox_sysfile1(). This function basically looks for the presence of VirtualBox drivers installed on the system. See the code below:

On the same line of thinking you can find the function vbox_sysfile2(). Which basically looks for the presence of specific VirtualBox DLLs. Here is the actual code:

One of the tricks mostly common used is… yes, you guessed it. Check the MAC address identifier. Here’s the code that check’s for the OUI vendor:

The code for pafish_check_mac_vendor() can be found on the utils.c source file. Here’s the actual code:

There are a few more tricks on the vbox.c file that shouldn’t be ignored, but I’ll ignore them for now.

As you can imagine most of the code used to fingerprint VirtualBox is used in almost identical fashion to fingerprint VMware and Qemu.Basically, the code looks for specific Windows Registry keys, specific file paths, drivers and MAC vendor.

## bochs.c

One neat idea we spotted in terms of how Pafish fingerprints Bochs was to play with CPU specific featurs that are present in Bochs but not real CPU.

For example:

The first and third functions bochs_cpu_amd1() and bochs_cpu_intel1() will check for typos in the processor CPU string, whilst the second, bochs_cpu_amd2() triggers an assembly level easter egg that is present in the Bochs x86 CPU emulation.

## cuckoo.c

Cuckoo is an open source project and the hooks it implements are known. The code you can find on cuckoo.c is quite small and basically plays with Cuckoo TLS_HOOK_INFO. As a side note don’t forget that most Cuckoo set-ups use VirtualBox.

## sandboxie.c

The trick to detect Sandboxie is quite simple.

As you can see the function aboves tries to load the Sandboxie specific DLL called sbiedll.dll. If it succeeds Sandboxie is installed in the systems. Otherwise it is not. Pretty small test but quite effective.

## wine.c

The code to detect the Wine environment is also quite small. The first function is wine_detect_get_unix_file_name().

It starts by getting an handle to the kernel32.dll and then calling the GetProcAddress to retrieve the address of the function/variable wine_get_unix_file_name exported and available in the kernel32.dll. If the function succeeds it will return the address of the exported function, otherwise it will return NULL. Meaning that if doesn’t return NULL Wine has been fingerprinted and the wine_detect_get_unix_file_name returns TRUE.

The other function that Pafish implements is shown bellow.

Nothing new here, wine_reg_key1 simply looks for the presence of a Windows Registry key.

## Conclusion

This short introduction to Pafish code was meant to evaluate how the code can be applied to our Red Team Exercises. Since the code/checks are not too advanced and in some cases can be completely fooled, the code should be tweaked if we want to use it in our engagements. It also doesn’t make sense to include all the checks blindly, which means a good information gathering phase must be assured before any “red team” exercise.

Anyway these different methods of checking whether the program is running under a debugger, Virtual Machine or a sandbox might be quite useful if we want to develop code for a specific environment. Looking at Pafish code certainly improves our knowledge about how to bypass some sandboxes.

Based on the code I’ve read, the most common ways to identify that we are running in a virtualized environment (running inside a debugger is not that useful to us) are:

• Registry Checks
• Memory Checks
• Communication Checks (with the host)
• Processes and Files Checks
• Hardware

# RealVNC 4.1.0 and 4.1.1 - Authentication Bypass Exploit

This is quite old but I needed a working PoC to run in an environment where Metasploit couldn’t be used. Basically I ported hdmoore/msf2 perl version to python. It was quite fun, since this is basically a MiTM…

Exploit Code:

You can find it on exploit-db as well.

# HP Data Protector EXEC_SETUP Remote Code Execution (ZDI-11-056)

Gotta love HP. Full code execution, w00t. Software massively used in Portugal… oh dear…

Exploit Code: