oxid.exe Analysis

This is more or less a part four to the naprava.exe analysis. Turns out the SD card holds many malicious surprises.

Again, this is a 14-year-old malware executable from Moldova that was inadvertently stored on a SD card.

Analysis

Submitted the file to AnyRun. The file performs the following actions (with the respective timestamps):

+47 msFile drops C:\Users\admin\lzmjqt.exe
+63 mslzmjqt.exe writes a new shell key to WinLogon registry
+218 msCreates process svchost.exe
+266 mssvchost.exe runs file C:\Users\admin\dcubkr.exe
+1610 msDNS request to slade.safehousenumber[.]com
+31268 msmurik.portal-protection[.]net[.]ru
+61014 msworld.rickstudio[.]ru
+90744 msbanana.cocolands[.]su
+121.47 sDNS request to portal.roomshowerbord[.]com
+301.69 sDNS request to portal.roomshowerbord[.]com

The executable drops the dcubkr.exe. This second executable writes a persistent reverse shell to the WinLogon registry. Then the original executable creates a svchost.exe process. The svchost.exe then runs the dropped file. This malware then reaches out to its C2 domains — slade.safehousenumber[.]com and portal.roomshowerbord[.]com.

AnyRun captured a pcap and the DNS output is such:

The first request sent to safehousenumber (44.221.84[.]105)received a response, containing the following bytes:

Second request was sent to murik.portal-protection[.].net[.]ru:

Response is:

Reverse engineering the malware with Ghidra gives the following decompilation:

void entry(void)

{
  undefined4 *puVar1;
  uint extraout_ECX;
  byte *pbVar2;
  char **local_8c;
  _startupinfo local_88;
  int local_84;
  char **local_80;
  int local_7c;
  _STARTUPINFOA local_78;
  undefined *local_34;
  void *pvStack_2c;
  undefined *puStack_28;
  undefined *puStack_24;
  undefined4 local_20;
  undefined *puStack_1c;
  
  puStack_1c = &stack0xfffffffc;
  puStack_24 = &DAT_00426010;
  puStack_28 = &DAT_00402160;
  pvStack_2c = ExceptionList;
  local_34 = &stack0xffffff54;
  local_20 = 0;
  ExceptionList = &pvStack_2c;
  __set_app_type(2);
  _DAT_004260f8 = 0xffffffff;
  _DAT_004261b4 = 0xffffffff;
  puVar1 = (undefined4 *)__p__fmode();
  *puVar1 = DAT_004261cc;
  puVar1 = (undefined4 *)__p__commode();
  *puVar1 = DAT_004260f4;
  _DAT_00426144 = *(undefined4 *)_adjust_fdiv_exref;
  FUN_00402122();
  if (DAT_004261c8 == 0) {
    __setusermatherr(&DAT_0042638c);
  }
  FUN_00402122();
  _initterm(&DAT_0042603c,&DAT_0042603c);
  local_88.newmode = DAT_004261ec;
  __getmainargs(&local_7c,&local_8c,&local_80,DAT_00426180,&local_88);
  _initterm(&DAT_0042603c,&DAT_0042603c);
  pbVar2 = *(byte **)_acmdln_exref;
  if (*pbVar2 != 0x22) {
    do {
      if (*pbVar2 < 0x21) goto LAB_004020bb;
      pbVar2 = pbVar2 + 1;
    } while( true );
  }
  do {
    pbVar2 = pbVar2 + 1;
    if (*pbVar2 == 0) break;
  } while (*pbVar2 != 0x22);
  if (*pbVar2 != 0x22) goto LAB_004020bb;
  do {
    pbVar2 = pbVar2 + 1;
LAB_004020bb:
  } while ((*pbVar2 != 0) && (*pbVar2 < 0x21));
  local_78.dwFlags = 0;
  GetStartupInfoA(&local_78);
  GetModuleHandleA((LPCSTR)0x0);
  local_84 = FUN_00401000(extraout_ECX);
                    /* WARNING: Subroutine does not return */
  exit(local_84);
}

Below is an analysis of the code:

Stack and variable initialization: The function begins by setting up the stack frame and initializing several local variables and pointers (e.g., puStack_1c, puStack_24, puStack_28, pvStack_2c, local_34, etc.). These are used to manage the runtime environment, exception handling, and function arguments.

Exception handling setup: The ExceptionList is assigned the address of pvStack_2c, establishing a mechanism for exception handling during execution.Set application type: The function calls __set_app_type(2), which likely designates the program as a console application (type 2 typically indicates a console app in certain runtime environments like MSVCRT).

Initialize global variables: Two global variables, _DAT_004260f8 and _DAT_004261b4, are set to 0xffffffff (likely -1), possibly indicating uninitialized or default states for some runtime settings.

Set file mode: The function retrieves a pointer to the file mode variable via __p__fmode() and sets it to the value stored in DAT_004261cc, configuring how file operations are handled (e.g., text or binary mode).

Set common I/O mode: Similarly, __p__commode() retrieves a pointer to the common I/O mode variable, which is set to DAT_004260f4, adjusting runtime I/O behavior.

Adjust floating-point division: The global variable _DAT_00426144 is set to the value from _adjust_fdiv_exref, likely configuring how floating-point division is handled (e.g., enabling or disabling adjustments for certain edge cases).

Call initialization function: FUN_00402122() is called (its purpose isn’t clear from the snippet alone, but it’s likely an initialization routine for the runtime environment).

Set math error handler (conditional): If DAT_004261c8 is 0, __setusermatherr(&DAT_0042638c) is called to set a custom handler for math errors (e.g., division by zero). This is part of floating-point exception management.

Repeat initialization function: FUN_00402122() is called again, possibly to ensure proper setup after the math error handler check.

Initialize runtime sections: _initterm(&DAT_0042603c, &DAT_0042603c) is called to initialize a section of the program (likely the C runtime library’s initialization table). The identical start and end arguments suggest it might be a placeholder or specific to this decompilation.

Set argument parsing mode: The newmode field of local_88 (a _startupinfo structure) is set to DAT_004261ec, configuring how command-line arguments are processed.

Parse command-line arguments: __getmainargs(&local_7c, &local_8c, &local_80, DAT_00426180, &local_88) retrieves the program’s command-line arguments, storing the count in local_7c, argument array in local_8c, and environment variables in local_80.

Reinitialize runtime sections: _initterm(&DAT_0042603c, &DAT_0042603c) is called again, possibly to finalize initialization after argument parsing.

Process command-line string: The code retrieves the command-line string via _acmdln_exref and processes it:

  • If the string starts with a quote (“, ASCII 0x22), it skips characters until it finds a closing quote or the end of the string.
  • If it doesn’t start with a quote, it skips characters until it finds a space-like character (ASCII < 0x21, e.g., space, tab, or null).
  • After finding the end of the first argument, it skips additional whitespace (characters < 0x21) until a non-whitespace character or null is encountered.

Get startup information: GetStartupInfoA(&local_78) retrieves information about how the process was started (e.g., window settings), storing it in local_78 (a _STARTUPINFOA structure). The dwFlags field is initialized to 0 beforehand.

Get module handle: GetModuleHandleA(0) retrieves the handle of the current executable module (passing 0 gets the handle of the calling process’s executable).

Call main function: FUN_00401000(extraout_ECX) is invoked, with extraout_ECX (likely the argument count or a related value) passed as an argument. This is presumably the program’s main logic, and its return value is stored in local_84. (The exact purpose of extraout_ECX depends on the calling convention and context.)

Exit the program: The function calls exit(local_84), terminating the program with the return code from FUN_00401000. The comment “Subroutine does not return” indicates that exit() halts execution, so no further instructions in this function are executed.

OSINT

Filenamedcubkr.exe
VirusTotal Scoren/a
MD5c948d76f4c6c483d8bb93c16ae65324f
SHA11518a004b6cbc91bdb536e33dc0d6b3562f507d2
SHA256e9eedc716558d925fa19b90aa43ae4f15b98f874b94c84a3e7ef3230810d198e

slade.safehousenumber[.]com
9/94, https://www.virustotal.com/gui/domain/slade.safehousenumber.com
URLScan reaches the domain but produces a blank white page: https://urlscan.io/result/019567f0-6bd6-7669-976e-9da47cfe8b30/

44.221.84[.]105
1/94, https://www.virustotal.com/gui/ip-address/44.221.84.105
IP is AWS owned and serves many other domains — both legitimate and malicious.
URLScan also shows a blank page: https://urlscan.io/result/01956809-0a45-7eed-925f-fe6e637b1665/

portal.roomshowerbord[.]com
5/94, https://www.virustotal.com/gui/domain/portal.roomshowerbord.com
Known malware C2 domain.

193.166.255[.]171
2/94, https://www.virustotal.com/gui/ip-address/193.166.255.171
Large Finnish ISP that provides hundreds of resolutions.
URLScan shows the IP does not provide a web page: https://urlscan.io/result/01956a2a-e667-7bb8-9f13-23e97f7e4d0f/

Conclusion

Malware reaches out to C2 for second stage but these are no longer functioning — even though the domains are still alive.

IOCs

44.221.84[.]105

193.166.255[.]171

portal.roomshowerbord[.]com

slade.safehousenumber[.]com

world.rickstudio[.]ru

banana.cocolands[.]su

c948d76f4c6c483d8bb93c16ae65324f

1518a004b6cbc91bdb536e33dc0d6b3562f507d2

e9eedc716558d925fa19b90aa43ae4f15b98f874b94c84a3e7ef3230810d198e

dcubkr.exe