In this post, I would like to share a walkthrough of the Agile Machine from Hack the Box


This room will be considered a medium machine on Hack the Box

What will you gain from the Agile machine?


For the user flag, you will need to abuse a Local File Read (LFR) which we are able to read the source file with the credentials. We are required to execute some port forwarding in which the local website leaks the password by using inspect function on Firefox.


As for the root flag, you only need to abuse the Python virtual environment activation script by modifying the script using sudoedit vulnerability (CVE-2023-22809)

Information Gathering on Agile Machine


Once we have started the VPN connection which requires a download from Hackthebox, we can start the information gathering on the machine by executing the command nmap -sC -sV -p- <IP Address> -PN


Let’s access the website interface


The website interface looks so basic, but I notice there’s a login function on top of the website itself.


Sadly, we don’t have any credentials that we can use over here. However, there is a register button that we can use to register a new account on the website.


Once we have successfully registered, we have been directed to a dashboard or also look as a vault page.


Therefore, we should be trying to test by exporting a piece of empty information and we only got an error saying “No password for user


We are required to add a password by entering the username and password


We can inspect the packet via burpsuite which will give us the information of the password manager that we keyin earlier.


However, we got a redirecting page when we try to export the information via Burpsuite. I did notice there’s a CSV file that we can try to read or download into our attacker’s machine.s


Sadly, it’s just a CSV file that contains the information that we found earlier.

Trying the Local File Inclusion on the application


Therefore, let’s run some Local File Inclusion attacks on the Burpsuite, and surprisingly the attack works like a charm.


As LFI attack work on the application, let’s run a file that contains the latest running process in the Linux server which means this file is readable by the web server.


Let’s see the context of the latest running process that we found earlier we got a MySQL database credential


Aside from that, we also found a location and a new PHP file that resides inside the server.

Python
import flask
import subprocess

from flask_login import login_required, current_user
from superpass.infrastructure.view_modifiers import response
import superpass.services.password_service as password_service
from superpass.services.utility_service import get_random
from superpass.data.password import Password

blueprint = flask. Blueprint('vault', name, template_folder='templates')
@blueprint.route('/vault')
@response(template_file='vault/vault.html')
@login_required
def vault():
passwords = password_service.get_passwords_for_user(current_user.id)
print(f'{passwords=}')
return {'passwords': passwords}
@blueprint.get('/vault/add_row')
@response(template_file='vault/partials/password_row_editable.html')
@login_required
def add_row():
p = Password()
p.password = get_random(20)
#import pdb;pdb.set_trace()
return {"p": p}
@blueprint.get('/vault/edit_row/')
@response(template_file='vault/partials/password_row_editable.html')
@login_required
def get_edit_row(id):
password = password_service.get_password_by_id(id, current_user.id)
return {"p": password}
@blueprint.get('/vault/row/')
@response(template_file='vault/partials/password_row.html')
@login_required
def get_row(id):
password = password_service.get_password_by_id(id, current_user.id)
return {"p": password}
@blueprint.post('/vault/add_row')
@login_required
def add_row_post():
r = flask.request
site = r.form.get('url', '').strip()
username = r.form.get('username', '').strip()
password = r.form.get('password', '').strip()
if not (site or username or password):
return ''
p = password_service.add_password(site, username, password, current_user.id)
return flask.render_template('vault/partials/password_row.html', p=p)
@blueprint.post('/vault/update/')
@response(template_file='vault/partials/password_row.html')
@login_required
def update(id):
r = flask.request
site = r.form.get('url', '').strip()
username = r.form.get('username', '').strip()
password = r.form.get('password', '').strip()
if not (site or username or password):
flask.abort(500)
p = password_service.update_password(id, site, username, password)
return {"p": p}
@blueprint.delete('/vault/delete/')
@login_required
def delete(id):
password_service.delete_password(id)
return ''
@blueprint.get('/vault/export')
@login_required
def export():
if current_user.has_passwords:
fn = password_service.generate_csv(current_user)
return flask.redirect(f'/download?fn={fn}', 302)
return "No passwords for user"
@blueprint.get('/download')
@login_required
def download():
r = flask.request
fn = r.args.get('fn')
with open(f'/tmp/{fn}', 'rb') as f:
data = f.read()
resp = flask.make_response(data)
resp.headers['Content-Disposition'] = 'attachment; filename=superpass_export.csv'
resp.mimetype = 'text/csv'
return resp

The Python file shows the vulnerabilities that we found earlier.


There’s a chance that the credentials would be something as mentioned on row/8


Sadly, the path that i managed to sighted has been patched and we need to find another path to get the credentials.

The intended way to obtain the credentials


We managed to see an error page when trying to download some random file


We are required to enter a PIN code to proceed with the next step.


A serial of the screenshot above shows on the information required to gather and put into the script that we found here


At last, we managed to obtain a PIN code


As a result, we need to enter the PIN code as shown above.


Let’s execute some python reverse shell connection command


Boom! We have successfully a reverse shell connection back to us.


Oh well, we managed to obtain the credentials which we can use for database enumeration


Therefore, let’s access the MySQL database with those credentials that we found earlier.


After a while, we managed retrieve a hash of password and two username that we can use it.


At last, we managed to verify that the credentials can be used on the SSH service


As a result, let’s access the machine via SSH service.


We can read the user flag by typing the “cat user.txt” command

Escalate to Root Privileges Access on Agile machine


As usual, we can find any malicious SUID binary by running the “sudo -l” command


As a result, let’s download the pspy64 into the victim’s machine


While running the pspy64, I notice that there’s a file /app/venv/bin/activate on the machine which we can use and abuse it in the future.


Therefore, let’s download the linpeas.sh into the victim’s machine


I notice there’s a –remote-debugging-port that looks suspicious to me.


I managed to verify that port 41829 is open on the machine.


Let’s download the chisel on the machine.

Firefox Plugin with the Port Forwarding

Graphical user interface, text, application

Description automatically generated

We can port forwarding with firefox by entering the “chrome://inspect/?#devices” and the DevTools page will appear as shown in the screenshot above.

Graphical user interface, application

Description automatically generated

Therefore, we can configure firefox by clicking the Configure button and key-in the URL such as localhost:41829

Graphical user interface, text, application, email

Description automatically generated

Once we have successfully configured it, it will look like something as shown above.

Graphical user interface, text, application

Description automatically generated

I did notice that we managed to obtain a subdomain of http://test.superpass.htb and we also can virtually inspect it by clicking the inspect link

Graphical user interface

Description automatically generated

The inspection will look something as shown above.

Graphical user interface

Description automatically generated

At last, we managed to retrieve another username as Edwards with his password

SSH the Agile machine as Edwards


Boom! We have successfully accessed it using the Edwards credentials that we found earlier.


As usual, we managed to find a SUID binary by typing the “sudo -l” command


However, those files cannot be accessed as Edwards access.


When i think back, i managed to find one file such as /app/venv/bin/activate

Text

Description automatically generated

As shown in the screenshot above, /bin/bash is still not a SUID binary at all.

Text

Description automatically generated

As a result, we can modify the file by adding “chmod u+s /bin/bash” on top of the app/config_test.json

Graphical user interface, text, application, chat or text message

Description automatically generated

Sadly, the command above has given us permission denied.


It’s the same as /app/venv/bin/activate

Text

Description automatically generated
Text

Description automatically generated

I did some experiments on the file and managed to obtain /etc/passwd file that appears using that method

Text

Description automatically generated

Therefore, let’s do some modifications to the command as above and add “chmod u+s /bin/bash” command on the top of /app/config_test.json file

Text

Description automatically generated

Finally, the /bin/bash file has turned into a SUID Binary which we can use to obtain a root shell


We can read the root flag by typing the “cat root.txt” command

Extra Information

Graphical user interface, text

Description automatically generated