Shodan has been called the "hacker's search engine" because it's literally a searchable database of internet-connected devices and servers. It allows anyone to search for webcams, routers, servers, Raspberry Pis, traffic lights, point of sale systems, industrial control systems, and much more.
The web tool accomplishes this by randomly iterating through every possible IP address in existence (whether it's online or not being used) and attempts to extract service banners on different ports. Service banners usually store metadata about the running service, like the service name, type, and version number.
Any internet-connected device will inevitably be scanned by Shodan and other databases like Censys. Hackers use these databases to locate out-of-date, vulnerable servers. Even system administrators who regularly update their servers and follow the best security practices are exposed to exploits. The libSSH authentication bypass vulnerability is an excellent example of this.
The libSSH vuln allowed hackers to connect to SSH services without first performing authentication. The most fully up-to-date services were still vulnerable to this exploit and put many servers and websites at risk. More importantly, fully updated systems are still exposed to exploits that have yet to be disclosed. Blackhat's sometimes horde and sell vulnerabilities in private communities. There's no telling how many undisclosed OpenSSH exploits may exist today.
Tor onion services can help mitigate exposure. Much like how onion websites can't be accessed using a standard web browser, SSH services can be configured only to allow access over Tor. It can make services entirely inaccessible for search engines like Shodan and more difficult for hackers to find.
The first thing we need to do is install Tor on both the virtual private server (VPS) and the client computer. The client can be a Debian, Ubuntu, or a Kali system to follow along. MacOS and Windows 10 users can check out the official Tor Project documentation for installing tor properly. For most readers, the SSH server will likely be a Debian VPS. However, this can be set up on an Ubuntu desktop or Raspberry Pi, for those who wish to remotely access computers at home.
Tor is available in many Linux repositories. In most cases, the packages aren't reliably maintained or updated, which means there could be missing critical stability and security updates. Furthermore, anonymity software should always be acquired directly from the source (i.e., torproject.org).
Log into your SSH server and add the Tor Project's repository to your APT repository list with the following echo command, which works in Debian.
~$ echo -e "deb https://deb.torproject.org/torproject.org $(lsb_release -sc) main \ndeb-src https://deb.torproject.org/torproject.org $(lsb_release -sc) main" > /etc/apt/sources.list.d/tor.list
If you're running Kali Linux, use the following command instead.
~$ echo -e "deb https://deb.torproject.org/torproject.org stretch main \ndeb-src https://deb.torproject.org/torproject.org stretch main" > /etc/apt/sources.list.d/tor.list
Then, download the Tor Project's package signing key and import it into your APT keyring with the following command.
~$ wget -O- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | sudo apt-key add - --2019-03-05 06:29:13-- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc Resolving deb.torproject.org (deb.torproject.org)... 184.108.40.206, 2001:41b8:202:deb:213:21ff:fe20:1426 Connecting to deb.torproject.org (deb.torproject.org)|220.127.116.11|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 19665 (19K) [text/plain] Saving to: ‘STDOUT’ - 100%[================================>] 19.20K 54.8KB/s in 0.4s 2019-03-05 06:29:16 (54.8 KB/s) - written to stdout [19665/19665]
You'll see the "OK" output when the signing key has been added to your keyring. Next, update APT using the below apt-get command.
~$ apt-get update Get:2 https://deb.torproject.org/torproject.org stretch InRelease [4,965 B] Get:4 https://deb.torproject.org/torproject.org stretch/main Sources [1,169 B] Get:5 https://deb.torproject.org/torproject.org stretch/main amd64 Packages [2,400 B] Fetched 8,534 B in 8s (1,091 B/s) Reading package lists... Done
Install Tor using the below apt-get command, and you're done.
~$ apt-get install tor deb.torproject.org-keyring torsocks Reading package lists... Done Building dependency tree Reading state information... Done Suggested packages: mixmaster torbrowser-launcher socat tor-arm apparmor-utils obfs4proxy The following NEW packages will be installed: deb.torproject.org-keyring The following packages will be upgraded: tor
Both the client and the VPS running the SSH server should have Tor installed. Be sure to follow the above steps on both systems.
The Tor process will likely get executed immediately after installing it so, as root (sudo), stop the process. This can be done using the systemctl command.
~$ sudo systemctl stop tor
Then, use a text editor to open the /etc/tor/torrc file. This is the configuration file used by Tor to modify its behavior and create onion services.
~$ sudo nano /etc/tor/torrc
There will be a ton of information in this file. Most of it isn't relevant to this article. Scroll down a bit to the "This section is just for location-hidden services" section. In Debian and Kali Linux, it appears as shown below.
############### This section is just for location-hidden services ### ## Once you have configured a hidden service, you can look at the ## contents of the file ".../hidden_service/hostname" for the address ## to tell people. ## ## HiddenServicePort x y:z says to redirect requests on port x to the ## address y:z. #HiddenServiceDir /var/lib/tor/hidden_service/ #HiddenServicePort 80 127.0.0.1:80 #HiddenServiceDir /var/lib/tor/other_hidden_service/ #HiddenServicePort 80 127.0.0.1:80 #HiddenServicePort 22 127.0.0.1:22
Uncomment (#) one "HiddenServiceDir" and one "HiddenServicePort" line, as such:
############### This section is just for location-hidden services ### ## Once you have configured a hidden service, you can look at the ## contents of the file ".../hidden_service/hostname" for the address ## to tell people. ## ## HiddenServicePort x y:z says to redirect requests on port x to the ## address y:z. #HiddenServiceDir /var/lib/tor/hidden_service/ #HiddenServicePort 80 127.0.0.1:80 HiddenServiceDir /var/lib/tor/other_hidden_service/ #HiddenServicePort 80 127.0.0.1:80 HiddenServicePort 22 127.0.0.1:22
Save and exit the text editor. Then, restart tor using the below command.
~$ sudo systemctl restart tor
The "hostname" file in the /var/lib/tor/other_hidden_service/ directory will hold the new onion address. Use cat to read the file. Take note of this onion address, it will be required in the next step.
~$ cat /var/lib/tor/other_hidden_service/hostname pkgsxmtmdrlxp7l3gfqysi3ceaochd4vnv7eax2fuyridmcz7ucvluad.onion
Before proceeding, it's good to make sure the SSH service is reachable using the new onion address. This can quickly be verified using the torsocks, a shell wrapper used to transparently Tor-ify command line applications like curl, wget, or nmap.
The following torsocks and curl command will query the new onion service. Be sure to append the SSH port number (:22), otherwise, curl will query port 80 by default and fail. A successful query will return the SSH version banner, as shown below.
~$ torsocks curl http://pkgsxmtmdrlxp7l3gfqysi3ceaochd4vnv7eax2fuyridmcz7ucvluad.onion:22 SSH-2.0-OpenSSH_7.4p1 Debian-10+deb9u5
By default, most SSH services are listening on every IPv4 interface. While not the case for all Linux distributions, this is true for popular ones like Ubuntu and Debian. This is usually represented as "0.0.0.0" in the /etc/ssh/sshd_config file, where SSH stores all of the service configurations.
SSH services configured this way makes it possible to access the server from any computer in the world. Which is convenient for website administrators who need to make changes to their website from different devices and networks.
First, let's have a look at SSH service running in the background. Use ss, a tool for investigating sockets, to show processes (-p) listening (-l) for TCP (-t) connections.
~$ ss -plt State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:ssh *:* users:(("sshd",pid=1148,fd=3))
If the server has applications running in the background (e.g., Apache, Nginx, IRC software, etc.), many services may appear here. Let's focus on the Local Address:Port column which reads *:ssh. Wildcards indicate the SSH service is listening on every available IPv4 and IPv6 interface.
Shodan is able to locate this SSH service because it's available (listening) in this state. To change this, open the /etc/ssh/sshd_config file and find the "ListenAddress" line(s).
~$ sudo nano /etc/ssh/sshd_confnig
In Debian, it appears as shown below. They will probably be commented out, which is normal. When every ListenAddress is commented out, SSH falls back to its default configuration to listen on every interface.
#Port 22 #AddressFamily any #ListenAddress 0.0.0.0 #ListenAddress ::
Change the ListenAddress line to "127.0.0.1" and uncomment it as such:
#Port 22 #AddressFamily any ListenAddress 127.0.0.1 #ListenAddress ::
Then, restart the SSH service.
~$ sudo systemctl restart ssh
Immediately after executing the systemctl command, the current SSH connection may close. The SSH service is no longer available on any IPv4 or IPv6 address so it's normal for the connection to break.
Fortunately, the onion service was set up on the server so the SSH service can still be reached. Now, from the client (i.e., laptop or remote computer), use the below torsocks command to connect to SSH service.
~$ torsocks ssh -p 22 firstname.lastname@example.org The authenticity of host 'pkgsxmtmdrlxp7l3gfqysi3ceaochd4vnv7eax2fuyridmcz7ucvluad.onion (127.42.42.0)' can't be established. ECDSA key fingerprint is SHA256:f22LX7WJfLGOiKxP+0+cA/l5Q1GsJLFA30ZyMyGLMl4. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'pkgsxmtmdrlxp7l3gfqysi3ceaochd4vnv7eax2fuyridmcz7ucvluad.onion' (ECDSA) to the list of known hosts. email@example.com's password:
After logging into the server using the onion address, use the ss command again to view listening services. It should no longer report SSH listening on every available interface, only 127.0.0.1.
~$ ss -plt State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 127.0.0.1:ssh *:* users:(("sshd",pid=1162,fd=3))
We can further verify this by executing a simple nmap version (-sV) scan on the server.
~$ nmap -p 22 -sV <vps ip here> PORT STATE SERVICE VERSION 22/tcp closed ssh
The SSH service may still appear on Shodan for days or even weeks. Shodan isn't great about purging old service banners and information. But that doesn't mean the SSH service is still accessible to attackers.
By far the most significant caveat to using SSH with onion services is the slowness. Responses in the terminal can be painfully slow for someone who isn't used to onion services and Tor.
Configuring Tor to work with SSH services in this way hides it from Shodan but doesn't make it entirely impossible to locate by hackers. It can still be reached using Tor, which significantly minimizes its overall exposure but doesn't make it altogether impervious to attacks.
There's a security feature in Tor called HiddenServiceAuthorizeClient. This feature allows users to essentially password-protect the onion service with an authentication cookie. At the time of this writing, HiddenServiceAuthorizeClient isn't supported by the newer "next-gen" onion services. It would be possible to generate older onion services, but it seems like bad security practice to use a soon to be a deprecated feature of Tor. In the future, it will be possible to use HiddenServiceAuthorizeClient with next-gen onions to make them completely inaccessible to anyone but you. For now, changing the SSH port number to something non-standard like 62359 or 41171 will help keep it off the radar of script-kiddies on the darknet mass-scanning on port 22.