Disclaimer

Friday, April 27, 2018

TrickBot Decoding Process...

Sha1: 7c0118a02867c5481bbe8b9b228fc9d0f47167b8
Sha256: c89c825c3554d8e1b4bee8096494d8bf08deab3121d104858b5e86ec318ea286

“Trickbot” is not a new malware but one of the popular banking Trojan that spread through e-mail nowadays. This malware uses a crypter/packer to hide its code from detection, but upon manually unpacking it you will see right away a very notable series of jumbled string (Modified base64) that really give us hint that they are encrypted.


Figure 1. The encoded strings of an unpacked version of Trickbot


But even the encrypted strings are expose on the unpack version of the malware you cannot directly cross reference the functions that uses the encrypted string, because Trickbot malware create an index table that contains the VA of each encrypted string and reference it dynamically using the pointer (DWORD) of each VA address. Sort of anti-static analysis technique.


Figure 2. There is no xref for the encrypted string

The Xref functions that use the SubDecFunc with some short description:

SubDecFunc – The actual decryption routine with 2 arguments, the pointer index of encrypted string to its table that contain the VA’s of the encrypted string and the allocated space where the decrypted value will be place.

Sub_SetupDecryption – Function That will call the SubDecFunc. That also has 2 the same arguments.

Sub_DecSetup1, Sub_DecSetup2, Sub_DecSetup3 = Function That can call Sub_SetupDecryption with same number and arguments values.

And from those 3 Sub_DecSetup* function there are couple of xref functions that uses it, where the inputting of the index and the output buffer as arguments of decryption routine take place. In this type of scenario we need more time to analyze each xref functions to decrypt all the strings, so it is much better to use scripting language like python to automate this.


Figure 3. Xref Function using the decryption routine

Figure 3.1. decoding flow of this malware

Decryption routine:

The structure of the encrypted and the decryption key in the file.

Figure 4. Encrypted File structure with the decryption routine


Figure 4.1. The Virtual Address Table of the Encrypted String




Figure 6. Decrpytion Routine

A simple explanation of its decryption routine.


1.  First it will get the length of the encrypted string.

2.  The decryption routine was designed to process 4 encrypted bytes at a time that’s why it needs to group the string into DWORD.

3.  after having a dword value, it will locate the position of each byte character (index of the byte) on that DWORD from the decryption key string and that index position will be the initial key to decrypt the actual value using some shift logical function in decryption_1.

4.  If an instance that the string is not divisible by 4. It will check how many bytes are need to have a DWORD value during grouping. By using Memset API it will fill the needed bytes with \x00 or null byte to form DWORD value, then find the index of each byte and used the decryption_2 to decrypt it.

    limit = enc_str_len
    dec_str =
""
   
while limit:
       
if limit >= 4:
            dec_bytes = initialized_var(size)
           
for i in range (0, 4):
                index_ptr = locate_index(enc_str[index + i])
                dec_bytes[i] = index_ptr

           
limit -= 4
           
index = index + i + 1
           
dec_str = decryption_routine_1(dec_bytes, dec_str)


       
else:
            dec_bytes = initialized_var(size)
           
for i in range(0, limit):
                index_ptr = locate_index(enc_str[index + i])
                dec_bytes[i] = index_ptr
            limit -= limit
            index = index + i +
1
           
dec_str = decryption_routine_2(dec_bytes, dec_str)
   
print dec_str
return


def decryption_routine_1(dec_bytes, dec_str):
    al = dec_bytes[
1]
    cl = dec_bytes[
0]
    dl = dec_bytes[
1]

    al = sar(al
, 4)
    cl = (cl <<
2) & 0xFF
   
al += cl
    dec_str +=
chr(al)
    al = dec_bytes[
2]
    cl = al
    cl = sar(cl
, 2)
    al = (al <<
6) & 0xFF
   
al += dec_bytes[3]
    cl &=
0x0f
   
dl = (dl << 4) & 0xFF
   
cl ^= dl
    dec_str +=
chr(cl)
    dec_str +=
chr(al)
   
return dec_str

def decryption_routine_2(dec_bytes, dec_str):
    al = dec_bytes[
1]
    cl = dec_bytes[
0]
    dl = dec_bytes[
1]

    al = sar(al
, 4)
    cl = (cl <<
2) & 0xFF
   
al &= 3
   
al = al + cl
    dec_str +=
chr(al)
    al = dec_bytes[
2]
    cl = al
    cl = sar(cl
, 2)
    cl &=
0x0f
   
dl = (dl << 4) & 0xff
   
al = (al << 6) & 0xff
   
al += dec_bytes[3]
    cl ^= dl
    dec_str +=
chr(cl)
    dec_str +=
chr(al)

   
return dec_str


Decrypted string:

Below you can see some notable decrypted string that may give us some help in analyzing the said malware.


Some of the API/modules it will parse and use during dynamic execution.

UnloadUserProfile

LoadUserProfileW 

DestroyEnvironmentBlock

CreateEnvironmentBlock 

USERENV.dll

GetAdaptersInfo

IPHLPAPI.dll

NtQueryInformationProcess 

ntdll.dll

PathFindExtensionW

PathRemoveFileSpecW 

PathRemoveBackslashW

StrStrIW

PathRenameExtensionW

PathAddBackslashW

PathFindFileNameW

SHLWAPI.dll

CryptBinaryToStringW

CryptStringToBinaryW

CRYPT32.dll

CoUninitialize

CoCreateInstance 

ole32.dll

SetSecurityDescriptorDacl 

InitializeSecurityDescriptor 

CopySid 

GetLengthSid

SetEntriesInAclW 

GetSecurityInfo

SetSecurityInfo

SetNamedSecurityInfoW

RegSetValueExW

RegOpenKeyExW 

RegCloseKey

RegCreateKeyExW

RevertToSelf

AdjustTokenPrivileges

LookupPrivilegeValueW

CryptGetHashParam

CryptAcquireContextW

CryptSetKeyParam 

CryptReleaseContext 

ConvertStringSecurityDescriptorToSecurityDescriptorW 

CryptImportKey

CryptCreateHash

CryptDecrypt

CryptDestroyHash 

CryptHashData 

CryptDestroyKey

AllocateAndInitializeSid

FreeSid 

OpenProcessToken 

EqualSid

CreateProcessAsUserW

DuplicateTokenEx 

LookupAccountSidW

GetTokenInformation 

GetUserNameW

ADVAPI32.dll

CreateToolhelp32Snapshot

Process32NextW

Process32FirstW

MultiByteToWideChar 

WideCharToMultiByte 

GetModuleHandleA 

QueryPerformanceCounter

GetCurrentThreadId

SetUnhandledExceptionFilter

UnhandledExceptionFilter

lstrlenA

GetCurrentProcessId 

GetSystemTimeAsFileTime

GetCurrentProcess

GetVersionExW 

GetVersion 

SetFilePointer

WriteFile

ReadFile

CreateFileW

lstrcmpiW

GetTempFileNameW 

CreateProcessW

MoveFileExW

GetTickCount

InitializeCriticalSectionAndSpinCount 

Sleep

GetFileAttributesW

GetModuleFileNameW

GetStartupInfoW

GetTempPathW

MoveFileW

SetCurrentDirectoryW

DeleteFileW

lstrcpyW

LocalFree

CreateMutexW

ResumeThread

WriteProcessMemory

DuplicateHandle

CreateEventW

GetExitCodeThread

VirtualAllocEx

VirtualProtectEx 

TerminateProcess 

ReadProcessMemory

VirtualFreeEx 

OpenProcess

CreateRemoteThread

SetEvent

CreateDirectoryW 

SetFileAttributesW

lstrcmpA

LoadLibraryA

GetFileTime

FindNextFileW 

GetSystemInfo 

LockResource

FindClose

GetLastError

lstrcpynW

SetFileTime

GetModuleHandleW 

LoadResource

FreeLibrary

FindResourceW 

FindFirstFileW

GetFullPathNameW 

lstrlenW

lstrcmpW

GetComputerNameW 

CreateThread

WTSQueryUserToken

WTSGetActiveConsoleSessionId 

WTSFreeMemory 

WTSEnumerateSessionsA

wtsapi32

GetProcAddress

LoadLibraryW

ExitProcess

ResetEvent 

CloseHandle

WaitForSingleObject 

SignalObjectAndWait 

InternetCanonicalizeUrlW

Wininet 

BCryptDestroyKey 

BCryptCloseAlgorithmProvider 

BCryptVerifySignature

BCryptGetProperty

BCryptImportKeyPair 

BCryptOpenAlgorithmProvider

NCryptFreeObject 

NCryptDeleteKey

NCryptImportKey

NCryptOpenStorageProvider 

Bcrypt.dll 

Ncrypt.dll 

HeapReAlloc

HeapFree

GetProcessHeap

HeapAlloc

kernel32.dll

Some Website that checks the ip address of the local machine:
ip.anysrc.net 

wtfismyip.com 

myexternalip.com 

icanhazip.com 

api.ipify.org 

ipinfo.io

ipecho.net 

checkip.amazonaws.com

other url domain:
spam.dnsbl.sorbs.net

dnsbl-1.uceprotect.net 

b.barracudacentral.org 

cbl.abuseat.org

zen.spamhaus.org 



Registry entries it used to exclude its drop file from WinDefender anti-virus.

MACHINE\SOFTWARE\Microsoft\Microsoft Antimalware\Exclusions\Paths

MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions\Paths

MACHINE\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths

Possible targeted machine:
x86

x64

Unknown 

Windows 2000

Windows XP 

Windows Server 2003 

Windows Vista 

Windows Server 2008 

Windows 7

Windows Server 2008 R2 

Windows 8

Windows Server 2012 

Windows 8.1

Windows Server 2012 R2 

Windows 10 

Windows 10 Server

Browser agent that it may use with its GET and POST traffic:
0.0.0.0 

POST 

GET

Mozilla/5.0 (Windows NT 10.0; WOW64; rv:59.0) Gecko/20100101 Firefox/59.0

An xml string that may give us a hint for other stuff it will try to do.
</Command>

</Exec>

</Actions>

</Task>



</Principal>

</Principals>

<Settings>

<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>

<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>

<StopIfGoingOnBatteries>false</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>true</Hidden>

<RunOnlyIfIdle>false</RunOnlyIfIdle>

<WakeToRun>false</WakeToRun>

<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>

<Priority>7</Priority>

</Settings>

<Actions Context="Author">

<Exec>

<Command> 

</StartBoundary>

<Enabled>true</Enabled>

<ScheduleByDay>

<DaysInterval>1</DaysInterval>

</ScheduleByDay>

</CalendarTrigger>

</Triggers>

<Principals>

<Principal id="Author">



<CalendarTrigger>

<Repetition>

<Interval>PT3M</Interval>

<Duration>P1D</Duration>

<StopAtDurationEnd>false</StopAtDurationEnd>

</Repetition>

<StartBoundary>

<?xml version="1.0" encoding="UTF-16"?>

<Task version="1.2"

xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">

<RegistrationInfo>

<Version>1.0.1</Version>

<Description>System service monitor.</Description>

<URI>\Task</URI>

</RegistrationInfo>

<Triggers>


Conclusion:

scripting language is really helpful to automate the analysis and make the Reverse engineering more easier. Analyzing some interesting stuff keeps me improve in Reverse Engineering :) hope you enjoy!!!

No comments:

Post a Comment

CobaltStrike - beacon.dll : Your No Ordinary MZ Header

Today I found some interesting sample that was flag as cobaltstrike sample in app.any.run (links are below). The execution of this file is q...