Hack-The-Box-walkthrough[timing]
introduce
OS: Linux
Difficulty: Medium
Points: 30
Release: 11 Dec 2021
IP: 10.10.11.135
Enumeration
NMAP
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
Nmap reveals two open ports, HTTP and SSH. Let’s look into webpage.
Just a login page, there’s nothing else on the homepage. Let’s do a directory brute force.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
We got couple of directories and php files. If we look closer, most php files are redirecting to ‘login.php’. However, image.php is not redirecting to anywhere, and also the size is ‘0’. Initially I was little bit confused, why there’s a ‘image.php’ and ‘images’ directory, both server the same purpose. So, I did a directory brute force on ‘images’.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
There’s another directory inside ‘images’. So, my speculation was, if user uploads any images via ‘upload.php’ it dumps it in ‘/images/upload’ directory and it can be accessed via ‘image.php’. I tried to fuzz with file parameter for any LFI or Path traversal attack.
1 | ┌──(root💀kali)-[~/ffuf] |
As you can see, status code of files are 200 but size is 0. It simply means, ‘file’ parameter is not working. I tried with couple other parameters but all failed, but ‘img’ parameter worked.
1 | ┌──(root💀kali)-[~/ffuf] |
We got 200 status code and size of all file same.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
As you can see, I tried to curl the path with ‘img’ parameter, and I got the above response. We need to bypass the security filters now.
- Wrapper php://filter
We will use:
1 | http://example.com/index.php?page=php://filter/convert.base64-encode/resource=index.php |
this php filter to bypass the filter and read the files. It gives output in base64 encoded format, so we need to decode it to understand.
We got the encoded information, let’s decode it.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
We can directly decode it and grep for user details. We got ‘aaron’ user. Now we can read files local files which we found in our initial directory brute force.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
‘Upload.php’ gives us another piece of information. But it only works if we have access to upload functionality. There’s Authentication check file, let’s look into it first.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
To access upload feature the user should have a ‘role 1’, if not, this feature is not available. Now we need to find a way to login. There are no any files which has login details. However, if we login using previously found user ‘aaron’ as username and password, then it’d give you dashboard.
It say’s logged in as user 2.
The only way to edit the role is when we update user profile. Let’s edit the profile and intercept the update request in burp.
No need to change anything from the above input, as it only concerns about role ID.
1 | POST /profile_update.php HTTP/1.1 |
Add the role to data and forward the request and refresh the page. You will see ‘admin panel’
Admin panel has upload image feature.
Now it’s time to look into ‘upload.php’ code.
1 | $upload_dir = "images/uploads/"; |
Above code is what we will look into. Uploaded files will be moved to ‘/images/uploads/‘ directory. File Extension must have ‘jpg’, and upon upload the filename will be changed to MD5 sum. The logic behind creating this MD5 sum is, it takes two things as input, ‘$file_hash’ and ‘time())’ and then adds the base filename of uploaded file to that hash.
According to PHP, uniqid() function generates a unique ID based on the microtime (the current time in microseconds). In PHP single quote (‘) and double quote(“) have different meanings and interpretations.
Single quoted strings will display things almost completely “as is.”. Double quote strings will display a host of escaped characters (including some regexes), and variables in the strings will be evaluated.
So, uniqid() is just a rabbit hole, it is taking $file_hash as string to generate MD5 hash. However, time()) is also being used as factor to generate MD5. It is considering current time in seconds, that means every second will get a new hash. We need to match the upload time to get the right hash. For that we need to make sure our local machine time is not far behind or a head.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
You can check the date and match it with your time using nmap. Target is ‘-16’ seconds behind from my local time. You just need to confirm time, make sure to set your time to GMT.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
Create a jpg file with PHP code which can give code execution access. Now we need to start a PHP interactive shell, where we run continuously run PHP code to generate hash based on time and string.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
Keep it going, do not terminate it. Now we need to upload that recently created jpg file, intercept the upload request, send it to repeater, check the response time and match the time with PHP hash.
1 | HTTP/1.1 200 OK |
Check burp response time and find the matching hash of that time from PHP interactive session.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
Response time is 15:26:25 Copy the hash, add the base filename of uploaded jpg file and access it via img query parameter.
Initial Access
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
As you can see we have a code execution. This machine will not easily provide you reverse shell, as firewall (iptables) are in place to block outgoing request from a www-data user.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
‘/opt’ directory has a backup of website. Let’s download it first.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
We can’t directory access the zip file, so copy it to uploads Directory and from there we can download it.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
Extract or unzip the file and you will .git repository.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing/backup] |
Let’s git commits using gittools.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing/backup] |
After commit extraction, you will see two directories. Now we need to find what has changed in terms of code.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing/backup/source] |
Database connection credentials has been modified. Let’s try these creds on user SSH login.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
The second password is being reused as ‘aaron’ user’s password.
Privilege Escalation - root
1 | aaron@timing:~$ sudo -l |
User can run a binary with root privileges. Let’s look into it.
1 | aaron@timing:~$ file /usr/bin/netutils |
It is a shell script, running a java application from root’s directory. Let’s interact with it.
1 | aaron@timing:~$ sudo /usr/bin/netutils |
Upon execution of the binary, it gives us two options, FTP and HTTP. Setup a HTTP server on Kali and download test file.
1 | aaron@timing:~$ sudo /usr/bin/netutils |
After download check the downloaded file in ‘aaron’ user’s home directory or current working directory.
1 | aaron@timing:~$ ls -la test.txt |
As you can see the file permissions are of root user and ‘aaron’ user has read access to it. We still don’t know what’s happening behind scene. Let’s run a pspy in one SSH terminal and in another execute sudo binary to find what’s happening.
1 | 2021/12/15 10:28:04 CMD: UID=0 PID=74557 | wget -r ftp://10.10.14.30 |
These two applications are being used behind the scene to download files. FTP is using wget and HTTP is using Axel application. We can get the ‘Axel’ application version via netcat.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
The user agent disclose application version. This version has no any CVEs. ‘Axel’ application has a configuration file via that we can dump our SSH public keys as authorized_keys.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
If you are on kali, you will find example axelrc file.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
This ‘default_filename’ will be activated when downloading something without any filename from ‘axel’.
1 | aaron@timing:~$ sudo /usr/bin/netutils |
As you can see from the above example, to download I didn’t provide any file name. Even thou it dowloaded something and saved it as ‘default’
1 | aaron@timing:~$ ls -la default |
If we read the ‘default’ file, then we will see HTML format of directory listing page.It just download the whole page and saved it as ‘default’. If we look closely, all the downloaded files have root’s permissions. We can use it our advantage.
1 | cat axelrc |
Change the ‘default_filename’ to ‘/root/.ssh/authorized_keys’, save it. Download this file to ‘aaron’ user’s home directory and save it as .axelrc.
If we download something without providing file name then it will be dumped into ‘root’ directory. So we will dump our Kali SSH public key and save it as ‘authorized_keys’. But as we saw previously, it saves it in HTML format. For that we need to create new directory and save your Kali public key as index.html
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
Now we are set to execute this. Setup a HTTP server where your Kali SSH key file is and download it via netutils HTTP option.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
1 | aaron@timing:~$ sudo /usr/bin/netutils |
and we are root now
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
privesclation via WGET (FTP)
There’s another method to do the same thing, but with WGET (FTP). This can be done by wgetrc
- Wgetrc Commands (GNU Wget 1.21.1-dirty Manual)
1 | aaron@timing:~$ cat .wgetrc |
Create a wget configuration file in ‘aaron’ users home directory. Setup a FTP server on Kali Linux.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
Make sure you have authorized_keys file and start a python FTP severe.
1 | aaron@timing:~$ sudo /usr/bin/netutils |
1 | [I 2021-12-18 18:36:43] 10.10.11.135:35200-[anonymous] USER 'anonymous' logged in. |
After this, you can login via SSH from Kali Linux.
1 | ┌──(root💀kali)-[~/hackthebox/machine/timing] |
Summary of knowledge
- dir brute with gobuster
- LFI bypass with php://filter
- get file upload shell name using PHP interactive shell check the response time and match the time with PHP hash
- .git leak ssh password
- Privilege Escalation through shell script
- pspy find suspicious process
Contact me
- QQ: 1185151867
- twitter: https://twitter.com/fdlucifer11
- github: https://github.com/FDlucifer
I’m lUc1f3r11, a ctfer, reverse engineer, ioter, red teamer, coder, gopher, pythoner, AI lover, security reseacher, hacker, bug hunter and more…