#TOR #De-anonymization #Cloud #Sniffing
This report explores practical methods for de-anonymizing TOR onion services, specifically by analyzing traffic within a local area network (LAN) and measuring latency from various global locations to the onion server. Onion services, accessible via .onion addresses, utilize Tor’s network of encrypted relays to ensure user anonymity. By employing traffic analysis and latency probing, we aim to discover Onion Services running on a LAN and infer their physical location on a worldwide scale, respectively.

The Tor network is a decentralized system designed to provide anonymity for users and services by routing traffic through a series of encrypted relays. It is widely used for protecting user privacy and enables hosting and accessing hidden services known as \textbf{onion services}. These services use .onion addresses, which mask the IP addresses of both users and service providers, preserving their anonymity
This report aims to explore how to pinpoint in a map where is physically hosted a onion service and how to detect if a local network is hosting an onion service.
Tor (The Onion Router) is an anonymity network that routes internet traffic through multiple encrypted relays (nodes) worldwide. This multi-hop structure ensures that no single node knows both the origin and destination of the traffic, making it difficult to trace. Tor achieves anonymity by:
Entry and Exit Nodes: The entry node sees the user's IP, while the exit node sees the destination, but neither node has complete information.
Rendezvous Point: TOR node where both the client and the web server agree to "meet" (both of them use their 3 nodes secure route to reach this node)
Onion services (formerly called hidden services) are web services that operate entirely within the Tor network. They are accessed using .onion addresses, which obscure the server's IP address. Key characteristics of onion services include:
The lifecycle of an onion service can be described through the following steps:
Service Creation and Publication:
Client Request:
Rendezvous Point Establishment:
Rendezvous Connection:

Detecting whether a local network is hosting Onion services involves analyzing specific network patterns, identifying Tor-related characteristics, and recognizing known traffic behaviors.
The laboratory setup is configured on a Raspberry Pi 4B. Ideally, we would detect the activity of the TOR Onion Service from another machine within the same network. However, since the Raspberry Pi is directly connected to the router via an RJ45 Ethernet cable, this is not feasible. As a result, the TShark instance is also running on the Raspberry Pi, albeit from a different Docker container. Both containers operate on the network as if they were the Raspberry Pi itself, rather than through a special IP or NAT configuration. This arrangement allows the TShark container to monitor the traffic generated by the Onion Service container.
Once the laboratory environment is fully operational, we can initiate our testing procedures. We conducted two distinct experiments to manually analyze the generated traffic. In both tests, we began by launching the TShark instance to capture all traffic on ports 80 and 443, followed by executing the action to be tested. The first test involved starting the Onion Service to monitor its connections to the Introduction Points. The second test consisted of accessing the Onion Service using the TOR Browser. The setup of the environment, including files and source code, can be found in Annex 1.

After capturing and manually analyzing the network traces from both tests, we reached the following conclusions:
The second practical part of this report focuses on determining whether it is possible to approximate the physical location of a TOR Onion Service. For this experiment, we will reuse the same laboratory setup as in the previous section, which is located in Zaragoza, Aragón, Spain.
To determine the server's location, we will measure the loading time of a reasonably sized website (approximately 8 MB) from various locations around the globe. In theory, the greater the distance between the server and the requesting host, the longer it will take for all data to reach the querying host. By collecting measurements from a sufficient number of locations, we can estimate the server's location more accurately.
Measuring the time required to establish a connection and transfer data over the TOR network yields significant insights into the nature of the traffic. Several factors influence these time measurements:
To perform the test we have booted up several Windows 11 VMs around the world by using Microsoft Azure cloud, inside each VM we accesed the web server from within TOR Browser. Details regarding the setup of the Virtual Machines can be found in Annex 2. The following table summarizes the time measurements observed when connecting from various Azure regions:
| Az Region | Loading Time | Circuit Node 1 | Circuit Node 2 | Circuit Node 3 |
|---|---|---|---|---|
| Spain Central | 16 sec | Switzerland | Germany | Poland |
| Brazil South | 28 sec | UK | Luxembourg | Germany |
| Australia East | 55 sec | Finland | Germany | UK |
| US West 2 | 46 sec | Switzerland | France | UK |
| Africa South | 37 sec | Netherlands | Italy | Germany |
| Korea Central | 2 min 55 sec | Spain | US | France |
| Israel Central | 1 min 18 sec | Netherlands | Germany | Finland |
| Poland Central | 22 sec | Moldova | US | Netherlands |
| UK South | 40 sec | Sweden | Germany | US |
| US East | 46 sec | Luxembourg | Finland | Russia |
The loading times recorded from various Azure regions provide critical insights into the geographical proximity of the Tor circuit nodes and the potential locations of onion services. Additional routing information can be found in Annex 3.
The following key observations emerge from the analysis:
Shortest Loading Times:
Longest Loading Times:
Moderate Loading Times:
Regional Node Analysis:
Consistent Trends:
This study demonstrated the effectiveness of analyzing network traffic to detect TOR Onion Services on a LAN and approximate their physical locations around the globe. By capturing and examining the traffic, we identified key characteristics, including the use of UDP on port 443. Only the Entry Guard IP address was observable, preventing the identification of the Introduction Point or Rendezvous Points. We also found that the Onion Service initiates communication with a limited number of packets, followed by exchanges to establish the circuit.
Additionally, we measured the loading time of an 8 MB website accessed through the TOR network from various global locations. Results indicated that the Onion Service accessed from the Spain Central region is likely hosted within Spain, as evidenced by a short loading time of 16 seconds. Latency patterns highlighting the influence of geographical proximity from the different relays that compose the whole circuit.
This section presents the directory and file structure used to configure TOR on a Raspberry Pi and to utilize TShark for capturing all network traffic.
+------------------------+
| / |
| |-- docker-compose.yml |
| |-- hiddenservice |
| | `-- Dockerfile |
| |-- trafficcaps |
| |-- tshark |
| | `-- Dockerfile |
| `-- webserver |
| |-- randomtext.txt |
| `-- webserver.py |
+------------------------+
The project structure consists of the following components:
The contents of the docker-compose.yml file, which is essential for defining and managing the services, are as follows:
version: '3.9'
services:
hiddenservice:
build:
context: ./hiddenservice
container_name: hiddenservice
network_mode: host
restart: always
volumes:
- ./webserver:/app
tshark:
build:
context: ./tshark
container_name: tshark
network_mode: host
volumes:
- ./trafficcaps:/trafficcaps
cap_add:
- NET_ADMIN # Grants network administration capabilities
- NET_RAW # Grants raw socket access
privileged: true # Gives the container elevated privileges (optional)
restart: always
This configuration defines two main services: - hiddenservice: Builds from the ./hiddenservice directory and runs a TOR hidden service. - tshark: Builds from the ./tshark directory and runs TShark for capturing network traffic, with the necessary permissions to operate effectively.
The hiddenservice/Dockerfile is crucial for setting up the TOR hidden service. The contents of this Dockerfile are as follows:
# Use the Ubuntu 20.04 base image
FROM ubuntu:20.04
# Set environment variable to prevent interactive prompts during installation
ENV DEBIAN_FRONTEND=noninteractive
# Update package lists and install required packages (curl, git, vim, tor, python3)
RUN apt update && apt install -y curl git vim tor python3 python3-pip
# Append the required lines to the torrc configuration file
RUN echo "HiddenServiceDir /var/lib/tor/hidden_service/" >> /etc/tor/torrc && \
echo "HiddenServicePort 80 127.0.0.1:50505" >> /etc/tor/torrc
RUN pip3 install flask
# Expose the port that the Python HTTP server will run on (8000 by default)
EXPOSE 50505
# Run both the Python HTTP server and the tor service in the background
CMD cd /app && python3 webserver.py & \
tor & \
tail -f /dev/null
The tshark/Dockerfile configures TShark within a container. Its contents are as follows:
# Use a lightweight alpine image
FROM alpine:latest
# Install tshark
RUN apk update && \
apk add --no-cache tshark
# Keep the container idle by running a sleep loop (or tail -f /dev/null)
CMD ["tail", "-f", "/dev/null"]
This Dockerfile uses a lightweight Alpine image, installs TShark, and keeps the container running with an idle command, allowing TShark to operate and capture traffic effectively.
The following code block presents the webserver/webserver.py script, which sets up a simple web server using Flask:
from flask import Flask
app = Flask(__name__)
with open('randomtext.txt', 'r') as file:
file_contents = file.read()
@app.route('/')
def home():
return '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Simple Web Page</title>
</head>
<body>
<h1>Welcome to My Web Page!</h1>
<p>It works!</p>
<p>''' + file_contents + '''
</p>
</body>
</html>
'''
if __name__ == '__main__':
app.run(host='localhost', port=50505)
This script utilizes Flask to create a simple web server that serves an HTML page. It reads the contents of randomtext.txt and dynamically displays them on the web page, providing an easy way to test the setup.
This section presents how to set up the laboratory on Microsoft Azure Cloud. Starting with the general configurations followed by images depicting the configuration of various virtual machines (VMs) in Microsoft Azure. The configuration illustrates the setup, including the types of virtual machines used, their specifications, and their interconnections.
Microsoft Azure is a leading cloud computing platform that provides a wide range of services, including the ability to create and manage virtual machines (VMs). These VMs can be quickly deployed to meet various workloads and requirements.
Before starting to create things we must create a subscription (a.k.a where are going the bills, and how are going to be paid), in this step is crucial to put a budget limit (we don't want to become poor from one day to another because of a error in the Cloud). Once we have our brand new subscription with a budget limit we need to create a resource group to group all the resources we are creating to run our laboratory (This can be done directly from the creation process of the 1º VM). Finally we can start creating VMs, to do so users typically follow these steps:
The images below showcase the results of the VMs created, displaying their configurations and how they are set up to interact with each other.




The previous images show the layout of multiple virtual machines deployed in Microsoft Azure. Each virtual machine is configured with specific resources, such as CPU, RAM, and storage, to meet the needs of different applications. The configuration also includes networking setups, allowing the virtual machines to communicate with each other and with other Azure services. This flexibility enables efficient resource management and scalability for various workloads.


The total cost for all the tests conducted was 1.80€
This section presents representative images of the Tor circuits established during the tests. Each image illustrates the configuration of the nodes and the traffic routes within the Tor system. The map shows the locations of the virtual machines in green and the .onion server in pink.





