An Excruciatingly Detailed Guide To SSH (But Only The Things I Actually Find Useful)
An Excruciatingly Detailed Guide To SSH (But Only The Things I<br>Actually Find Useful)
Oh you like SSH? Name every<br>flag.
Published: 2023-08-22
~16 min read
Welcome
We’ve all seen these great<br>diagrams of how SSH port forwarding works but if your brain is<br>anything like mine, these diagrams leave you with a lot of unanswered<br>questions. If you’re on a red team, understanding how to traverse a<br>network better than the people who designed it gives you immense power<br>to do evil things. SSH is such a powerful tool but sometimes the syntax<br>and other concepts can get in the way of us accomplishing our goals. In<br>an effort to do more evil things in a timely fashion I’ve put together a<br>massive list of SSH things that I find useful. You can read it<br>too, but if I’m being honest, this is mostly for me. I’ve learned that I<br>really don’t grasp concepts unless I have hands on keyboard time doing<br>them. This post is essentially just everything I learned while doing so.<br>Also I should point out that in all of these examples I am using a<br>websever to demonstrate port forwarding but this can be done with almost<br>any service including RDP, SQL, etc.
Local Port Forwarding (-L)
Like the name implies, local port forwarding allows you to create a<br>local port that is forwarded to a remote port. Let’s assume that the<br>server internal-web.int is hosting a webpage that is only<br>accessible on the loopback interface. This means that in order for us to<br>access that webpage, we must be on internal-web.int. One<br>way that we can get around this is by using an SSH local port forward.<br>Assuming we SSH access to internal-web.int, on the host<br>machine campfire.int, we can create a local forward that<br>will allow us to access the remote webserver via a local port.
The command to do this is:<br>ssh -N -f -L 1337:127.0.0.1:80 [email protected]. This<br>command is ran on campfire.int. That’s a complicated<br>command, as always, breaking it down by flag will allow us to figure out<br>what exactly is happening.
-N: This lets SSH know that we’re not going to be<br>sending any commands after the server. Without this we’d get a shell on<br>[email protected]
-f: This sends SSH to the background. If we didn’t do<br>this, our terminal would hang and we wouldn’t be able to use it.
-L Tells SSH to forward a local port
1337:127.0.0.1:80: This tells SSH to bind the local<br>port 1337 to the remote port of 80 (the port our webserver is on).
Note The best way I found to remember this is -L means local is on the left-hand side of the address. -R means the local port is on the right-hand side of the address.
[email protected] This is telling SSH that we wish<br>to login to the remote server as the root user to establish the SSH<br>tunnel. Remember, port 1337 on our local machine is going to be bound to<br>port 80 on the remote server.
Now that we have established the local port forward, we can interact<br>with port 80 on internal-web.int by sending requests to<br>port 1337 on our local machine( campfire.int).
Interacting with port 80 on<br>internal-web.int
Remote Port Forwarding (-R)
Remote port forwarding is the opposite of local port forwarding. Lets<br>assume that we have access to internal-web.int and it is<br>hosting a webpage that is only accessible on the loopback interface.<br>Lets also assume that campfire.int cannot directly access<br>internal-web.int. In this scenario we’d like to access<br>internal-web.int from campfire.int. The<br>problem is that we cannot directly communicate between<br>campfire.int and internal-web.int due to a<br>firewall. To get around this, we identify that<br>vuln-server.int is reachable by both<br>campfire.int and internal-web.int. The<br>solution in this case is to use remote port forwarding SSH option to<br>forward the port 80 from internal-web.int to an arbitrary<br>port on vuln-server.int. Once we complete the remote port<br>forward, we should be able to access the internal-web.int’s<br>internal web page running on port 80 by issuing a curl command to<br>vuln-server.int.
The command to do this is:<br>ssh -N -f -R 3000:127.0.0.1:80 [email protected].
-N: This lets SSH know that we’re not going to be<br>sending any commands after the server. Without this we’d get a shell on<br>[email protected]
-f: This sends SSH to the background. If we didn’t do<br>this, our terminal would hang and we wouldn’t be able to use it.
-R Tells SSH to forward a remote port
3000:127.0.0.1:80: This tells SSH to bind the remote<br>port 3000 to the local port of 80.
Note
The best way I found to remember this is local forwarding with-L means local is on the left-hand side of the address. Remote forwarding with-R means the local port is on the right-hand side of the address.
[email protected]: This is telling SSH that we wish<br>to login to the remote server as the root user to establish the SSH<br>tunnel. Remember, port 3000 (on vuln-server.int) is going<br>to be bound to port 80 on this server.
Now that we have established the remote port forward, we can access<br>port 80 on...