SSH Tunneling / Port Forwarding / Pivoting /Socks proxy/adb port fwd and some SSH Control Sequences

n00🔑
7 min readMay 12, 2021

Hi readers here we will see how we can tunnel tcp traffic inside ssh session. There are two types of tunneling/forwarding local and remote. In local we expose services running on system accesible to remote server(ssh server) to our local network and in remote we expose services running in local network to a device accesible by remote server(ssh server). I have found a excellent diagram explaining this on stackexchange discussions (https://unix.stackexchange.com/questions/115897/whats-ssh-port-forwarding-and-whats-the-difference-between-ssh-local-and-remot) take a look and you will get more clear picture what is going on here.

NOTE: Please keep in mind for case 2 of both -R and -L options the nearhost or farhost may not exist in same network as of ssh client(-R) or ssh server(-L). the only thing required them to work is that the near/faraway host must be accessible to ssh client(-R) and ssh server(-L).

We will be seeing all this in action with an example(I will try to explain as much I understood rest you may teach me in comment section :)

Network Architecture:

Remote (-R option)

First step to understand anything is to see help/manual of it and try to understand.

man ssh

Well I found this bit confusing, if this is the case with you too, you may continue reading…

Case 1:(ssh client is on same machine)

Let’s assume we don’t have public IP(most ISPs don’t provide for free) and we want to expose a http web application service running on a device(192.0.0.8) on port 80 in our local network to outside world via our cloud machine(139.59.91.150) on port 8000. SSH server is running on cloud machine(139.59.91.150).

ssh -R 8000:127.0.0.1:80 root@139.59.91.150

Using plink.exe(Commandline putty):

echo y | .\plink_x64.exe -pw toor root@10.10.14.8 -P 2222 -R 3306:127.0.0.1:3306

Note: If you look carefully in bottom left tmux pane our ssh session is only listening to localhost i.e 127.0.0.1. Our internal web application is still not accessible via our public ip of cloud box(curl http://139.59.91.150:8000). For this we need to edit the ssh config on server(139.59.91.150) and allow GatewayPorts option in ssh configuration and then restart ssh server.

vim /etc/ssh/sshd_config

(Also you may need to enable root user login via ssh, if is not enabled earlier)

PermitRootLogin yes

Just add this line anywhere in the sshd_config

systemctl restart ssh
ssh -R 0.0.0.0:8000:127.0.0.1:80 root@139.59.91.150

And now our internal web server is accessible to outside world via our cloud box ip address(139.59.91.150)!

Case 2:(ssh client is on different machine)

Let’s assume we don’t have public IP(most ISPs don’t provide for free) and we want to expose a http web application service running on a device(192.0.0.3) on port 80 in our local network to outside world via our cloud machine(139.59.91.150) on port 8000. SSH server is running on cloud machine(139.59.91.150) and we are connecting from ssh client(192.0.0.8).

ssh -R 0.0.0.0:8000:192.0.0.3:80 root@139.59.91.150ORssh -R 8000:192.0.0.3:80 root@139.59.91.150

In Web Server logs you can see that request has been made from 192.0.0.8(ssh client)!

Local (-L option)

First step to understand anything is to see help/manual of it and try to understand.

man ssh

Well I found this bit confusing, if this is the case with you too, you may continue reading…

Note: -L option is usually used to expose internal services(like mysql, internal web app etc.) to outside network.

Case 1:(ssh server is on same machine)

Let’s assume we want to expose web app running on a device(192.0.0.8) internally on 127.0.0.1. Here ssh server is also running on device(192.0.0.8) in internal network which is made accessible via port forwarding to public IP assigned to router. Here our cloud box(139.59.91.150) will be used as ssh client.

ssh -L 8000:127.0.0.1:80 root@117.222.234.72

As you can see we are able to access the internal web app running on localhost on our ssh server from our cloud box!

Case 2:(ssh server is on different machine)

Let’s assume we want to expose web app running on a device(192.0.0.3) on 0.0.0.0(listening on all interfaces). Here ssh server is also running on device(192.0.0.8) in internal network which is made accessible via port forwarding to public IP assigned to router. Here our cloud box(139.59.91.150) will be used as ssh client.

ssh -L 8000:192.0.0.3:80 root@117.222.234.72

As you can see we are able to access the internal web app running on other machine(192.0.0.3) in same network of our ssh server(192.0.0.8) from our cloud box(139.59.91.150)!

Dynamic (-D option)

This option is used for using ssh client as SOCKS proxy server. Fortunately i was able to understand help for this option

man ssh

The usecase for this may be to hide our real IP address while browsing web. This can be confogured with proxychains or we can manually edit proxy settings in firefox.

ssh -D 0.0.0.0:3128 root@139.59.91.150

And we can see our IP is changed and HTTP traffic is being proxied through our cloud box!

We can create proxy server at ssh server instead of ssh client:

ssh -f -N -R 1080 -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" root@<IP>
ssh -f -N -R 1080 -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" -i /var/lib/mysql/.ssh/id_rsa root@192.168.119.156

Note: For automation I prefer to use sshpass and disable StrictHostKeyChecking

sshpass -p <password> ssh -o StrictHostKeyChecking=no <options> <username>@<domain_name/IP_address>

SSH Control Sequences-

I bet you must have faced issue when ssh stops responding and connection dies and you need to close teriminal to again need to connect ssh. Well let’s see what ssh control sequences offer us-

man ssh
<Enter> + ~^Z

Let’s see some of these in live ssh connection-

Enter key should be preceded using these options.

<Enter>

a. Disconnecting ssh(Useful for connections which stops responding)-

~.

b. Background ssh connection-

~<CTRL>Z

c. Checking all supported Escape sequences-

~?

d. SSH command line for using ssh options without reconnecting-

~C

let’s forward ports 5801 and 5901 running on binded to localhost to our machine-

ADB port fwd-

Source- Roman’s “Android App Hacking — Black Belt Edition” Course
adb forward tcp:1337 tcp:31415
# It exposes service running on localhost on device on port 1337 to port 31415 on clinet machine

adb reverse tccp:80 tcp:8080
#It exposes service running on client system on port 8080 to mobile phone on port 80

Thanks for reading!

Author: Prabhsimran (https://www.linkedin.com/in/pswalia2u/)

References:

https://www.youtube.com/watch?v=N8f5zv9UUMI

--

--