Port forwarding and pivoting: SSH, chisel and socat
How to reach a service that only listens on 127.0.0.1 or sits on another internal network: local, remote and dynamic SSH tunnels, chisel when there is no SSH, socat and proxychains.
Very often the way to root is a service that only listens on localhost: an internal web panel on port 8080, a database, a Docker API. You cannot see it from outside; you have to bring that port to your machine.
Finding what listens locally
ss -tlnp # or netstat -tlnp on older systems
cat /proc/net/tcp # if neither exists (ports in hex)
ip a; ip route # more networks? (docker0, a 172.16.x.x...)
cat /etc/hosts
Look for anything listening on 127.0.0.1 or ::1 that did not show up in your nmap. Those are your candidates.
Tip
To decode /proc/net/tcp by hand: 0100007F:1F90 is 127.0.0.1:8080 (the IP is byte-reversed and the port is hex: 0x1F90 = 8080).
With SSH
If you have credentials or an SSH key, SSH is the easiest option.
Local (-L): bring a remote port to your machine
ssh -L 8080:127.0.0.1:8080 [email protected]
# now http://localhost:8080 in your browser is the victim's internal 8080
The format is -L port_on_your_machine:destination:destination_port. The destination is resolved from the victim, so you can reach another host on its network: -L 3306:172.17.0.2:3306.
Remote (-R): take one of your ports to the victim
Handy when the victim cannot connect to you directly, or to expose your own server on it:
ssh -R 9001:127.0.0.1:9001 [email protected]
# on the victim, connecting to 127.0.0.1:9001 reaches your 9001
Dynamic (-D): a SOCKS proxy into its whole network
ssh -D 1080 -N [email protected]
And at the end of /etc/proxychains4.conf:
socks5 127.0.0.1 1080
proxychains -q nmap -sT -Pn -p 22,80,445 172.16.1.10
proxychains -q curl http://172.16.1.10
Warning
Only TCP goes through a SOCKS proxy. nmap needs -sT -Pn (no ping, no SYN scan) and it is slow: keep the port list short.
SSH tricks
-Nopens no shell and-fbackgrounds it:ssh -fN -L 8080:127.0.0.1:8080 user@ip.- In an open session,
~C(after pressing Enter) opens a command line where you can type-L 8080:127.0.0.1:8080without reconnecting. On OpenSSH 9.2 or later you need-o EnableEscapeCommandline=yes. - If you only have a non-SSH shell but can write to
~/.ssh/authorized_keys, drop your public key in and you have SSH.
No SSH: chisel
chisel is a single binary (Linux and Windows) that tunnels over HTTP. Upload it to the victim and start the server on your machine:
# Your machine
./chisel server -p 8000 --reverse
# Victim: bring its 127.0.0.1:8080 to your port 8080
./chisel client 10.10.14.5:8000 R:8080:127.0.0.1:8080
# Victim: several at once
./chisel client 10.10.14.5:8000 R:8080:127.0.0.1:8080 R:3306:127.0.0.1:3306
# Victim: a SOCKS proxy on your 127.0.0.1:1080 into its whole network
./chisel client 10.10.14.5:8000 R:socks
With R:socks you use proxychains just like with ssh -D.
Note
Use the same chisel version on both ends. If the victim runs Windows, grab the .exe from the same release (chisel_x.y.z_windows_amd64).
socat: forwarding a port on the victim itself
If you want to expose one of the victim's local ports to the outside (to attack it directly from your machine), and socat is installed or you can upload it:
socat TCP-LISTEN:8081,fork,reuseaddr TCP:127.0.0.1:8080
# now 10.10.10.10:8081 reaches the internal 8080
It also works as a "bridge" when pivoting: whatever reaches the middle host is forwarded to a third one.
On Windows
- chisel.exe, exactly as above.
- plink.exe (PuTTY's SSH) to do a
-Rto your machine:plink.exe -l tunnel -pw tunnel -R 4445:127.0.0.1:445 10.10.14.5(create a user just for this: its password stays on the victim). - netsh (needs admin):
netsh interface portproxy add v4tov4 listenport=8081 listenaddress=0.0.0.0 connectport=8080 connectaddress=127.0.0.1.
Whole networks: ligolo-ng
When there are several internal networks and lots of services, a SOCKS proxy falls short. ligolo-ng creates a network interface on your machine and routes all traffic (including regular nmap and UDP) through the agent running on the victim. It takes more setting up the first time, but then you work as if you were inside the network. Check the docs for the version you download, as the commands have changed between releases.
What to do with the port
Once it is on your localhost, treat it as a new target: nmap -sCV -p 8080 127.0.0.1, open the web app, look up the version. Unpatched internal panels, unauthenticated APIs and databases using the password from the config file are how many boxes end.