MGx0: Spider Sector

The Null Drop: Anonymous File Sharing in C

πŸ““ Before You Read

These are personal research notes β€” a record of something I built and found worth documenting. I explain the core ideas and design choices, but this is not a step-by-step guide, a support thread, or a turnkey implementation.

This blog is my lab notebook.

⚠️ Source code is intentionally incomplete. Snippets are illustrative and will not compile or run as-is.


Disclaimer

This material is provided strictly for educational and ethical security research purposes.

By continuing, you agree that:

Do not use this knowledge to access systems without permission, disrupt services, collect data unlawfully, or violate applicable cybersecurity or privacy laws in your jurisdiction.

The intent is to advance defensive understanding, privacy awareness, and ethical research β€” nothing more.

Proceed responsibly.

Table of Contents

  1. Overview
  2. How TOR Works
  3. What "Your IP Never Reaches the Server" Means
  4. AES-256 Encryption
  5. 0x0.st β€” The File Host
  6. The Full Security Stack
  7. C Implementation
  8. Setup & Usage
  9. Threat Model
  10. Latency & Trade-offs
  11. Key Concepts Glossary
  12. References
  13. Final Thoughts

1. Overview

This system combines three independent components to achieve anonymous, encrypted file sharing:

Component Role Protects Against
AES-256-CBC Encrypts file content Anyone reading the file
TOR Network Hides your IP address Server knowing who you are
0x0.st Hosts the encrypted blob Need to run your own server
PBKDF2-SHA256 Hardens the password Brute-force attacks

The key principle: no single point of failure. Even if someone compromises 0x0.st, they only see encrypted ciphertext. Even if they break the encryption, they cannot trace who uploaded it because TOR hid the uploader's IP.


2. How TOR Works

TOR (The Onion Router) routes your traffic through three volunteer-operated nodes before reaching the destination. Each node only knows the previous and next hop β€” never the full path.

The 3-Hop Circuit

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     YOU     β”‚     β”‚  Guard Node  β”‚     β”‚ Middle Node  β”‚     β”‚  Exit Node   β”‚
β”‚ 103.45.67.x │────▢│   Germany    │────▢│ Netherlands  │────▢│   Romania    β”‚
β”‚             β”‚     β”‚              β”‚     β”‚              β”‚     β”‚              β”‚
β”‚ Knows:      β”‚     β”‚ Knows:       β”‚     β”‚ Knows:       β”‚     β”‚ Knows:       β”‚
β”‚  - Guard IP β”‚     β”‚  - Your IP   β”‚     β”‚  - Guard IP  β”‚     β”‚  - Middle IP β”‚
β”‚             β”‚     β”‚  - Middle IP β”‚     β”‚  - Exit IP   β”‚     β”‚  - Dest. IP  β”‚
β”‚             β”‚     β”‚  NOT dest.   β”‚     β”‚  NOT you     β”‚     β”‚  NOT you     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                                      β”‚
                                                                      β–Ό
                                                                   0x0.st
                                                            Sees: Romania IP only

Onion Encryption Layers

Before sending, your TOR client wraps the data in three layers of encryption β€” one for each node:

Original Data
    └── Encrypted for Exit Node        ← Exit node decrypts this layer
        └── Encrypted for Middle Node  ← Middle node decrypts this layer
            └── Encrypted for Guard    ← Guard node decrypts this layer

Each node peels one layer, like peeling an onion β€” hence the name.

Why No Single Node Can Betray You

Node Knows Your IP? Knows Destination?
Guard Node βœ… Yes ❌ No
Middle Node ❌ No ❌ No
Exit Node ❌ No βœ… Yes

No single node has both pieces of information simultaneously.


3. What "Your IP Never Reaches the Server" Means

Without TOR β€” Direct Connection

Your PC ──────────────────────────────────────▢ 0x0.st
IP: 103.45.67.89                                Logs: 103.45.67.89
                                                ISP also logs this connection

The server's access log records your real IP. Law enforcement can subpoena these logs. Your ISP also sees the destination.

With TOR β€” Anonymized Connection

Your PC ──▢ Guard ──▢ Middle ──▢ Exit ──▢ 0x0.st
103.45.67.89                     185.220.x.x  Logs: 185.220.x.x (Exit node)

0x0.st logs the exit node's IP, which is a volunteer's server β€” not yours. Your real IP 103.45.67.89 never appears in any request to the destination server.

DNS Leak Prevention β€” socks5h:// vs socks5://

This is a critical implementation detail:

// ❌ WRONG β€” DNS resolved locally (leaks hostnames to your ISP)
#define TOR_PROXY  "socks5://127.0.0.1:9050"

// βœ… CORRECT β€” DNS resolved inside TOR (no leak)
#define TOR_PROXY  "socks5h://127.0.0.1:9050"
//                         ^
//                         h = hostname resolution through TOR

Without socks5h, your system sends DNS queries for 0x0.st to your ISP's DNS server before connecting through TOR. This reveals which sites you're visiting even if the content is hidden.


4. AES-256 Encryption

What is AES-256-CBC?

AES (Advanced Encryption Standard) with a 256-bit key in CBC (Cipher Block Chaining) mode is a symmetric encryption algorithm used by governments, militaries, and financial institutions worldwide.

Key Derivation β€” PBKDF2-SHA256

A human password like "hunter2" is too short and weak to use directly as an AES key. PBKDF2 (Password-Based Key Derivation Function 2) solves this:

Password: "hunter2"  +  Random Salt (16 bytes)
                ↓
    PBKDF2-SHA256  Γ—  200,000 iterations
                ↓
    AES-256 Key (32 bytes) β€” looks like random data

The 200,000 iterations mean an attacker trying to brute-force the password must run the hash function 200,000 times per guess. At 1 billion guesses/second, cracking a 12-character random password would take longer than the age of the universe.

The Encrypted Blob Structure

The program stores all decryption metadata alongside the ciphertext in a single binary blob:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  BLOB HEADER (fixed size)                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚ Magic    β”‚ Salt         β”‚    IV    β”‚ Lengths       β”‚ β”‚
β”‚  β”‚ "0X0E"   β”‚ 16 bytes     β”‚ 16 bytes β”‚ 8+8 bytes     β”‚ β”‚
β”‚  β”‚ 4 bytes  β”‚ (random)     β”‚ (random) β”‚               β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  CIPHERTEXT (variable size)                             β”‚
β”‚  [ encrypted file data ... ]                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Field Purpose
Magic Identifies the blob format (0X0E)
Salt Random value β€” makes each encryption unique even with same password
IV Initialization Vector β€” randomizes CBC mode
Lengths Needed to correctly decrypt and verify output size
Ciphertext The actual encrypted file data

5. 0x0.st β€” The File Host

0x0.st (the "null pointer") is a minimalist file hosting service:

Upload API

# Upload any file
curl -F "file=@myfile.bin" https://0x0.st

# Response:
# https://0x0.st/AbCd.bin
# X-Token: secrettoken123

Delete API

# Delete using token
curl -F "token=secrettoken123" -F "delete=" https://0x0.st/AbCd.bin

Why 0x0.st Over PasteBin?

Feature 0x0.st PasteBin
API Key Required ❌ No βœ… Yes
Binary file support βœ… Yes ❌ No (text only)
Deletion token βœ… Yes (X-Token) ⚠️ Limited
Account needed ❌ No Optional
Size limit ~512 MB ~10 MB

Binary support is critical here β€” our encrypted blob is raw binary data, not text.


6. The Full Security Stack

Encryption Flow (Upload)

Original File
      β”‚
      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  1. Generate random Salt + IV   β”‚  (RAND_bytes β€” cryptographically secure)
β”‚  2. Derive AES key via PBKDF2   β”‚  (password + salt β†’ 32-byte key)
β”‚  3. AES-256-CBC encrypt         β”‚  (plaintext β†’ ciphertext)
β”‚  4. Prepend blob header         β”‚  (salt, iv, lengths)
β”‚  5. Write binary blob to temp   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚
      β–Ό
Encrypted Blob (binary)
      β”‚
      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  6. CURL multipart POST         β”‚
β”‚  7. Via SOCKS5h β†’ TOR daemon    β”‚  (127.0.0.1:9050)
β”‚  8. TOR 3-hop circuit           β”‚  (Guard β†’ Middle β†’ Exit)
β”‚  9. Exit node β†’ 0x0.st          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚
      β–Ό
URL + Token (stored in receipt.txt)

Decryption Flow (Download)

URL + AES Password
      β”‚
      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  1. CURL GET via TOR            β”‚  (anonymous download)
β”‚  2. Verify magic bytes "0X0E"   β”‚
β”‚  3. Extract salt, IV, lengths   β”‚
β”‚  4. Derive AES key via PBKDF2   β”‚  (same password + stored salt)
β”‚  5. AES-256-CBC decrypt         β”‚
β”‚  6. Verify plaintext length     β”‚
β”‚  7. Write to output file        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚
      β–Ό
Original File (restored)

7. C Implementation

Core CURL TOR Setup

The most important function β€” applies TOR proxy to every network request:

static CURL *curl_tor_init(void) {
    CURL *curl = curl_easy_init();

    // Route ALL traffic through TOR SOCKS5h proxy
    curl_easy_setopt(curl, CURLOPT_PROXY,     "socks5h://127.0.0.1:9050");
    curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME);

    // Security settings
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);  // Verify TLS cert
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);  // Verify hostname
    curl_easy_setopt(curl, CURLOPT_TIMEOUT,        120L); // TOR is slower
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.88.0"); // Generic UA

    return curl;
}

Key Derivation

static int derive_key(const char *pass, const unsigned char *salt,
                      unsigned char *key) {
    return PKCS5_PBKDF2_HMAC(
        pass, strlen(pass),   // Password
        salt, SALT_LEN,       // Random salt (16 bytes)
        200000,               // 200,000 iterations
        EVP_sha256(),         // Hash function
        AES_KEY_LEN,          // Output: 32 bytes
        key
    );
}

TOR Verification

The program can verify TOR is working before uploading:

// Hits https://check.torproject.org/api/ip
// Returns: {"IsTor":true,"IP":"185.220.x.x"}

Compile

# Install dependencies
sudo apt install libssl-dev libcurl4-openssl-dev

# Compile
gcc secure_0x0_tor.c -o secure_0x0_tor -lssl -lcrypto -lcurl

8. Setup & Usage

Step 1 β€” Install and Start TOR

# Install TOR
sudo apt install tor          # Debian/Ubuntu
brew install tor              # macOS

# Start the daemon
sudo systemctl start tor
sudo systemctl enable tor     # Auto-start on boot

# Verify TOR is listening on port 9050
ss -tlnp | grep 9050

Step 2 β€” Verify TOR Connection

./secure_0x0_tor check

# Expected output:
# [+] Response: {"IsTor":true,"IP":"185.220.101.x"}
# ╔══════════════════════════════════════════╗
# β•‘   βœ“ Connected through TOR network       β•‘
# β•‘   Your real IP is hidden                β•‘
# β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

Step 3 β€” Encrypt & Upload

./secure_0x0_tor encrypt secret.pdf "my-strong-password"

# Output:
# [+] Read 42391 bytes from 'secret.pdf'
# [+] Key derived (PBKDF2-SHA256, 200k rounds)
# [+] Encrypted 42391 β†’ 42400 bytes
# [+] Uploading via TOR β†’ https://0x0.st ...
#
# ╔════════════════════════════════════════════════════════╗
# β•‘          UPLOAD SUCCESSFUL (via TOR) βœ“                β•‘
# ╠════════════════════════════════════════════════════════╣
# β•‘  URL   : https://0x0.st/AbCdEfGh.bin                  β•‘
# β•‘  Token : a1b2c3d4e5f6...                               β•‘
# β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

Step 4 β€” Share With Recipient

Share these three things separately (never together in one message):

1. URL     β†’ https://0x0.st/AbCdEfGh.bin    (can send openly)
2. Token   β†’ a1b2c3d4...                    (keep private β€” for deletion)
3. Password β†’ "my-strong-password"           (send via Signal or in person)

Step 5 β€” Recipient Decrypts

./secure_0x0_tor decrypt https://0x0.st/AbCdEfGh.bin "my-strong-password"

# Output file: decrypted_AbCdEfGh.bin

Step 6 β€” Delete After Use

./secure_0x0_tor delete https://0x0.st/AbCdEfGh.bin "a1b2c3d4e5f6..."
# HTTP 200 β€” Deleted successfully

9. Threat Model

What This System Protects Against

Threat Protected? How
0x0.st seeing your IP βœ… Yes TOR exit node IP shown instead
ISP seeing destination βœ… Yes TOR encrypts traffic
Network surveillance / MITM βœ… Yes TOR + TLS
Server compromise β€” reading files βœ… Yes AES-256 ciphertext only
Passive global traffic analysis ⚠️ Partial TOR reduces but doesn't eliminate
Someone with your URL but no password βœ… Yes AES-256 encryption
DNS leaks βœ… Yes socks5h:// resolves DNS inside TOR

What This System Does NOT Protect Against

Threat Protected? Notes
Malware on your own machine ❌ No Keylogger can steal password
Weak AES password ❌ No Use 12+ random characters
Operational security mistakes ❌ No Logging in to accounts while using TOR
Advanced timing attacks ❌ No Nation-state level adversaries
Physical access to your machine ❌ No Disk forensics can find temp files

Password Strength Recommendations

Password Time to Crack (200k PBKDF2) Rating
password123 Seconds ❌ Never use
correct-horse-battery Years ⚠️ Passable
Xk9#mP2$vL7nQ4@ Heat death of universe βœ… Excellent
Random 20-char alphanumeric Heat death of universe βœ… Excellent

10. Latency & Trade-offs

Why TOR is Slower

Your data travels through 3 servers across the world instead of going directly:

Direct connection:
  You ─────────────────────────────── 0x0.st
  Latency: ~50ms

TOR connection:
  You ── Germany ── Netherlands ── Romania ── 0x0.st
  Latency: ~2000ms (40Γ— slower)

Each hop adds:

File Upload Time Estimates

File Size Direct Via TOR
10 KB < 1 sec 5–15 sec
100 KB 1–2 sec 15–30 sec
512 KB (our limit) 2–5 sec 30–90 sec

The Trade-off is Worth It

The latency cost is entirely acceptable for sensitive file sharing where anonymity matters. For real-time streaming or large files, TOR is the wrong tool β€” but for occasional secure uploads, 30–90 seconds is a small price for hiding your identity completely.


11. Key Concepts Glossary

Term Definition
AES Advanced Encryption Standard β€” symmetric block cipher used worldwide
CBC Cipher Block Chaining β€” each ciphertext block depends on the previous
PBKDF2 Password-Based Key Derivation Function 2 β€” stretches weak passwords into strong keys
Salt Random bytes added to password before hashing β€” prevents rainbow table attacks
IV Initialization Vector β€” random value that randomizes the first CBC block
TOR The Onion Router β€” anonymity network routing traffic through 3 hops
Exit Node The last TOR hop β€” the IP address the destination server sees
SOCKS5h Proxy protocol where DNS resolution happens on the proxy side (inside TOR)
DNS Leak When DNS queries bypass TOR, revealing which sites you visit to your ISP
0x0.st Minimalist anonymous file host β€” no account, returns URL + delete token
X-Token HTTP response header from 0x0.st containing the file deletion secret
Blob Binary data structure combining the encrypted blob header and ciphertext
Multipart POST HTTP file upload format used to send binary files to 0x0.st
CURLOPT_PROXYTYPE libcurl option specifying the proxy protocol type

12. References


13. Final Thoughts

Three components, zero overlap in what they know, no single point of failure. The encryption hides the content. TOR hides the sender. 0x0.st asks no questions. None of these are new ideas β€” the interesting part was wiring them together in C and making sure the socks5h detail didn't get missed.

If you're reading this because you're building something similar β€” pay attention to your DNS. That's the part most people get wrong.

AES ate it. TOR lost it. Nobody saw nothing.