DirtyDecrypt analysis

chicchi

Level 1
Thread author
Jul 23, 2017
9
In terms of encrypting the file with its own API without using the attack target encryption API to encrypt the file,
I tried to analyze dirtydecrypt.
But,I could not find the place where file encryption processing is being done.
I analyzed using ollydbg this time.
People who know something tell me to tell.
I am in great trouble.

Thank you.
 
Last edited:
D

Deleted member 65228

How are you performing the analysis? For example... Static, dynamic or both?

I am not sure if this will help you however I recall reading about this ransomware before and some reverse engineering notes from others a few years ago; it might be packed with UPX and should drop other files to disk - you can check this out and analyse other dropped PEs if any can be found.
 
D

Deleted member 65228

hxxp://malwaredb.malekal.com/index.php?malware=zbot

Ctrl + F: "c02618dcfbf748c334bf30bf25c3ef9c" (MD5 hash of the sample from the VirusTotal report)
Uploaded on MalwareDB on: "Wed, 14 Aug 2013 22:07:56 +0200"

Download link: hxxp://malwaredb.malekal.com/files.php?file=c02618dcfbf748c334bf30bf25c3ef9c

I assume this is the sample you have been trying to analyse (same hash checksum).
 

chicchi

Level 1
Thread author
Jul 23, 2017
9
How are you performing the analysis? For example... Static, dynamic or both?

I am not sure if this will help you however I recall reading about this ransomware before and some reverse engineering notes from others a few years ago; it might be packed with UPX and should drop other files to disk - you can check this out and analyse other dropped PEs if any can be found.

thanks for your reply.

I am trying to analyze dynamically.

As a result of analysis once,
1.copying itself to several directories
2.DirtyDecrypt.exe executable file is placed in several directories


What I want to know is to find places where cryptographic processing is done.
Whether the copied itself is encrypting the file, DirtyDecrypt.exe is doing it,
I'm still a beginner and I do not know.
 
  • Like
Reactions: XhenEd
D

Deleted member 65228

thanks for your reply.

I am trying to analyze dynamically.

As a result of analysis once,
1.copying itself to several directories
2.DirtyDecrypt.exe executable file is placed in several directories


What I want to know is to find places where cryptographic processing is done.
Whether the copied itself is encrypting the file, DirtyDecrypt.exe is doing it,
I'm still a beginner and I do not know.
I couldn't get the sample to encrypt any files on my environment (I did however notice that it was opening handles to files on disk, and I could view that opened handles were for general documents and what-not); you could say it is related to potential Anti-VM identification (do you know if there is any?) however the sample still carried out other operations therefore I doubt this is the case, nor did I find evidence of that yet. The sample successfully performs activities such as disabling Windows programs (e.g. Task Manager) though.

The initial sample you are testing with will drop other samples to disk; these are used to perform different tasks. I setup detours on various functions to allow me to dynamically intercept specific actions such as process execution.

They appear to all be compiled in C++ (MFC) but I'll have to re-check this. DirtyDecrypt.exe is packed with UPX however you don't need to debug it with OllyDbg, wait for the unpacking in memory, dump to disk and then fix factors such as the Import Address Table to unpack it - using the -d command with upx.exe will be enough.

In case you were unaware about DirtyDecrypt.exe being packed, I have uploaded some of the files I found during some quick analysis. This includes the unpacked version of DirtyDecrypt.exe. Link:
Code:
hxxp://www63.zippyshare.com/v/FCZ8WImL/file.html

The initial launcher likes administrator rights, it will attempt to spawn cmd.exe elevated during execution flow so it can try to use it to re-start up the launcher elevated also (on default UAC settings an elevated process can elevate another process without another alert, and the user is more likely to allow a Windows program than an unknown one, which probably is the meaning behind this).

DirtyDecrypt.exe by default will hide and not show a GUI however if you restart its process which should be executing in memory silently after the launcher has been deployed for some time, it'll show its GUI. That is to do with arguments ("\hide" is used to prevent the GUI from being shown, you can find it at the executables WinMain function if I recall right). The GUI is used to accept payment methods. There should be a hotkey to cause it to display.
 
Last edited by a moderator:
D

Deleted member 65228

I'm still a beginner and I do not know.
Don't think like that! In the real world... we are all beginners because we all learn something new every-day. I am not experienced with ransomware analysis at all either, so I myself am learning more trying to help you too. At the end of the day, all that matters is that we all are on the same side (trying to fight malware and not assist its existence being maintained), its the taking part that counts! :)
 
D

Deleted member 65228

I found more time to look at the sample more, I will share some further findings with you.

1. The sample doesn't actually encrypt the files (apparently). It only appends data to them... When you open up an affected file it is intervened due to the data the sample injected into the victim files. This is why the wallpaper image is dropped to disk but never gets set for the actual Desktop wallpaper. This explains why I found it opening handles to files on the disk and reading the data/writing to them but the files not becoming encrypted (API call logging -> NtCreateFile, NtReadFile and NtWriteFile). I haven't even been able to get this functionality proven in my environment, this is based off old research I read while checking up about this threat last night.

2. The initial launcher is responsible for the file operations and getting other files dropped to disk. It is a fan of elevation therefore it will use cmd.exe to elevate it if it isn't ran with administrator rights initially. The idea behind this is the user might allow a Windows program (trusted) to run with administrator rights even if it is out of the blue compared to an untrusted unknown program.

The sample will attempt to enable privileges such as debugging rights, I will show some examples via disassembly/decompilation (in ASM/C) later on within this post.

3. DirtyDecrypt.exe takes arguments and depending on the argument it will show its GUI or not. It also registers a hotkey which will cause the GUI to be displayed if used.

The initial launcher was annoying me because I was trying to perform disassembly but wasn't getting anywhere at first and I couldn't understand why (the sample didn't appear to be packed with anything, just an MFC C++ compiled PE). In the end I moved to dynamic analysis for the time-being. Therefore I started monitoring various API calls I managed to log data which was a starting point for the analysis...

Originally I wanted to see the static imports but all I got was the following:
4iekAx.jpg


There are 312 static function imports there but I wasn't finding what I needed, nor everything which was going on. After multiple tests with the sample I knew it was using functions from other modules, so I stopped bothering with static at this point temporarily.


When the initial launcher starts up (c02618dcfbf748c334bf30bf25c3ef9c.exe) the DLLs it uses will be loaded into its address space. LdrLoadDll ends up being called of course for the DLL loading.


EMa8LC.jpg




I58Skp.jpg



In the end here is the list of modules:
Code:
C:\Windows\SysWOW64\advapi32.dll
C:\Windows\SysWOW64\apphelp.dll
C:\Windows\SysWOW64\bcryptprimitives.dll
C:\Windows\SysWOW64\cfgmgr32.dll
C:\Windows\SysWOW64\combase.dll
C:\Windows\SysWOW64\cryptbase.dll
C:\Windows\SysWOW64\gdi32.dll
C:\Windows\SysWOW64\gdi32full.dll
C:\Windows\SysWOW64\imm32.dll
C:\Windows\SysWOW64\kernel.appcore.dll
C:\Windows\SysWOW64\kernel32.dll
C:\Windows\SysWOW64\KernelBase.dll
C:\Windows\System32\locale.nls
C:\Windows\SysWOW64\mfc42.dll
C:\Windows\SysWOW64\en-US\MFC42.dll.mui
C:\Windows\SysWOW64\msvcp_win.dll
C:\Windows\SysWOW64\msvcrt.dll
C:\Windows\SysWOW64\ntdll.dll
C:\Windows\System32\ntdll.dll
C:\Windows\SysWOW64\ole32.dll
C:\Windows\SysWOW64\oleaut32.dll
C:\Windows\SysWOW64\powrprof.dll
C:\Windows\SysWOW64\profapi.dll
C:\Windows\SysWOW64\rpcrt4.dll
C:\Windows\SysWOW64\sechost.dll
C:\Windows\SysWOW64\SHCore.dll
C:\Windows\SysWOW64\shell32.dll
C:\Windows\SysWOW64\shlwapi.dll
C:\Windows\SysWOW64\sspicli.dll
C:\Windows\SysWOW64\ucrtbase.dll
C:\Windows\SysWOW64\user32.dll
C:\Windows\SysWOW64\uxtheme.dll
C:\Windows\SysWOW64\win32u.dll
C:\Windows\SysWOW64\windows.storage.dll
C:\Windows\System32\wow64.dll
C:\Windows\System32\wow64cpu.dll
C:\Windows\System32\wow64win.dll

After these standard initialisation operations, the sample will attempt to spawn a duplicate of itself in memory. The CreateProcess Win32 API function is called however there is more going on for this operation behind closed doors. To be precise, a manual detour on CreateProcessInternalW (undocumented Win32 API function, exported by kernel32.dll on earlier versions of Windows and kernelbase.dll on newer versions of Windows) was hit which made me aware of an process start-up attempt, and my break-point on NtResumeThread was triggered when the process was ready to have its main thread resumed to execute its code.

Don't be mistaken though. The file path might be the same but the process memory is not identical... Before the call to NtResumeThread is internally made by Windows for the process to start executing code, virtual memory operations occur with the newly starting process; memory allocation (VirtualAllocEx -> NtAllocateVirtualMemory) and memory writing (WriteProcessMemory -> NtWriteVirtualMemory).

Since I am intercepting both NtAllocateVirtualMemory and NtWriteVirtualMemory, I can make sense from the parameters. The allocation type is MEM_RESERVE and MEM_COMMIT, and the memory protection flag is PAGE_EXECUTE_READWRITE.


YieTKJ.jpg



You can read more about the parameters for memory allocation by looking at the VirtualAllocEx function which is available at MSDN or alternatively ZwAllocateVirtualMemory (driver routine documentation):
VirtualAllocEx function (Windows)
ZwAllocateVirtualMemory routine (Windows Drivers)

Take note of the BaseAddress parameter with the NtAllocateVirtualMemory call.

jHyBTw.jpg



After this call has been made, a call to NtWriteVirtualMemory is called as I have previously noted. Lets take a look at the parameters...

z0gX9n.jpg



Remember the BaseAddress we noted from the allocation operation? It was 0x00400000 in the target process. If we look at the above image, the BaseAddress parameter is also 0x00400000 for the target process. This means that bytes are being written to the memory that was previously allocated, and we can see that the size of the bytes written in total is 4096 (NumberOfBytesToWrite = 4096 & NumberOfBytesWritten = 4096 therefore it was successful).

The ProcessHandle parameter is also the same among both calls therefore we know that the target is the same process of course.

Here is the HEX output for the first memory write operation.

zCZpaT.jpg


Code:
4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 b8 00 00 00 00 00 00 00
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 d8 00 00 00 0e 1f ba 0e 00 b4 09 cd
21 b8 01 4c cd 21 54 68 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f
74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 6d 6f 64 65 2e 0d 0d 0a
24 00 00 00 00 00 00 00 73 c2 9e 24 37 a3 f0 77 37 a3 f0 77 37 a3 f0 77
f4 ac af 77 31 a3 f0 77 37 a3 f1 77 f3 a3 f0 77 f4 ac ad 77 38 a3 f0 77
10 65 82 77 2e a3 f0 77 10 65 8c 77 36 a3 f0 77 10 65 88 77 36 a3 f0 77
52 69 63 68 37 a3 f0 77 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50 45 00 00 4c 01 03 00 a5 2a ca 51 00 00 00 00 00 00 00 00 e0 00 03 01
0b 01 08 00 00 00 03 00 00 10 00 00 00 00 02 00 f0 ff 04 00 00 10 02 00
00 10 05 00 00 00 40 00 00 10 00 00 00 02 00 00 04 00 00 00 00 00 00 00
04 00 00 00 00 00 00 00 00 20 05 00 00 10 00 00 00 00 00 00 02 00 00 06
00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00 00 00 00 00 10 00 00 00
00 00 00 00 00 00 00 00 28 13 05 00 cc 01 00 00 00 10 05 00 28 03 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 55 50 58 30 00 00 00 00 00 00 02 00 00 10 00 00
00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 e0
55 50 58 31 00 00 00 00 00 00 03 00 00 10 02 00 00 f2 02 00 00 04 00 00
00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 e0 2e 72 73 72 63 00 00 00
00 10 00 00 00 10 05 00 00 06 00 00 00 f6 02 00 00 00 00 00 00 00 00 00
00 00 00 00 40 00 00 c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 33 2e 30 34 00 55 50 58 21 0d 09 08 0a a4 ed 1b c2 f9 09 48 bc
8d dc 04 00 e1 ef 02 00 00 e0 04 00 26 06 00 18

You can see the first two bytes are 4D 5A which is MZ. This is an identification of the file being a Portable Executable, of course there are other identifications but that is one of the very first. MZ is used for PE files to be executable. You can briefly see the DOS compatibility warning message which you will find among other executables and you may have noticed "UPX0" or "UPX1". The reason that is there could be for two reasons only: the sample is packed with UPX; or alternatively the sample is packed with something else but the attacker is trying to fool us into thinking it is UPX at first (because you can change the section names). Personally I think it was not the latter currently, but we'll see as we keep moving forward...

There are several calls to NtWriteVirtualMemory because the bytes are being written in stages. The bytes in HEX representation above is not enough alone of course.

I allowed the thread to be resumed and continued to log API calls however I suspended it quickly after monitoring some initialisation operations regarding module loading. Below is a list of the modules for the new version of the sample (process) in memory.
Code:
C:\Windows\SysWOW64\advapi32.dll
C:\Windows\SysWOW64\atl.dll
C:\Windows\SysWOW64\bcryptprimitives.dll
C:\Windows\SysWOW64\cfgmgr32.dll
C:\Windows\SysWOW64\clbcatq.dll
C:\Windows\SysWOW64\combase.dll
C:\Windows\SysWOW64\cryptbase.dll
C:\ProgramData\Microsoft\Windows\Caches\cversions.2.db
C:\ProgramData\Microsoft\Windows\Caches\cversions.2.db
C:\Windows\SysWOW64\edputil.dll
C:\Windows\SysWOW64\gdi32.dll
C:\Windows\SysWOW64\gdi32full.dll
C:\Windows\SysWOW64\iertutil.dll
C:\Windows\SysWOW64\imm32.dll
C:\Windows\SysWOW64\kernel.appcore.dll
C:\Windows\SysWOW64\kernel32.dll
C:\Windows\SysWOW64\KernelBase.dll
C:\Windows\System32\locale.nls
C:\Windows\SysWOW64\msvcp_win.dll
C:\Windows\SysWOW64\msvcrt.dll
C:\Windows\SysWOW64\netapi32.dll
C:\Windows\SysWOW64\netutils.dll
C:\Windows\SysWOW64\ntdll.dll
C:\Windows\System32\ntdll.dll
C:\Windows\SysWOW64\ntmarta.dll
C:\Windows\SysWOW64\ole32.dll
C:\Windows\SysWOW64\oleaut32.dll
C:\Windows\SysWOW64\powrprof.dll
C:\Windows\SysWOW64\profapi.dll
C:\Windows\SysWOW64\propsys.dll
C:\Windows\SysWOW64\rpcrt4.dll
C:\Windows\SysWOW64\samcli.dll
C:\Windows\SysWOW64\sechost.dll
C:\Windows\SysWOW64\SHCore.dll
C:\Windows\SysWOW64\shell32.dll
C:\Windows\SysWOW64\shlwapi.dll
C:\Windows\SysWOW64\sspicli.dll
C:\Windows\SysWOW64\StateRepository.Core.dll
C:\Windows\SysWOW64\ucrtbase.dll
C:\Windows\SysWOW64\urlmon.dll
C:\Windows\SysWOW64\user32.dll
C:\Windows\SysWOW64\uxtheme.dll
C:\Windows\SysWOW64\win32u.dll
C:\Windows\SysWOW64\Windows.StateRepository.dll
C:\Windows\SysWOW64\windows.storage.dll
C:\Windows\System32\wow64.dll
C:\Windows\System32\wow64cpu.dll
C:\Windows\System32\wow64win.dll
C:\Windows\SysWOW64\ws2_32.dll

There are definitely differences with the modules between the original process for the sample and the duplicate. After the new process has been successfully started up, the original one is closed down in memory.

Moving on, one of the first things the sample will do after the duplicate modified copy is running is create a registry key.

TrGKkJ.jpg




The sample will drop files to disk. Two files will be placed in AppData\\Local\\Temp (Temp folder): hHxcwHhd.exe and nNUCNjFw.exe.

Both dropped files are 312 bytes in size. They are both the same; the MD5 hash is c02618dcfbf748c334bf30bf25c3ef9c

Plot twist. Both the dropped samples to the Temp folder are the same as the initial launcher. Same hash, size, icon, everything.

The sample will add the hHxcwHhd.exe to start-up via the registry with HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run.


ln8YRE.jpg




ZdmSCA.jpg



Orhced.jpg




Previously the sample had dropped another file to disk, called xeKPZbZN.exe (which was not grouped with the other two file drops earlier). It was dropped in a folder present within Program Files (x86). The sample will hijack the Winlogon key (HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon) by modifying the value within Userinit, appending xeKPZbZN.exe to the value.


hpcvmt.jpg


wvfWCp.jpg


gzNBMo.jpg



xeKPZbZN.exe is also the same initial launcher based on file hash checksum and file size/icon.

Anyway, I decided to speed things up considering this threat has been known since 2013 and is heavily detected by AV vendors. Time to cut straight to the point regarding file operations in terms of affecting the user... I gathered since this initialisation has all been done, if I terminated the current process and re-ran the original launcher it would be ready to do something. I was right.

Some other files are dropped to disk, nothing new. DirtyDecrypt.exe is started up in memory but it sits patiently and doesn't do anything, the launcher on the other hand will perform operations for the time being.

The sample will start enumerating through files on the system, opening handles and performing write operations if its interested in them. Here is an example.


pqVs9b.jpg



I could directly see with Process Hacker the new handle creations and then closing of them afterwards, and I could see from the API monitoring logs that it was writing to the acquired handles occasionally. However, the documents in my environment do not seem to be affected to an inoperable way. The file enumeration might be broken for me because it has been constantly re-opening handles in the same areas constantly for over half an hour.


fuxDMo.jpg




The threat will block some analysis tools you may attempt to use. As an example, when I tried to spawn procmon (from SysInternals), the sample identified the start-up and tried to open a handle to the process with access rights PROCESS_TERMINATE. Once it had acquired the handle, it terminated it with TerminateProcess.

GYWSor.jpg



UDdvsc.jpg



I had enough of watching the launcher do the same thing over and over again over a prolonged duration so I forcefully terminated it. Enough with that process.

DirtyDecrypt.exe is still running but it doesn't do anything yet, it is actually a Win32 GUI program.

8WmSsy.jpg


If you restart it, it won't have an argument for "/hide" and the GUI will be displayed.

n7SOQC.jpg



You can see the file path to DirtyDecrypt.exe in one of the above images, it was dropped to AppData\Roaming\Dirty.

There's a DirtyDecrypt.exe file under the Local folder for AppData as well.


B7SqFb.jpg


8FYdEy.jpg



It appears that the alertwall.jpg should be displayed when affected documents are ran but as I have already stated, the files maintain usability without the interruption after testing out the sample in my environment.

DirtyDecrypt.exe is compressed with UPX however using -d with upx.exe is sufficient. There is no need to use OllyDbg with DirtyDecrypt.exe for dumping to disk (and then fixing the header/re-building IAT).


8KacmV.jpg


HTwyC0.jpg



Now the sample has been unpacked you'll be able to analyse DirtyDecrypt.exe through disassembly properly. Here is a list of the static imports.

Code:
Address  Ordinal Name                                                 Library
-------  ------- ----                                                 -------
0040C000         RegCreateKeyExW                                      ADVAPI32
0040C004         CryptDestroyKey                                      ADVAPI32
0040C008         AdjustTokenPrivileges                                ADVAPI32
0040C00C         ConvertStringSecurityDescriptorToSecurityDescriptorW ADVAPI32
0040C010         LookupPrivilegeValueW                                ADVAPI32
0040C014         OpenProcessToken                                     ADVAPI32
0040C018         RegSetValueExW                                       ADVAPI32
0040C01C         RegCloseKey                                          ADVAPI32
0040C020         RegOpenKeyExW                                        ADVAPI32
0040C024         RegQueryValueExW                                     ADVAPI32
0040C028         CryptDecrypt                                         ADVAPI32
0040C02C         CryptHashData                                        ADVAPI32
0040C030         CryptDestroyHash                                     ADVAPI32
0040C034         CryptCreateHash                                      ADVAPI32
0040C038         CryptEncrypt                                         ADVAPI32
0040C03C         CryptImportKey                                       ADVAPI32
0040C040         CryptGetProvParam                                    ADVAPI32
0040C044         CryptAcquireContextA                                 ADVAPI32
0040C048         CryptAcquireContextW                                 ADVAPI32
0040C04C         CryptVerifySignatureW                                ADVAPI32
0040C050         CryptGetKeyParam                                     ADVAPI32
0040C054         CryptReleaseContext                                  ADVAPI32
0040C05C         InitCommonControlsEx                                 COMCTL32
0040C064         SetTextColor                                         GDI32  
0040C068         GetTextMetricsW                                      GDI32  
0040C06C         DeleteObject                                         GDI32  
0040C070         SelectObject                                         GDI32  
0040C074         GetStockObject                                       GDI32  
0040C078         SetBkMode                                            GDI32  
0040C07C         CreateFontIndirectW                                  GDI32  
0040C084         GetSystemDirectoryW                                  KERNEL32
0040C088         CopyFileW                                            KERNEL32
0040C08C         GetFileAttributesW                                   KERNEL32
0040C090         ReadFile                                             KERNEL32
0040C094         GetModuleFileNameW                                   KERNEL32
0040C098         CreateFileW                                          KERNEL32
0040C09C         GetTempPathW                                         KERNEL32
0040C0A0         GetLastError                                         KERNEL32
0040C0A4         LockFileEx                                           KERNEL32
0040C0A8         FindClose                                            KERNEL32
0040C0AC         RemoveDirectoryW                                     KERNEL32
0040C0B0         FindNextFileW                                        KERNEL32
0040C0B4         GetFileTime                                          KERNEL32
0040C0B8         GetDiskFreeSpaceExW                                  KERNEL32
0040C0BC         CloseHandle                                          KERNEL32
0040C0C0         DeleteFileW                                          KERNEL32
0040C0C4         SetFileAttributesW                                   KERNEL32
0040C0C8         GetVolumeInformationW                                KERNEL32
0040C0CC         HeapReAlloc                                          KERNEL32
0040C0D0         WriteFile                                            KERNEL32
0040C0D4         HeapFree                                             KERNEL32
0040C0D8         GetProcessHeap                                       KERNEL32
0040C0DC         HeapDestroy                                          KERNEL32
0040C0E0         HeapCreate                                           KERNEL32
0040C0E4         GetModuleHandleW                                     KERNEL32
0040C0E8         LoadLibraryW                                         KERNEL32
0040C0EC         GetProcAddress                                       KERNEL32
0040C0F0         Process32FirstW                                      KERNEL32
0040C0F4         Process32NextW                                       KERNEL32
0040C0F8         CreateToolhelp32Snapshot                             KERNEL32
0040C0FC         FindResourceW                                        KERNEL32
0040C100         LoadResource                                         KERNEL32
0040C104         SizeofResource                                       KERNEL32
0040C108         LockResource                                         KERNEL32
0040C10C         SetErrorMode                                         KERNEL32
0040C110         GetCurrentProcess                                    KERNEL32
0040C114         LocalAlloc                                           KERNEL32
0040C118         LocalFree                                            KERNEL32
0040C11C         lstrcmpA                                             KERNEL32
0040C120         lstrlenA                                             KERNEL32
0040C124         lstrcpynA                                            KERNEL32
0040C128         WideCharToMultiByte                                  KERNEL32
0040C12C         lstrcpynW                                            KERNEL32
0040C130         lstrcatA                                             KERNEL32
0040C134         CompareStringW                                       KERNEL32
0040C138         lstrlenW                                             KERNEL32
0040C13C         lstrcatW                                             KERNEL32
0040C140         CompareStringA                                       KERNEL32
0040C144         lstrcpyW                                             KERNEL32
0040C148         lstrcpyA                                             KERNEL32
0040C14C         CreateMutexW                                         KERNEL32
0040C150         WaitForSingleObject                                  KERNEL32
0040C154         SetEvent                                             KERNEL32
0040C158         ResetEvent                                           KERNEL32
0040C15C         CreateEventW                                         KERNEL32
0040C160         SetFileTime                                          KERNEL32
0040C164         ReleaseMutex                                         KERNEL32
0040C168         CreateThread                                         KERNEL32
0040C16C         FreeLibrary                                          KERNEL32
0040C170         GetSystemDirectoryA                                  KERNEL32
0040C174         LoadLibraryA                                         KERNEL32
0040C178         UnlockFileEx                                         KERNEL32
0040C17C         CreateDirectoryW                                     KERNEL32
0040C180         GetLogicalDriveStringsW                              KERNEL32
0040C184         SetEndOfFile                                         KERNEL32
0040C188         GetDriveTypeW                                        KERNEL32
0040C18C         SetFilePointer                                       KERNEL32
0040C190         FindFirstFileW                                       KERNEL32
0040C194         GetFileSize                                          KERNEL32
0040C198         GlobalAddAtomW                                       KERNEL32
0040C19C         GlobalDeleteAtom                                     KERNEL32
0040C1A0         GetCommandLineW                                      KERNEL32
0040C1A4         ExitProcess                                          KERNEL32
0040C1A8         Sleep                                                KERNEL32
0040C1AC         DeleteCriticalSection                                KERNEL32
0040C1B0         EnterCriticalSection                                 KERNEL32
0040C1B4         LeaveCriticalSection                                 KERNEL32
0040C1B8         InitializeCriticalSection                            KERNEL32
0040C1BC         GetTickCount                                         KERNEL32
0040C1C0         HeapAlloc                                            KERNEL32
0040C1C4         WaitForMultipleObjects                               KERNEL32
0040C1CC         ShellExecuteW                                        SHELL32
0040C1D4         DrawTextW                                            USER32
0040C1D8         PostMessageW                                         USER32
0040C1DC         UnregisterClassW                                     USER32
0040C1E0         PostQuitMessage                                      USER32
0040C1E4         GetMessageW                                          USER32
0040C1E8         GetWindowRect                                        USER32
0040C1EC         ScreenToClient                                       USER32
0040C1F0         SetTimer                                             USER32
0040C1F4         GetWindowTextLengthW                                 USER32
0040C1F8         DestroyWindow                                        USER32
0040C1FC         GetWindowThreadProcessId                             USER32
0040C200         IsWindowVisible                                      USER32
0040C204         GetClassNameW                                        USER32
0040C208         KillTimer                                            USER32
0040C20C         LoadCursorW                                          USER32
0040C210         GetDC                                                USER32
0040C214         TranslateMessage                                     USER32
0040C218         RegisterClassExW                                     USER32
0040C21C         LoadIconW                                            USER32
0040C220         InvalidateRect                                       USER32
0040C224         GetWindowTextW                                       USER32
0040C228         DispatchMessageW                                     USER32
0040C22C         DefWindowProcW                                       USER32
0040C230         ReleaseDC                                            USER32
0040C234         GetDlgItem                                           USER32
0040C238         SetWindowPos                                         USER32
0040C23C         ShowWindow                                           USER32
0040C240         FindWindowExW                                        USER32
0040C244         CreateWindowExW                                      USER32
0040C248         MessageBoxW                                          USER32
0040C24C         SetDlgItemTextW                                      USER32
0040C250         SendMessageW                                         USER32
0040C254         UpdateWindow                                         USER32
0040C258         EnableWindow                                         USER32
0040C25C         UnregisterHotKey                                     USER32
0040C260         RegisterHotKey                                       USER32
0040C268 5       getpeername                                          WS2_32
0040C26C         WSAIoctl                                             WS2_32
0040C270 4       connect                                              WS2_32
0040C274 12      inet_ntoa                                            WS2_32
0040C278 115     WSAStartup                                           WS2_32
0040C27C 11      inet_addr                                            WS2_32
0040C280 8       htonl                                                WS2_32
0040C284 18      select                                               WS2_32
0040C288 111     WSAGetLastError                                      WS2_32
0040C28C 9       htons                                                WS2_32
0040C290 22      shutdown                                             WS2_32
0040C294 116     WSACleanup                                           WS2_32
0040C298 16      recv                                                 WS2_32
0040C29C 23      socket                                               WS2_32
0040C2A0 55      getservbyname                                        WS2_32
0040C2A4 112     WSASetLastError                                      WS2_32
0040C2A8 3       closesocket                                          WS2_32
0040C2AC 52      gethostbyname                                        WS2_32
0040C2B0 19      send                                                 WS2_32
0040C2B8         GetOpenFileNameW                                     comdlg32

The sample will attempt to enable additional privileges through process tokens. You may notice the function AdjustTokenPrivileges from the static imports list.

TVOlEM.jpg


WHn9pC.jpg


I found where the function was called, here is the disassembly and the pseudo-code for the function.

2TBFfV.jpg


xqmkta.jpg



We can check where the function is being called, only from within one function in the program.


i61mwP.jpg



Lets view the function.

d63WT0.jpg


The function used for adjusting token privileges accepted parameters, and we can see it being called from within the function above with parameters. It appears the sample will attempt to gain SeSecurityPrivilege, SeDebugPrivilege and SeTcbPrivilege.

If we go back to the imports we can find some functions from advapi32.dll related to encryption (or it seems). Lets take a look at some.

zMr4Uu.jpg


tMPG0i.jpg


gj4h9D.jpg


ydnoBK.jpg




We can even find file enumeration by tracing the use of imports.

xhlkQd.jpg




xhlkQd.jpg



-------------------------------------------
@chicchi I apologise about this not being what you were after, I was unable to get the sample to affect files on the environment. Does it do this for you? I can find evidence of it scanning through the documents, even opening handles with write access, and doing many other things... other than causing harm to the documents. I could go back and check the NtWriteFile calls and see if I made a mistake while checking if it did append but just didn't work to how it was supposed to but I don't see the point at this moment. There is no doubt that the sample is malware, and it is heavily detected of course (originated in 2013). I'm not even very good with cryptography/ransomware.

You can dig deeper if you'd like and find out more, hopefully this still helped you though in some way. I gather you've been looking into this sample for awhile before commenting so if I got any details wrong here please correct them - been writing for hours without break so the quality may degrade as you continue reading but I guess I didn't do too bad at checking things.

If you do end up finding what you are after (encryption functionality) assuming it works in your environment (if it is present in this sample - maybe it is just broken for me and someone else I had test it in their environment also) please let us know as it'd be educational if you don't mind.

PS: The initial launcher is also pumped (check in HxD). Use a debugger to make it easier for following operations and analysing before more are performed... I prefer API monitoring in these cases but it can be troublesome sometimes as well and can cause you to miss things. ;)

Thanks for reading, good luck! :)



-
 

Attachments

  • 1.png
    1.png
    100.4 KB · Views: 458
  • 2.png
    2.png
    32.1 KB · Views: 508
  • 3.png
    3.png
    11.8 KB · Views: 536
  • 4.png
    4.png
    8.6 KB · Views: 495
  • 5.png
    5.png
    10.7 KB · Views: 505
  • 6.png
    6.png
    10.7 KB · Views: 514
  • 7.png
    7.png
    16.4 KB · Views: 504
  • 8.png
    8.png
    13.2 KB · Views: 480
  • 9.png
    9.png
    21.1 KB · Views: 512
  • 10.png
    10.png
    12.4 KB · Views: 579
  • 11.png
    11.png
    53.1 KB · Views: 539
  • 12.png
    12.png
    20.3 KB · Views: 517
  • 13.png
    13.png
    11.7 KB · Views: 537
  • 14.png
    14.png
    36.3 KB · Views: 514
  • 15.png
    15.png
    15.5 KB · Views: 523
  • 16.png
    16.png
    58.8 KB · Views: 583
  • 17.png
    17.png
    10 KB · Views: 569
  • 18.png
    18.png
    2.2 KB · Views: 594
  • 19.png
    19.png
    28.2 KB · Views: 550
  • 20.png
    20.png
    10.6 KB · Views: 485
  • 21.png
    21.png
    5 KB · Views: 546
  • 22.png
    22.png
    83.1 KB · Views: 398
  • 23.png
    23.png
    36.7 KB · Views: 398
  • 24.png
    24.png
    14.1 KB · Views: 508
  • 25.png
    25.png
    22.2 KB · Views: 478
  • 26.png
    26.png
    31 KB · Views: 524
  • 27.png
    27.png
    9.7 KB · Views: 533
  • 28.png
    28.png
    13 KB · Views: 524
  • 29.png
    29.png
    8.6 KB · Views: 537
  • 30.png
    30.png
    35.8 KB · Views: 532
  • 31.png
    31.png
    15.3 KB · Views: 550
  • 32.png
    32.png
    11.6 KB · Views: 535
  • 33.png
    33.png
    4.8 KB · Views: 552
  • 34.png
    34.png
    27 KB · Views: 506
  • 35.png
    35.png
    21 KB · Views: 365
D

Deleted member 65228

@Opcode Really nice job. Really extensive but easy to read analysis :)
Merci!

The threat will block some analysis tools you may attempt to use.
By default on Windows 10 there might not be a modifiable value which can be changed to disable Task Manager however it can be manually set-up and will work just fine. I came back to this thread to note this because I suddenly remembered that the key/value didn't exist in the past by default, and that the sample used the registry trick to disable access to Task Manager.

Key:
Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System

Name:
DisableTaskMgr (type DWORD)

Values:
0 = enabled
1 = disabled


If the value is in-existent, or even if the System key under Policies is not there, it'll be enabled by default. (On my Host system I had to manually create the System key under Policies).

I am not sure if it works for all Windows versions although I doubt it wouldn't. I'm on Windows 10 Professional though. Could someone on Windows 10 Home let me know if it works for them too?
 
Last edited by a moderator:

Andy Ful

From Hard_Configurator Tools
Verified
Honorary Member
Top Poster
Developer
Well-known
Dec 23, 2014
8,042
Merci!


By default on Windows 10 there might not be a modifiable value which can be changed to disable Task Manager however it can be manually set-up and will work just fine. I came back to this thread to note this because I suddenly remembered that the key/value didn't exist in the past by default, and that the sample used the registry trick to disable access to Task Manager.

Key:
Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System

Name:
DisableTaskMgr (type DWORD)

Values:
0 = enabled
1 = disabled


If the value is in-existent, or even if the System key under Policies is not there, it'll be enabled by default. (On my Host system I had to manually create the System key under Policies).

I am not sure if it works for all Windows versions although I doubt it wouldn't. I'm on Windows 10 Professional though. Could someone on Windows 10 Home let me know if it works for them too?
It works for all Windows versions since XP:
https://support.microsoft.com/en-us/help/555480
 

chicchi

Level 1
Thread author
Jul 23, 2017
9
I found more time to look at the sample more, I will share some further findings with you.

1. The sample doesn't actually encrypt the files (apparently). It only appends data to them... When you open up an affected file it is intervened due to the data the sample injected into the victim files. This is why the wallpaper image is dropped to disk but never gets set for the actual Desktop wallpaper. This explains why I found it opening handles to files on the disk and reading the data/writing to them but the files not becoming encrypted (API call logging -> NtCreateFile, NtReadFile and NtWriteFile). I haven't even been able to get this functionality proven in my environment, this is based off old research I read while checking up about this threat last night.

2. The initial launcher is responsible for the file operations and getting other files dropped to disk. It is a fan of elevation therefore it will use cmd.exe to elevate it if it isn't ran with administrator rights initially. The idea behind this is the user might allow a Windows program (trusted) to run with administrator rights even if it is out of the blue compared to an untrusted unknown program.

The sample will attempt to enable privileges such as debugging rights, I will show some examples via disassembly/decompilation (in ASM/C) later on within this post.

3. DirtyDecrypt.exe takes arguments and depending on the argument it will show its GUI or not. It also registers a hotkey which will cause the GUI to be displayed if used.

The initial launcher was annoying me because I was trying to perform disassembly but wasn't getting anywhere at first and I couldn't understand why (the sample didn't appear to be packed with anything, just an MFC C++ compiled PE). In the end I moved to dynamic analysis for the time-being. Therefore I started monitoring various API calls I managed to log data which was a starting point for the analysis...

Originally I wanted to see the static imports but all I got was the following:
4iekAx.jpg


There are 312 static function imports there but I wasn't finding what I needed, nor everything which was going on. After multiple tests with the sample I knew it was using functions from other modules, so I stopped bothering with static at this point temporarily.


When the initial launcher starts up (c02618dcfbf748c334bf30bf25c3ef9c.exe) the DLLs it uses will be loaded into its address space. LdrLoadDll ends up being called of course for the DLL loading.


EMa8LC.jpg




I58Skp.jpg



In the end here is the list of modules:
Code:
C:\Windows\SysWOW64\advapi32.dll
C:\Windows\SysWOW64\apphelp.dll
C:\Windows\SysWOW64\bcryptprimitives.dll
C:\Windows\SysWOW64\cfgmgr32.dll
C:\Windows\SysWOW64\combase.dll
C:\Windows\SysWOW64\cryptbase.dll
C:\Windows\SysWOW64\gdi32.dll
C:\Windows\SysWOW64\gdi32full.dll
C:\Windows\SysWOW64\imm32.dll
C:\Windows\SysWOW64\kernel.appcore.dll
C:\Windows\SysWOW64\kernel32.dll
C:\Windows\SysWOW64\KernelBase.dll
C:\Windows\System32\locale.nls
C:\Windows\SysWOW64\mfc42.dll
C:\Windows\SysWOW64\en-US\MFC42.dll.mui
C:\Windows\SysWOW64\msvcp_win.dll
C:\Windows\SysWOW64\msvcrt.dll
C:\Windows\SysWOW64\ntdll.dll
C:\Windows\System32\ntdll.dll
C:\Windows\SysWOW64\ole32.dll
C:\Windows\SysWOW64\oleaut32.dll
C:\Windows\SysWOW64\powrprof.dll
C:\Windows\SysWOW64\profapi.dll
C:\Windows\SysWOW64\rpcrt4.dll
C:\Windows\SysWOW64\sechost.dll
C:\Windows\SysWOW64\SHCore.dll
C:\Windows\SysWOW64\shell32.dll
C:\Windows\SysWOW64\shlwapi.dll
C:\Windows\SysWOW64\sspicli.dll
C:\Windows\SysWOW64\ucrtbase.dll
C:\Windows\SysWOW64\user32.dll
C:\Windows\SysWOW64\uxtheme.dll
C:\Windows\SysWOW64\win32u.dll
C:\Windows\SysWOW64\windows.storage.dll
C:\Windows\System32\wow64.dll
C:\Windows\System32\wow64cpu.dll
C:\Windows\System32\wow64win.dll

After these standard initialisation operations, the sample will attempt to spawn a duplicate of itself in memory. The CreateProcess Win32 API function is called however there is more going on for this operation behind closed doors. To be precise, a manual detour on CreateProcessInternalW (undocumented Win32 API function, exported by kernel32.dll on earlier versions of Windows and kernelbase.dll on newer versions of Windows) was hit which made me aware of an process start-up attempt, and my break-point on NtResumeThread was triggered when the process was ready to have its main thread resumed to execute its code.

Don't be mistaken though. The file path might be the same but the process memory is not identical... Before the call to NtResumeThread is internally made by Windows for the process to start executing code, virtual memory operations occur with the newly starting process; memory allocation (VirtualAllocEx -> NtAllocateVirtualMemory) and memory writing (WriteProcessMemory -> NtWriteVirtualMemory).

Since I am intercepting both NtAllocateVirtualMemory and NtWriteVirtualMemory, I can make sense from the parameters. The allocation type is MEM_RESERVE and MEM_COMMIT, and the memory protection flag is PAGE_EXECUTE_READWRITE.


YieTKJ.jpg



You can read more about the parameters for memory allocation by looking at the VirtualAllocEx function which is available at MSDN or alternatively ZwAllocateVirtualMemory (driver routine documentation):
VirtualAllocEx function (Windows)
ZwAllocateVirtualMemory routine (Windows Drivers)

Take note of the BaseAddress parameter with the NtAllocateVirtualMemory call.

jHyBTw.jpg



After this call has been made, a call to NtWriteVirtualMemory is called as I have previously noted. Lets take a look at the parameters...

z0gX9n.jpg



Remember the BaseAddress we noted from the allocation operation? It was 0x00400000 in the target process. If we look at the above image, the BaseAddress parameter is also 0x00400000 for the target process. This means that bytes are being written to the memory that was previously allocated, and we can see that the size of the bytes written in total is 4096 (NumberOfBytesToWrite = 4096 & NumberOfBytesWritten = 4096 therefore it was successful).

The ProcessHandle parameter is also the same among both calls therefore we know that the target is the same process of course.

Here is the HEX output for the first memory write operation.

zCZpaT.jpg


Code:
4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 b8 00 00 00 00 00 00 00
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 d8 00 00 00 0e 1f ba 0e 00 b4 09 cd
21 b8 01 4c cd 21 54 68 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f
74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 6d 6f 64 65 2e 0d 0d 0a
24 00 00 00 00 00 00 00 73 c2 9e 24 37 a3 f0 77 37 a3 f0 77 37 a3 f0 77
f4 ac af 77 31 a3 f0 77 37 a3 f1 77 f3 a3 f0 77 f4 ac ad 77 38 a3 f0 77
10 65 82 77 2e a3 f0 77 10 65 8c 77 36 a3 f0 77 10 65 88 77 36 a3 f0 77
52 69 63 68 37 a3 f0 77 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50 45 00 00 4c 01 03 00 a5 2a ca 51 00 00 00 00 00 00 00 00 e0 00 03 01
0b 01 08 00 00 00 03 00 00 10 00 00 00 00 02 00 f0 ff 04 00 00 10 02 00
00 10 05 00 00 00 40 00 00 10 00 00 00 02 00 00 04 00 00 00 00 00 00 00
04 00 00 00 00 00 00 00 00 20 05 00 00 10 00 00 00 00 00 00 02 00 00 06
00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00 00 00 00 00 10 00 00 00
00 00 00 00 00 00 00 00 28 13 05 00 cc 01 00 00 00 10 05 00 28 03 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 55 50 58 30 00 00 00 00 00 00 02 00 00 10 00 00
00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 e0
55 50 58 31 00 00 00 00 00 00 03 00 00 10 02 00 00 f2 02 00 00 04 00 00
00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 e0 2e 72 73 72 63 00 00 00
00 10 00 00 00 10 05 00 00 06 00 00 00 f6 02 00 00 00 00 00 00 00 00 00
00 00 00 00 40 00 00 c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 33 2e 30 34 00 55 50 58 21 0d 09 08 0a a4 ed 1b c2 f9 09 48 bc
8d dc 04 00 e1 ef 02 00 00 e0 04 00 26 06 00 18

You can see the first two bytes are 4D 5A which is MZ. This is an identification of the file being a Portable Executable, of course there are other identifications but that is one of the very first. MZ is used for PE files to be executable. You can briefly see the DOS compatibility warning message which you will find among other executables and you may have noticed "UPX0" or "UPX1". The reason that is there could be for two reasons only: the sample is packed with UPX; or alternatively the sample is packed with something else but the attacker is trying to fool us into thinking it is UPX at first (because you can change the section names). Personally I think it was not the latter currently, but we'll see as we keep moving forward...

There are several calls to NtWriteVirtualMemory because the bytes are being written in stages. The bytes in HEX representation above is not enough alone of course.

I allowed the thread to be resumed and continued to log API calls however I suspended it quickly after monitoring some initialisation operations regarding module loading. Below is a list of the modules for the new version of the sample (process) in memory.
Code:
C:\Windows\SysWOW64\advapi32.dll
C:\Windows\SysWOW64\atl.dll
C:\Windows\SysWOW64\bcryptprimitives.dll
C:\Windows\SysWOW64\cfgmgr32.dll
C:\Windows\SysWOW64\clbcatq.dll
C:\Windows\SysWOW64\combase.dll
C:\Windows\SysWOW64\cryptbase.dll
C:\ProgramData\Microsoft\Windows\Caches\cversions.2.db
C:\ProgramData\Microsoft\Windows\Caches\cversions.2.db
C:\Windows\SysWOW64\edputil.dll
C:\Windows\SysWOW64\gdi32.dll
C:\Windows\SysWOW64\gdi32full.dll
C:\Windows\SysWOW64\iertutil.dll
C:\Windows\SysWOW64\imm32.dll
C:\Windows\SysWOW64\kernel.appcore.dll
C:\Windows\SysWOW64\kernel32.dll
C:\Windows\SysWOW64\KernelBase.dll
C:\Windows\System32\locale.nls
C:\Windows\SysWOW64\msvcp_win.dll
C:\Windows\SysWOW64\msvcrt.dll
C:\Windows\SysWOW64\netapi32.dll
C:\Windows\SysWOW64\netutils.dll
C:\Windows\SysWOW64\ntdll.dll
C:\Windows\System32\ntdll.dll
C:\Windows\SysWOW64\ntmarta.dll
C:\Windows\SysWOW64\ole32.dll
C:\Windows\SysWOW64\oleaut32.dll
C:\Windows\SysWOW64\powrprof.dll
C:\Windows\SysWOW64\profapi.dll
C:\Windows\SysWOW64\propsys.dll
C:\Windows\SysWOW64\rpcrt4.dll
C:\Windows\SysWOW64\samcli.dll
C:\Windows\SysWOW64\sechost.dll
C:\Windows\SysWOW64\SHCore.dll
C:\Windows\SysWOW64\shell32.dll
C:\Windows\SysWOW64\shlwapi.dll
C:\Windows\SysWOW64\sspicli.dll
C:\Windows\SysWOW64\StateRepository.Core.dll
C:\Windows\SysWOW64\ucrtbase.dll
C:\Windows\SysWOW64\urlmon.dll
C:\Windows\SysWOW64\user32.dll
C:\Windows\SysWOW64\uxtheme.dll
C:\Windows\SysWOW64\win32u.dll
C:\Windows\SysWOW64\Windows.StateRepository.dll
C:\Windows\SysWOW64\windows.storage.dll
C:\Windows\System32\wow64.dll
C:\Windows\System32\wow64cpu.dll
C:\Windows\System32\wow64win.dll
C:\Windows\SysWOW64\ws2_32.dll

There are definitely differences with the modules between the original process for the sample and the duplicate. After the new process has been successfully started up, the original one is closed down in memory.

Moving on, one of the first things the sample will do after the duplicate modified copy is running is create a registry key.

TrGKkJ.jpg




The sample will drop files to disk. Two files will be placed in AppData\\Local\\Temp (Temp folder): hHxcwHhd.exe and nNUCNjFw.exe.

Both dropped files are 312 bytes in size. They are both the same; the MD5 hash is c02618dcfbf748c334bf30bf25c3ef9c

Plot twist. Both the dropped samples to the Temp folder are the same as the initial launcher. Same hash, size, icon, everything.

The sample will add the hHxcwHhd.exe to start-up via the registry with HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run.


ln8YRE.jpg




ZdmSCA.jpg



Orhced.jpg




Previously the sample had dropped another file to disk, called xeKPZbZN.exe (which was not grouped with the other two file drops earlier). It was dropped in a folder present within Program Files (x86). The sample will hijack the Winlogon key (HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon) by modifying the value within Userinit, appending xeKPZbZN.exe to the value.


hpcvmt.jpg


wvfWCp.jpg


gzNBMo.jpg



xeKPZbZN.exe is also the same initial launcher based on file hash checksum and file size/icon.

Anyway, I decided to speed things up considering this threat has been known since 2013 and is heavily detected by AV vendors. Time to cut straight to the point regarding file operations in terms of affecting the user... I gathered since this initialisation has all been done, if I terminated the current process and re-ran the original launcher it would be ready to do something. I was right.

Some other files are dropped to disk, nothing new. DirtyDecrypt.exe is started up in memory but it sits patiently and doesn't do anything, the launcher on the other hand will perform operations for the time being.

The sample will start enumerating through files on the system, opening handles and performing write operations if its interested in them. Here is an example.


pqVs9b.jpg



I could directly see with Process Hacker the new handle creations and then closing of them afterwards, and I could see from the API monitoring logs that it was writing to the acquired handles occasionally. However, the documents in my environment do not seem to be affected to an inoperable way. The file enumeration might be broken for me because it has been constantly re-opening handles in the same areas constantly for over half an hour.


fuxDMo.jpg




The threat will block some analysis tools you may attempt to use. As an example, when I tried to spawn procmon (from SysInternals), the sample identified the start-up and tried to open a handle to the process with access rights PROCESS_TERMINATE. Once it had acquired the handle, it terminated it with TerminateProcess.

GYWSor.jpg



UDdvsc.jpg



I had enough of watching the launcher do the same thing over and over again over a prolonged duration so I forcefully terminated it. Enough with that process.

DirtyDecrypt.exe is still running but it doesn't do anything yet, it is actually a Win32 GUI program.

8WmSsy.jpg


If you restart it, it won't have an argument for "/hide" and the GUI will be displayed.

n7SOQC.jpg



You can see the file path to DirtyDecrypt.exe in one of the above images, it was dropped to AppData\Roaming\Dirty.

There's a DirtyDecrypt.exe file under the Local folder for AppData as well.


B7SqFb.jpg


8FYdEy.jpg



It appears that the alertwall.jpg should be displayed when affected documents are ran but as I have already stated, the files maintain usability without the interruption after testing out the sample in my environment.

DirtyDecrypt.exe is compressed with UPX however using -d with upx.exe is sufficient. There is no need to use OllyDbg with DirtyDecrypt.exe for dumping to disk (and then fixing the header/re-building IAT).


8KacmV.jpg


HTwyC0.jpg



Now the sample has been unpacked you'll be able to analyse DirtyDecrypt.exe through disassembly properly. Here is a list of the static imports.

Code:
Address  Ordinal Name                                                 Library
-------  ------- ----                                                 -------
0040C000         RegCreateKeyExW                                      ADVAPI32
0040C004         CryptDestroyKey                                      ADVAPI32
0040C008         AdjustTokenPrivileges                                ADVAPI32
0040C00C         ConvertStringSecurityDescriptorToSecurityDescriptorW ADVAPI32
0040C010         LookupPrivilegeValueW                                ADVAPI32
0040C014         OpenProcessToken                                     ADVAPI32
0040C018         RegSetValueExW                                       ADVAPI32
0040C01C         RegCloseKey                                          ADVAPI32
0040C020         RegOpenKeyExW                                        ADVAPI32
0040C024         RegQueryValueExW                                     ADVAPI32
0040C028         CryptDecrypt                                         ADVAPI32
0040C02C         CryptHashData                                        ADVAPI32
0040C030         CryptDestroyHash                                     ADVAPI32
0040C034         CryptCreateHash                                      ADVAPI32
0040C038         CryptEncrypt                                         ADVAPI32
0040C03C         CryptImportKey                                       ADVAPI32
0040C040         CryptGetProvParam                                    ADVAPI32
0040C044         CryptAcquireContextA                                 ADVAPI32
0040C048         CryptAcquireContextW                                 ADVAPI32
0040C04C         CryptVerifySignatureW                                ADVAPI32
0040C050         CryptGetKeyParam                                     ADVAPI32
0040C054         CryptReleaseContext                                  ADVAPI32
0040C05C         InitCommonControlsEx                                 COMCTL32
0040C064         SetTextColor                                         GDI32
0040C068         GetTextMetricsW                                      GDI32
0040C06C         DeleteObject                                         GDI32
0040C070         SelectObject                                         GDI32
0040C074         GetStockObject                                       GDI32
0040C078         SetBkMode                                            GDI32
0040C07C         CreateFontIndirectW                                  GDI32
0040C084         GetSystemDirectoryW                                  KERNEL32
0040C088         CopyFileW                                            KERNEL32
0040C08C         GetFileAttributesW                                   KERNEL32
0040C090         ReadFile                                             KERNEL32
0040C094         GetModuleFileNameW                                   KERNEL32
0040C098         CreateFileW                                          KERNEL32
0040C09C         GetTempPathW                                         KERNEL32
0040C0A0         GetLastError                                         KERNEL32
0040C0A4         LockFileEx                                           KERNEL32
0040C0A8         FindClose                                            KERNEL32
0040C0AC         RemoveDirectoryW                                     KERNEL32
0040C0B0         FindNextFileW                                        KERNEL32
0040C0B4         GetFileTime                                          KERNEL32
0040C0B8         GetDiskFreeSpaceExW                                  KERNEL32
0040C0BC         CloseHandle                                          KERNEL32
0040C0C0         DeleteFileW                                          KERNEL32
0040C0C4         SetFileAttributesW                                   KERNEL32
0040C0C8         GetVolumeInformationW                                KERNEL32
0040C0CC         HeapReAlloc                                          KERNEL32
0040C0D0         WriteFile                                            KERNEL32
0040C0D4         HeapFree                                             KERNEL32
0040C0D8         GetProcessHeap                                       KERNEL32
0040C0DC         HeapDestroy                                          KERNEL32
0040C0E0         HeapCreate                                           KERNEL32
0040C0E4         GetModuleHandleW                                     KERNEL32
0040C0E8         LoadLibraryW                                         KERNEL32
0040C0EC         GetProcAddress                                       KERNEL32
0040C0F0         Process32FirstW                                      KERNEL32
0040C0F4         Process32NextW                                       KERNEL32
0040C0F8         CreateToolhelp32Snapshot                             KERNEL32
0040C0FC         FindResourceW                                        KERNEL32
0040C100         LoadResource                                         KERNEL32
0040C104         SizeofResource                                       KERNEL32
0040C108         LockResource                                         KERNEL32
0040C10C         SetErrorMode                                         KERNEL32
0040C110         GetCurrentProcess                                    KERNEL32
0040C114         LocalAlloc                                           KERNEL32
0040C118         LocalFree                                            KERNEL32
0040C11C         lstrcmpA                                             KERNEL32
0040C120         lstrlenA                                             KERNEL32
0040C124         lstrcpynA                                            KERNEL32
0040C128         WideCharToMultiByte                                  KERNEL32
0040C12C         lstrcpynW                                            KERNEL32
0040C130         lstrcatA                                             KERNEL32
0040C134         CompareStringW                                       KERNEL32
0040C138         lstrlenW                                             KERNEL32
0040C13C         lstrcatW                                             KERNEL32
0040C140         CompareStringA                                       KERNEL32
0040C144         lstrcpyW                                             KERNEL32
0040C148         lstrcpyA                                             KERNEL32
0040C14C         CreateMutexW                                         KERNEL32
0040C150         WaitForSingleObject                                  KERNEL32
0040C154         SetEvent                                             KERNEL32
0040C158         ResetEvent                                           KERNEL32
0040C15C         CreateEventW                                         KERNEL32
0040C160         SetFileTime                                          KERNEL32
0040C164         ReleaseMutex                                         KERNEL32
0040C168         CreateThread                                         KERNEL32
0040C16C         FreeLibrary                                          KERNEL32
0040C170         GetSystemDirectoryA                                  KERNEL32
0040C174         LoadLibraryA                                         KERNEL32
0040C178         UnlockFileEx                                         KERNEL32
0040C17C         CreateDirectoryW                                     KERNEL32
0040C180         GetLogicalDriveStringsW                              KERNEL32
0040C184         SetEndOfFile                                         KERNEL32
0040C188         GetDriveTypeW                                        KERNEL32
0040C18C         SetFilePointer                                       KERNEL32
0040C190         FindFirstFileW                                       KERNEL32
0040C194         GetFileSize                                          KERNEL32
0040C198         GlobalAddAtomW                                       KERNEL32
0040C19C         GlobalDeleteAtom                                     KERNEL32
0040C1A0         GetCommandLineW                                      KERNEL32
0040C1A4         ExitProcess                                          KERNEL32
0040C1A8         Sleep                                                KERNEL32
0040C1AC         DeleteCriticalSection                                KERNEL32
0040C1B0         EnterCriticalSection                                 KERNEL32
0040C1B4         LeaveCriticalSection                                 KERNEL32
0040C1B8         InitializeCriticalSection                            KERNEL32
0040C1BC         GetTickCount                                         KERNEL32
0040C1C0         HeapAlloc                                            KERNEL32
0040C1C4         WaitForMultipleObjects                               KERNEL32
0040C1CC         ShellExecuteW                                        SHELL32
0040C1D4         DrawTextW                                            USER32
0040C1D8         PostMessageW                                         USER32
0040C1DC         UnregisterClassW                                     USER32
0040C1E0         PostQuitMessage                                      USER32
0040C1E4         GetMessageW                                          USER32
0040C1E8         GetWindowRect                                        USER32
0040C1EC         ScreenToClient                                       USER32
0040C1F0         SetTimer                                             USER32
0040C1F4         GetWindowTextLengthW                                 USER32
0040C1F8         DestroyWindow                                        USER32
0040C1FC         GetWindowThreadProcessId                             USER32
0040C200         IsWindowVisible                                      USER32
0040C204         GetClassNameW                                        USER32
0040C208         KillTimer                                            USER32
0040C20C         LoadCursorW                                          USER32
0040C210         GetDC                                                USER32
0040C214         TranslateMessage                                     USER32
0040C218         RegisterClassExW                                     USER32
0040C21C         LoadIconW                                            USER32
0040C220         InvalidateRect                                       USER32
0040C224         GetWindowTextW                                       USER32
0040C228         DispatchMessageW                                     USER32
0040C22C         DefWindowProcW                                       USER32
0040C230         ReleaseDC                                            USER32
0040C234         GetDlgItem                                           USER32
0040C238         SetWindowPos                                         USER32
0040C23C         ShowWindow                                           USER32
0040C240         FindWindowExW                                        USER32
0040C244         CreateWindowExW                                      USER32
0040C248         MessageBoxW                                          USER32
0040C24C         SetDlgItemTextW                                      USER32
0040C250         SendMessageW                                         USER32
0040C254         UpdateWindow                                         USER32
0040C258         EnableWindow                                         USER32
0040C25C         UnregisterHotKey                                     USER32
0040C260         RegisterHotKey                                       USER32
0040C268 5       getpeername                                          WS2_32
0040C26C         WSAIoctl                                             WS2_32
0040C270 4       connect                                              WS2_32
0040C274 12      inet_ntoa                                            WS2_32
0040C278 115     WSAStartup                                           WS2_32
0040C27C 11      inet_addr                                            WS2_32
0040C280 8       htonl                                                WS2_32
0040C284 18      select                                               WS2_32
0040C288 111     WSAGetLastError                                      WS2_32
0040C28C 9       htons                                                WS2_32
0040C290 22      shutdown                                             WS2_32
0040C294 116     WSACleanup                                           WS2_32
0040C298 16      recv                                                 WS2_32
0040C29C 23      socket                                               WS2_32
0040C2A0 55      getservbyname                                        WS2_32
0040C2A4 112     WSASetLastError                                      WS2_32
0040C2A8 3       closesocket                                          WS2_32
0040C2AC 52      gethostbyname                                        WS2_32
0040C2B0 19      send                                                 WS2_32
0040C2B8         GetOpenFileNameW                                     comdlg32

The sample will attempt to enable additional privileges through process tokens. You may notice the function AdjustTokenPrivileges from the static imports list.

TVOlEM.jpg


WHn9pC.jpg


I found where the function was called, here is the disassembly and the pseudo-code for the function.

2TBFfV.jpg


xqmkta.jpg



We can check where the function is being called, only from within one function in the program.


i61mwP.jpg



Lets view the function.

d63WT0.jpg


The function used for adjusting token privileges accepted parameters, and we can see it being called from within the function above with parameters. It appears the sample will attempt to gain SeSecurityPrivilege, SeDebugPrivilege and SeTcbPrivilege.

If we go back to the imports we can find some functions from advapi32.dll related to encryption (or it seems). Lets take a look at some.

zMr4Uu.jpg


tMPG0i.jpg


gj4h9D.jpg


ydnoBK.jpg




We can even find file enumeration by tracing the use of imports.

xhlkQd.jpg




xhlkQd.jpg



-------------------------------------------
@chicchi I apologise about this not being what you were after, I was unable to get the sample to affect files on the environment. Does it do this for you? I can find evidence of it scanning through the documents, even opening handles with write access, and doing many other things... other than causing harm to the documents. I could go back and check the NtWriteFile calls and see if I made a mistake while checking if it did append but just didn't work to how it was supposed to but I don't see the point at this moment. There is no doubt that the sample is malware, and it is heavily detected of course (originated in 2013). I'm not even very good with cryptography/ransomware.

You can dig deeper if you'd like and find out more, hopefully this still helped you though in some way. I gather you've been looking into this sample for awhile before commenting so if I got any details wrong here please correct them - been writing for hours without break so the quality may degrade as you continue reading but I guess I didn't do too bad at checking things.

If you do end up finding what you are after (encryption functionality) assuming it works in your environment (if it is present in this sample - maybe it is just broken for me and someone else I had test it in their environment also) please let us know as it'd be educational if you don't mind.

PS: The initial launcher is also pumped (check in HxD). Use a debugger to make it easier for following operations and analysing before more are performed... I prefer API monitoring in these cases but it can be troublesome sometimes as well and can cause you to miss things. ;)

Thanks for reading, good luck! :)



-
@Opcode I appreciate your help! I owe you!

I would like to analyze myself while referring to your analysis.
Otherwise, it will not be own strength.

Because I changed the image file to a warning image, I misunderstood that the image was encrypted.
Does this ransomware not encrypt files, is the sample bad...?
I would like to do my best to analyze this program for my study and for @Opcode's help,
But, What I want to know right now is ransomware encrypting the file with its own API without using the attack target encryption API to encrypt the file.
Although DirtyDecrypt found out that it applied to it...
 
  • Like
Reactions: frogboy and XhenEd

chicchi

Level 1
Thread author
Jul 23, 2017
9
Thanks mate. I was interested because I didn't know that by manually making the key and values on Windows 10 it would work... Where on earth have I been haha. :oops: :)

If you do not mind, please tell me which tools and software you are using.
 
D

Deleted member 65228

If you do not mind, please tell me which tools and software you are using.
Of course I don't mind!

For the analysis I demonstrated in my response, I used:
- ExeInfo PE
- API Monitor
- IDA
- HxD
- Process Hacker (suspend/resume on-demand -> KM driver enabled)
- WinDbg (I think I used it once during my initial tests with the sample before I returned and used the other tools for a break-point on a function)

I do things manually in a native language if it is required (e.g. detour functions not supported by API Monitor or do it manually so I can get the NT Path from the HANDLE in NTAPI functions, etc). But I try not too if I am in a rush. :)

Very clear and well explained inspection, great work @Opcode ;)
Thank you! :)
 

chicchi

Level 1
Thread author
Jul 23, 2017
9
Of course I don't mind!

For the analysis I demonstrated in my response, I used:
- ExeInfo PE
- API Monitor
- IDA
- HxD
- Process Hacker (suspend/resume on-demand -> KM driver enabled)
- WinDbg (I think I used it once during my initial tests with the sample before I returned and used the other tools for a break-point on a function)

I do things manually in a native language if it is required (e.g. detour functions not supported by API Monitor or do it manually so I can get the NT Path from the HANDLE in NTAPI functions, etc). But I try not too if I am in a rush. :)


Thank you! :)
MD5:7a3c8d7f8b2b5bd26995dd33f4c1ee3c
Does this sample encrypt files?
I can not analysis this sample file format with Win32 Cabinet Self-Extractor...
I am sorry that I rely on you...
 
Last edited:
D

Deleted member 65228

MD5:7a3c8d7f8b2b5bd26995dd33f4c1ee3c
Does this sample encrypt files?
I can not analysis this sample file format with Win32 Cabinet Self-Extractor...
I am sorry that I rely on you...
I don't think there is a need for me to spend time analysing it manually, there is good information on the sample which validates it really is malicious already which was from a long time ago. I cannot provide better than information already provided either really, except for additional detail on things regarding Win32 API/NTAPI (check last comment in this post).

Malwr - Malware Analysis by Cuckoo Sandbox
https://www.bromium.com/sites/default/files/bromium-report-ransomware.pdf - looks like you found yourself a DirtyDecrypt sample which likely works (since they used it in the PDF). :)

That PDF discusses your sample and it also demonstrates using MS Detours (there is a free version for 32-bit processes only and the 64-bit version is paid and is only given to selected people by Microsoft and probably costs a lot) on hooking some Win32 API functions, you might be interested in that too. I skimmed through it briefly to see if it might be informative for you and it appears to be okay.

The only problem I had with the PDF whilst reading it quickly is that they are trying to detour functions like WriteProcessMemory which is silly in my opinion. If you're going to hook in user-mode, go for the NTAPI version (e.g. NtWriteVirtualMemory not WriteProcessMemory). Their demonstration hook is more or less useless due to how easy it would be to bypass it... Just make a type definition for NtWriteVirtualMemory, get the address from the EAT in-case of EAT hooks on the function and then use that. So it isn't close to a proper solution for implementation. I've seen other articles do similar with functions like VirtualProtect (instead of NtProtectVirtualMemory) and what-not about other topics, even about exploit mitigation. I guess it is just an example at the end of the day.

Hopefully that'll help you out.
 
Last edited by a moderator:

About us

  • MalwareTips is a community-driven platform providing the latest information and resources on malware and cyber threats. Our team of experienced professionals and passionate volunteers work to keep the internet safe and secure. We provide accurate, up-to-date information and strive to build a strong and supportive community dedicated to cybersecurity.

User Menu

Follow us

Follow us on Facebook or Twitter to know first about the latest cybersecurity incidents and malware threats.

Top