cwoellner.com ~ personal website & blog

Securing Hidden Services

Published on: Saturday, Apr 13, 2024

Intro

Ever since the takedown of LockBit earlier this year, I have been thinking quite a lot about how to avoid having your entire service taken down and your operation getting deanonymized. In this post I want to discuss a couple of ideas on how to architect a (legal) hidden service securely.

Basics

First let’s talk about some security basics.

Components of a Hidden Service

At its core a hidden server is server side application like any clear net service, what makes it hidden is that is communicating through the tor daemon. Giving us our first component, the tor daemon.

In this post I will use a classic web application as my example, but the ideas can be implemented for most application types. The traditional web application has three tiers: the frontend, the backend and the database. Most tor users tend to browse with their JavaScript turned off, so we will have to resort to pure server-side rendering, resulting in a somewhat merged front- and backend. The content needs to be served by a web server, which might included in the backend a stand-alone server, forwarding the queries to a socket.

This gives us the following list of components:

Now that we know the components let’s take a look at how attackers exploit them.

Typical Attack Paths

Attackers will try to attack one of our components in order to gain a foothold and then use that foot hold to escalate their privileges ultimately obtaining root privileges, allowing them take over the server and to look us out.

The most common attack vector is the abuse of bug in the code of the software we are using, this affects both software written by us (the web application) and software written by others (like our operating system). Since even big corporations routinely have vulnerabilities in their code we should always assume that any of our components can be exploited, especially the ones we wrote ourselves.

The other important attack vector are incorrectly configured components, this can be avoided by reading and understanding the documentation, and by adhering to best practices.

Virtualization and Splitting of the Gateway

The basic setup that most tutorials show (and the setup I assume LockBit used) is the following:

All services are placed on the same host

The core issue here is: If somebody manages to compromise one of the services, they are able to communicate without using tor leading to our IP address being leaked. With the IP address being leaked the hosting provider can be contacted, and the server can be shut down or a trap can be setup.

If an attacker is able to escalate their obtained access, they can get the private key of our hidden service and advertise their own service using our onion address.

The easiest way to avoid this to set up two VMs on our host: a server and a gateway. The only way the server is able to reach the internet is via the tor service running on the gateway. In this scenario it is not possible for an attacker to access our private key or to leak our IP address (Keep in mind when an attacker controls a huge amount of nodes in the tor network, they might still be able to deanonymize you, but even then it will most likely take a while to do so).

The way we connect to these machines to perform maintenance is directly via the console on the hypervisor.

A setup with a split gateway might look like this:

two virtual machines, one runs the tor daemon, the other runs the rest of the services

This setup can be even further improved on by splitting up the services in the services VM into their separate VMs, if the available resources allow for it.

Limiting Service Privileges and Jailing Services

While attackers, that are able to exploit one our services, might no longer be able to leak our IP address, they might still be able to escalate their privileges in order to intercept, log and manipulate traffic, or to ransom our data.

In order to avoid this we should employ the principle of least privilege. Meaning that none of our services should run under the root user and that their access to the file system should be as limited as possible. While the first topic is very easy to implement, in order to solve the second a more complicated solution is needed: Firejail.

Applications run through Firejail run in their own namespace allowing us to control which commands and which files are accessible to the application, minimizing our attack surface. Configuration might be a bit difficult for new users, but not impossible to learn.

Keep in mind that when ever we are adding new software in order to enhance our security, we will always broaden our attack surface a bit, since those security tools might be vulnerable themselves.

Using a WAF

With the web application being the most likely vulnerable component in use, it should obtain additional protection. A good way to do this is deploying a Web Application Firewall (WAF), the WAF will detect suspicious queries and block them before they hit the web application.

Since most vendors are either only offering SaaS solutions or dedicated appliances, we are somewhat limited in the selection of our WAF software and will most likely end up using ModSecurity. Sadly since Trustwave stopped sponsoring the project, the future of is uncertain, so depending on the state of software users might have to select a different solution in the future.

When using WAFs keep in mind that they will never be able to filter 100% of malicious queries.

Monitoring and Alerting

While the ideas above result in a reasonable secure setup, we still need to make sure we are being notified if suspicious activity occurs on one of our VMs.

I guess the monitoring and detection part could be done by an open source XDR and SIEM solution like wazuh, but I did not have the chance to test this yet.

In terms of sending out our alerts we are somewhat limited, since both our alerting system sending the alerts and our client reading the alerts have to connect to a service using tor. My suggestion here would be to find a public IRC server allowing connections from the tor network or tor exit nodes and to use a channel on there.

In case of a breach the XDR logs will also help us to identify what vulnerability has been abused.

This is the point I am most split up about, without extensive logging and alerting you are not operating in a secure environment, but at the same time you are adding a lot of potentially vulnerable components to your setup, and you need a relatively good understanding of cybersecurity to analyze and act on those alerts.

Closing Thoughts

Running a hidden service, set up following popular configurations guides, is playing Russian roulette: You might be able to patch in time for a long time, but eventually you will end up like LockBit and “get lazy”. We have to expect this and, with a couple of modifications to our setup, we can delay and soften the blow.

Also: This is purely theoretical, please don’t use this information to set up any actual illegal services.