EscapeRoom Lab

CyberDefenders Network Forensics Lab

Scenario

You as a soc analyst belong to a company specializing in hosting web applications through KVM-based Virtual Machines. Over the weekend, one VM went down, and the site administrators fear this might be the result of malicious activity. They extracted a few logs from the environment in hopes that you might be able to determine what happened.

Question 1

What service did the attacker use to gain access to the system?

Answer 1

Looking through the packet capture, there was a large amount of SSH requests.

Press enter or click to view image in full size

Question 2

What attack type was used to gain access to the system?(one word)

Answer 2

Judging by the amount of SSH requests, this appeared to be a bruteforce attack. There were a total of 2098 SSH packets that were captured, which is large volume for a single capture. On top of this, while checking the conversations tab in Wireshark, I saw that there were a ton of requests with exactly 13 packets. Leading to my conclusion.

Question 3

What was the tool the attacker possibly used to perform this attack?

Answer 3

I was not super familiar with the common tools used for brute forcing via SSH. But after some brief research it seems Hydra was the tool the attacker used.

Press enter or click to view image in full size

Question 4

How many failed attempts were there?

Answer 4

For this question I used a tool called Zui, it was my first time so I had to look up some basic commands to filter out what I needed.

The following command helped me filter out unsuccessful attempts by the attacker to brute force via SSH.

_path=="ssh" and auth_success!=true

Press enter or click to view image in full size

This left me with 52 unsuccessful attempts. I thought I would note here, that I first tried to do this in Wireshark by counting the key exchange requests and going from there, but the amount of time and filtering was a little much compared to using Zui.

Question 5

What credentials (username:password) were used to gain access? Refer to shadow.log and sudoers.log.

Answer 5

Looking deeper into both files it was clear that shadow.log contains a number of hashed passwords. So noticing this I used JohntheRipper to extract as many as I could using the following command:

└─$ john --wordlist=rockyou.txt shadow.log

I ran JohntheRipper and let it go for around 16 minutes, gathering the following output:

└─$ john --wordlist=rockyou.txt shadow.log 
Using default input encoding: UTF-8
Loaded 11 password hashes with 11 different salts (sha512crypt, crypt(3) $6$ [SHA512 512/512 AVX512BW 8x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
forgot           (manager)     
god              (gibson)     
spectre          (sean)     
3g 0:00:16:07 14.82% (ETA: 11:50:04) 0.003102g/s 2427p/s 19587c/s 19587C/s 1973**9+10..195453
Use the "--show" option to display all of the cracked passwords reliably
Session aborted

Props to the box creator leaving in a Hackers reference. If only they used a stronger password to protect the Gibson.

The first entry stood out to me the most here, while cross referencing it with the sudoers.log file I could see that manager had sudo perms, giving the attacks a nice entry point.

Question 6

What other credentials (username:password) could have been used to gain access also have SUDO privileges? Refer to shadow.log and sudoers.log.

Answer 6

Referencing the above output again and matching them up with the users in sudoers.log, its clear that the user sean also has SUDO perms.

Question 7

What is the tool used to download malicious files on the system?

Answer 7

I filtered down the packet capture to look for HTTP requests from the attacker. Then a quick search inside the User Agent revealed that Wget was used to download malicious files onto the system.

Press enter or click to view image in full size

Question 8

How many files the attacker download to perform malware installation?

Answer 8

Looking through the export list for HTTP objects I could see that were 3 text/html types files.

Press enter or click to view image in full size

Question 9

What is the main malware MD5 hash?

Answer 9

I extracted the files that were uploaded by the attacker and uploaded the file with the name “1” to VirusTotal. Revealing it was indeed malicious and had the following MD5 hash value.

 772b620736b760c1d736b1e6ba2f885b 

Press enter or click to view image in full size

Question 10

What file has the script modified so the malware will start upon reboot?

Answer 10

Looking through the other files, the only one I could read using a text editor was named “3”. It is a shell script that modifies rc.local using the follwoing command:

echo -e "/var/mail/mail &\nsleep 1\npidof mail > /proc/dmesg\nexit 0" > /etc/rc.local

the rc.local is a file that gives admins a single place to place scripts or command that run at the end of the boot process. Making it a perfect place for an attacker to add something malicious to.

Question 11

Where did the malware keep local files?

Answer 11

I could see from the commands at the start of the malicious script that the malware used the location /var/mail/ to keep local files.

mv 1 /var/mail/mail
chmod +x /var/mail/mail

Question 12

What is missing from ps.log?

Answer 12

The ps.log file is something that captures the process currently running on the system. Knowing full well the attacker had used a payload to alter the rc.local file there was no evidence for this in the ps.log file. Meaning it had been altered in some way. The following was a suspicious entry in said file:

Question 13

What is the main file that used to remove this information from ps.log?

Answer 13

Looking back at the file “3”, there were a couple of lines of code that stood out to me. The first being the usage of:

uname -r

This command grabs the information of the current system. The the subsequent command places the file sysmod.ko into the kernal. Then it adds the name of the file to the modules list to ensure it loads on boot time. Sysmod.ko is the answer here.

Question 14

Inside the Main function, what is the function that causes requests to those servers?

Answer 14

After unpacking the file in upx, I opened up IDA to try and compile some pseudocode that I could read. After doing which, one line of code in the main function stood out.

requestFile((&addr)[v8]);

The malware seems to use the requestFile function specifying an address, to make a request to the server.

Press enter or click to view image in full size

Line 20

Question 15

One of the IP’s the malware contacted starts with 17. Provide the full IP.

Answer 15

Checking in with NetworkMiner, reveals the IP addresses that the malware contacts, one of with being:

174.129.57.253

Press enter or click to view image in full size

Question 16

How many files the malware requested from external servers?

Answer 16

I again used NetworkMiner to check what files the malware was working with. Apart form the 3 that were dropped by the malware, it looks like there were 9 bmp files that were requested from external servers.

Press enter or click to view image in full size

Question 17

What are the commands that the malware was receiving from attacker servers? Format: comma-separated in alphabetical order

Answer 17

This one stumped me. I took the hints that were available and started to learn as much as I could about radare2.

About an hour later. After a couple of nudges and trying to work around using radare2 I have found the answers. But first I am going to give a brief run down on how I got there. None of the other guides on the site explained how they did it, they just gave answers, including the official guide, which I found got it in a different way than I did. So let me explain how to get where I got.

Using radare2. First you load the file.

┌──(zero㉿kali)-[~/…/temp_extract_dir/EscapeRoom/files/backup]
└─$ r2 file
WARN: Relocs has not been applied. Please use `-e bin.relocs.apply=true` or `-e bin.cache=true` next time
[0x00400ad0]> 

The file is now loaded, with you pointer (the last line) being the first part of the program. Now you want radare2 to analyze the program using the following:

[0x00400ad0]> aaa
INFO: Analyze all flags starting with sym. and entry0 (aa)
INFO: Analyze imports (af@@@i)
INFO: Analyze entrypoint (af@ entry0)
INFO: Analyze symbols (af@@@s)
INFO: Analyze all functions arguments/locals (afva@@@F)
INFO: Analyze function calls (aac)
INFO: Analyze len bytes of instructions for references (aar)
INFO: Finding and parsing C++ vtables (avrr)
INFO: Analyzing methods (af @@ method.*)
INFO: Recovering local variables (afva@@@F)
INFO: Type matching analysis for all functions (aaft)
INFO: Propagate noreturn information (aanr)
INFO: Use -AA or aaaa to perform additional experimental analysis
[0x00400ad0]>

From here you can look for a list of functions using the following command:

[0x00400ad0]> afl
0x00400940    1      6 sym.imp.free
0x00400950    1      6 sym.imp.puts
0x00400960    1      6 sym.imp.fread
0x00400970    1      6 sym.imp.fclose
0x00400980    1      6 sym.imp.__stack_chk_fail
0x00400990    1      6 sym.imp.strchr
0x004009a0    1      6 sym.imp.printf
.
.
0x00403313   33   1371 sym.encryptMessage
0x00403ab1    9    394 main
0x00401027   10    648 sym.import_message
0x00402138   11    349 sym.decode
0x00400c76    3    434 sym.copyMessage
0x004039e8    3    201 sym.requestFile
0x004016d5    7     65 sym.isZero
0x00401ca6    1    139 sym.productMod
0x00400bb4    4     96 sym.printArray
0x00402e15   37   1278 sym.decryptMessage
0x00400c14    4     98 sym.printArray64
0x00400910    1     24 sym._init

There are more functions, I just don’t want to fill up the whole page. There are a couple of important ones, main, sym.requestFile, sym.decryptMessage, sym.encryptMessage. I am pretty sure sym.imp means imported files at the top of that. The others use classic programming capitalization.

Then I went to the main function and displayed it using the following:

[0x00400ad0]> s main
[0x00403ab1]> 
[0x00403ab1]> pdf@main
            ; ICOD XREF from entry0 @ 0x400aed(r)                                                                                                                                                                                           
┌ 394: int main (int argc, char **argv, char **envp);                                                                                                                                                                                       
│ afv: vars(6:sp[0x10..0x430])                                                                                                                                                                                                              
│           0x00403ab1      55             push rbp                                                                                                                                                                                         
│           0x00403ab2      4889e5         mov rbp, rsp                                                                                                                                                                                     
│           0x00403ab5      4881ec3004..   sub rsp, 0x430                                                                                                                                                                                   
│           0x00403abc      64488b0425..   mov rax, qword fs:[0x28]                                                                                                                                                                         
│           0x00403ac5      488945f8       mov qword [var_8h], rax                                                                                                                                                                          
│           0x00403ac9      31c0           xor eax, eax                                                                                                                                                                                     
│           0x00403acb      c785e8fbff..   mov dword [var_418h], 0                                                                                                                                                                          
│           0x00403ad5      bf00000000     mov edi, 0                  ; time_t *timer                                                                                                                                                      
│           0x00403ada      e831cfffff     call sym.imp.time           ; time_t time(time_t *timer)                                                                                                                                         
│           0x00403adf      89c7           mov edi, eax                ; int seed                                                                                                                                                           
│           0x00403ae1      e8faceffff     call sym.imp.srand          ; void srand(int seed)                                                                                                                                               
│       ┌─< 0x00403ae6      eb01           jmp 0x403ae9

s to SEEK to the main function, pdf@main to display it. Again there is more here but I want to save space.

Press enter or click to view image in full size

Colourful version

The thing that caught my eye in this output was this:

│     ╎╎    0x00403be3      e886fcffff     call sym.processMessage
│     ╎╎    0x00403be8      85c0           test eax, eax

This “test”. Taking 2 variables, I am looking for 2 commands so this lined up. It was in a function called processMessage, which could be used to process commands from the attackers.

Now this is where I had to look up a little about assembly and what some of the code meant. call is a function calling something, mov is moving data around, but the key one here was cmp. Comparing, which is basically checking if the attacker sent a valid command.

[0x00403ab1]> pdf@sym.processMessage
            ; CALL XREF from main @ 0x403be3(x)
┌ 378: sym.processMessage (size_t arg1);
│ `- args(rdi) vars(6:sp[0x10..0x438])
│           0x0040386e      55             push rbp
│           0x0040386f      4889e5         mov rbp, rsp
│           0x00403872      4881ec3004..   sub rsp, 0x430
│           0x00403879      4889bdd8fb..   mov qword [var_428h], rdi   ; arg1
│           0x00403880      64488b0425..   mov rax, qword fs:[0x28]
│           0x00403889      488945f8       mov qword [canary], rax
│           0x0040388d      31c0           xor eax, eax
│           0x0040388f      488b85d8fb..   mov rax, qword [var_428h]
│           0x00403896      8b00           mov eax, dword [rax]
│           ;-- hit1_78:
│           ;-- hit3_78:
│           ;-- hit4_25:
│           ;-- hit5_78:
│           ;-- hit6_25:
│           0x00403898      3d00504f4e     cmp eax, 0x4e4f5000
│       ┌─< 0x0040389d      750a           jne 0x4038a9
│       │   0x0040389f      b800000000     mov eax, 0
│      ┌──< 0x004038a4      e929010000     jmp 0x4039d2
│      ││   ; CODE XREF from sym.processMessage @ 0x40389d(x)
│      │└─> 0x004038a9      488b85d8fb..   mov rax, qword [var_428h]
│      │    0x004038b0      8b00           mov eax, dword [rax]
│      │    ;-- hit1_79:
│      │    ;-- hit3_79:
│      │    ;-- hit4_26:
│      │    ;-- hit5_79:
│      │    ;-- hit6_26:
│      │    0x004038b2  ~   3d3a4e5552     cmp eax, 0x52554e3a         ; ':NUR'
│      │    ;-- hit1_80:
│      │    ;-- hit3_80:
│      │    ;-- hit5_80:

There are 2 cmp values here, both with in hexadecimal.

0x52554e3a
0x4e4f5000

Now, I then found that you can do a search within radare2. Using the following command you could shortcut you way here if you knew what you were looking for:

[0x00403ab1]> /ac cmp @sym.processMessage

Something I should try and explain, although I am not 100% sure on this is eax, ebx etc. eax from my understanding is a 32-bit data register in assembly mainly used for input and output operations. So it makes sense to me to search for an cmp eax operetion as its an input.

Back to the hexvalues. I quickly through them into CyberChef and got the answer. NOP and RUN.

Lab complete!

Last updated