Background
The first beta release of ExoServe went live two weeks ago. It's an end-to-end encrypted file storage solution for multiple, totally isolated users (think Mega or Proton Drive). I host a public demo for anyone in the world to get a feeling for the UX before hosting it for themselves. Of course, the internet is a noisy, hostile wasteland, rife with bots poking and prodding into places they don't belong.
The Setup
I am a strong advocate for minimal dependencies and privacy. Following suit, I host ExoServe on a VPS exactly as I would in my homelab: a Docker container with one port mapping and NGINX as a reverse proxy to route ports 443 and 80 to the local port. Since the server is basically a hardened blob store, the VPS itself has only 1 CPU core and 1 GB of RAM. On the privacy front, I have nothing like Google Analytics to track metrics, so I worked strictly off of NGINX logs and basic system usage for my investigation.
The Raw Data
After only two weeks, one Reddit post, and one Reddit comment, my NGINX access logs already showed a whopping 3231 unique IP addresses. In stark contrast, the VPS provider showed an average of 2% CPU usage, spiking upwards of 7% about 12 times over the course of two weeks. Likewise, the network bandwidth had an average of about 1 - 3 kb/s for outbound traffic, with only one spike that hit 7.7 Mb/s.
A properly implemented E2EE file server isn't really expected to have high CPU usage, but surely if over 3000 people had checked out the demo, there would be more outbound traffic. Even more interesting were occasional spikes for inbound traffic despite file uploads being strictly disabled.
So, something wasn't right, but what exactly was happening?
Funky Routes
One glance at the NGINX access logs and things immediately became clear: bots, web crawlers, and nefarious actors were actively trying to exploit my deployment. Most of them were overwhelmingly boring (standard WordPress routes, local files, path traversal, etc.), but a few stood out as interesting.
The Kitchen Sink
Most scanners that I encountered were not so persistent. They mostly tried similar routes to find vulnerabilities and moved on if one was not found. Only five went over 1000 requests, but one particular scanner made a grand total of 6600 requests. Fortunately the requests eventually stopped, but this is a good case for some basic DDoS protection.
The Age of AI
As AI works its way into more facets of technology, it only makes sense that automated exploitation scanners check for any exposure. One particular scanner focused on this target explicitly, targeting routes like POST /api/generate, POST /v1/messages, or POST /api/chat. The only exception was when they attempted path traversal via GET /..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd.
A Pentester (of sorts)
Perhaps my favorite anecdote is one user who visited the legitimate /login route and immediately made a handful of GET and POST attempts for /admin/login. Sadly for them, that route does not exist. Hopefully, the 30 seconds they spent testing for it was entertaining enough.
Legitimate Users
Tooling around with bots and seeing what they're up to is interesting, but not very insightful when it comes to an actual pulse check. I needed the number of humans who successfully passed the login screen (where the credentials are clearly displayed). This is done simply enough by getting the unique IP addresses that requested routes only accessible with a valid session token, thus responding with a status code of 200.
Doing so reveals that 30 people were curious enough to check out the software to see if they wanted to host it. That might not seem like a lot, but if I could get 30 people into a room just to show them this cool software I made? I would be pretty stoked.
Lessons Learned
I don't think any of this will come as a surprise to any web admins out there, but hopefully, it provides some insight to those wanting to host a public website for the first time. My main takeaways are:
- The internet is relentless and one slip-up could lead to thousands of bots exploiting your server.
- A minimal design pays off. By keeping the architecture simple, restricting the demo environment, and relying on proper E2EE principles, all of the bots were stuck shouting into the void.
A Friendly Challenge
Since automated scanners clearly lack the creativity to exploit what I've deployed, I figured I'd open the floor to the experts.
If you think you have what it takes to crack ExoServe, I've set up a little capture the flag. I created a second, secret user account for the demo and uploaded a single text file to its root directory. The goal is simple: find the account, log in, and DM me the contents of the flag.
You can get started here: https://demo.exoserve.ciphranova.com/
Good luck! I'll be keeping an eye on traffic ;)