(Please note some of the internal links are in Spanish)
One of the things that most caught our attention from the #NotPetya malware lab is the module that appears to contain code from the mimikatz tool. It is an automation of the process of any pentest that we believe is worth studying and treat it with love, to learn.
For the analysis we focus on the 32-bit version of the binary:
As he said on twitter, even the mimikatz developer finds similarities between the malware and mimikatz. Our first task is to identify the functions that are in the github of mimikatz and malware:
For example, we see the kuhl_m_sekurlsa_enum function:
In the github of mimikatz we see:
Another point that is observed simply by viewing the strings of the module is the following:
These strings give us an idea that the mimikatz sekurlsa module could work with the packages msv (credential hashes) and wdigest (clear credentials). On the other hand, the Primary and CredentialKeys strings are typical in any mimikatz output.
Once we have “mapped” the code with mimikatz functions, let’s see the logical structure of the malware. For this there is nothing like starting from the main, where we can see:
The first thing we see is that it calls a function we have named readPipe. In this function it receives as argument the pipe that has to instantiate, and where it will write the credentials later. This pipe, if you remember will be the one that will provide it the NotPetya dll . In this function it tries to access it three times and if it is not there, it leaves.
Then, as you see in the image, it retrieves the system version with the RtlGetNtVersionNumbers API, since that depending on the operating system the whole process that mimikatz performs to obtain the credentials varies in memory.
The next step is to obtain the appropriate privileges to access lsass.exe . To do so, from the interface of mimikatz we would do privilege::debug. The malware module will do so using the RtlAdjustPrivilege API. If we have executed it with enough privileges it will continue.
The next important step is the execution of the kuhl_m_sekurlsa_getLogonData() function, where the mimikatz logic starts. During the execution we see how the callback function kuhl_m_sekurlsa_enum() is the one that has been modified, as expected, since it is the point where mimikatz normally prints the credentials by screen. In this case we see the following:
The first thing that we find is a function that performs several checks to see if the credentials are good. As we have been able to verify in our environment, it did not dump the local credentials of the machine to the pipe (if someone can give us feedback on this subject we will thank you since we have not deepen into the code of this function, sub_13E31AB). On the other hand, we see that it has an if where it checks if the package corresponds with wdigest (credentials in clear text). Only in that case calls a1 , which corresponds to the function we have named dump2pipe:
As you can see there is a function inside this dump2pipe , which is dump_credentials , which is where you write to the pipe:
We can even see the format in which it will write to the pipe. Once we have studied the module to do a little PoC, we have created a very simple example of a program that creates a pipe and writes on the screen what is written on that pipe , in order to see the credentials of the machine.
In the following images you first have the original mimikatz window showing the credentials of the Administrator of the LAB domain (which had been authenticated in the machine in the past). In the second (right screeen) we have executed the malware module responsible for collecting the credentials. And below we have our program, which reads from the pipe and dumps it on the console (in this case we will see the credentials collected, this is what the malware will send to psexec).
I put the example that we used in case you want to play with the module:
As always, we hope this post helps you.
The mimi (mimikatz) side of #NotPetya
7 de July de 2017 Por