More counter.social "private account" bypasses

Published on , 2128 words, 8 minutes to read

An image of mushroom cloud, cityscape, 1girl, gas mask, ninja, dystopian
mushroom cloud, cityscape, 1girl, gas mask, ninja, dystopian - Waifu Diffusion v1.3

Hi there. This is a followup to my article about the vulnerabilities I found in a mastodon server named counter.social. This community is powered by a very hacked up fork of Mastodon, a popular federated social media platform you can self-host that behaves something like Twitter did before the Elon takeover.

Background

counter.social is a social network built on the open source software Mastodon. For various reasons, counter.social is one of the few Mastodon servers that does not federate to the larger community, and as such has implemented unique account security features that allows it to differentiate itself from other Mastodon instances. It also has an embedded stream of CNN and other news sites.

This social network is run by the hacktivist th3j35t3r. He has an extensive rapsheet and had drama with popular hacking groups like LulzSec. th3j35t3r is a very unstable figure in the best of times, so it has been interesting to see the fallout of his operations of a Mastodon server.

Cadey is coffee
<Cadey>

For various reasons, I think that the best way to describe counter.social's federation policy as "should not federate" rather than "does not federate". But, I digress, for all practical reasons you can treat it as "does not federate" because they broke the federation API in weird ways.

Earlier in November 2022, I discovered a number of trivial exploits that could let you bypass its "private account" system, also called a "public landing page". One of the main things this system lets you do is have an account that is "public" to other users of counter.social, but does not index on Google search. This security method was implemented using JavaScript and a HTML <iframe> element. Needless to say, this mechanism was trivially bypassed by either using curl -H "Accept: application/json" or disabling JavaScript in your browser.

Cadey is facepalm

The fixes

To give th3j35t3r some credit, the main problems I reported were fixed. If you make unauthenticated requests to the federation API, Cloudflare's web application filter will block them. If you view those things from a browser, you get 302 redirected to the same iframe that says "lol no that page doesn't work friend".

I'd personally like to see the redirect be replaced with either the 404 page or some error page that describes things instead of the 302 redirect, but this does work.

The other problems seem to have been fixed by blocking other API calls, but I don't know if the way that the API calls were blocked would break other clients working. For various reasons that I am about to get into, this was difficult to test.

Mara is hmm
<Mara>

Wait, isn't most of this technically public information? All of the posts you've mentioned have a privacy profile of public, which means that being able to see them isn't surprising or novel at all. Why would anyone care about this?

Cadey is coffee
<Cadey>

Here's why:

Mara is hmm
<Mara>

Yeah, maybe that is a good reason.

Cadey is coffee
<Cadey>

If I'm not supposed to view a thing without being authenticated, it's a bug if I'm viewing it without being authenticated.

counter.social participates in retaliation against researchers doing responsible disclosure

When I made that earlier disclosure, I was banned in retaliation after making my standard public announcement on it. I don't have the contents of the toot anymore, but I said something along the lines of "I hacked counter.social" on counter.social with my burner account and I was banned within 5 minutes because of it. After complaining about this on Twitter, I got blocked on Twitter too.

Amusingly my home IP address is listed as a "rogue state actor", which my friends at the pretend CIA have to disagree with:

Central Intelligence Agency :verified:
2022-12-06T16:24:47.140952Z
Dear @cadey,

We at the CIA are pleased to inform you that after careful consideration, we have determined that you are not a hostile nation state. In fact, we don't even see you as a threat at all. Keep up the good work!

Best regards,
The CIA
Link
Cadey is enby
<Cadey>

Honestly this is one of the highlights of my career as a technical communicator!

Honestly, at this point I was ready to just call things a loss and ignore the situation. Nothing good would come of me raising a stink about things, and apparently th3j35t3r has been leveling false representations about the vulnerability I discovered and reported. He got all up in arms about me accessing "public content", but if it was public then why do users not have the public landing page feature enabled? Why would that be "public"? It doesn't make sense, but apparently we're dealing with troll logic so who knows anymore?

This whole situation also frustrates me in particular because I used to look up to th3j35t3r as a bit of a hacktivist role model when I was in my edgelord teenager phase that everyone goes through. I am told that finding out your childhood heroes are shitbags is a common experience and that in general you should never meet your heroes. I can't agree more after this experience.

Oh also apparently there was supposed to be a bug bounty for counter.social for doing the first exploit. I did not receive any such payout. Should th3j35t3r be reading this post, please get in contact with me to arrange payment. I take PayPal, Bitcoin, and Ethereum.

I found more vulnerabilities in counter.social's "private account" feature. I'm going to step through them and explain how the routing stack in Rails works so that I can show you how to find more of them.

Mara is hacker
<Mara>

As a regular reminder, if you are running a Mastodon server that you don't want to federate with the public Internet and additionally don't want it to be open for scraping, you should enable secure mode to prevent unauthorized servers from federating with your server. If th3j35t3r would have enabled secure mode, none of these vulnerabilities would work.

Here's some irresponsible disclosure.

The "featured" collection

Every so often I look at the error logs in my servers. This is purely for my own amusement, and one day I ended up looking at the error log on my Akkoma server. Akkoma is a Mastodon-compatible social media server, and as such it will sometimes give you error messages when it has trouble poking mastodon servers for whatever reason. I noticed a URL pattern come up a few times:

/users/{username}/collections/featured

When I ran this against my Mastodon account, I got the contents of my pinned posts. This immediately made me wonder if this would work on counter.social. Needless to say, it does. This is yet another information disclosure that can be easily solved by enabling secure mode. This route shows you pinned posts so that viewing a new remote profile on another server shows you something useful other than "lol I don't know anything yet".

Cadey is coffee
<Cadey>

Also for what it's worth, I was able to access the featured collection on my home IP address even after it was blocked. I'm starting to get this weird feeling that the IP address blocklist is also implemented with client-side JavaScript. I haven't cared to reverse-engineer things though.

I thought to try this on counter.social because I got a random follow from someone on it to my pony.social account. This struck me as super odd because I thought that the server wasn't meant to federate. It is still partially federating but both the follow back and DM I sent are not going to result in anything useful I don't think. Apparently the sidekiq jobs that I made doing that are never going to succeed for a very weird reason: th3j35t3r changed the server inbox route to /etc/passwd.

Security through what the hell

In ActivityPub, actors have inboxes and outboxes. New items are put into the inbox and fetched from the outbox. Conventionally, each actor's inbox is supposed to be at https://{actor_base}/inbox and the outbox is supposed to be at https://{actor_base}/outbox. Servers in ActivityPub have their own inboxes and outboxes for various federation errata.

For some reason, th3j35t3r changed the server inbox to https://counter.social/etc/passwd. This breaks incoming federation from remote ActivityPub servers. I don't have any idea why this path in particular was chosen, but my Mastodon server admin suspects it's so that they can file abuse complaints with hosters that people are trying to get the passwords of the remote system.

Cadey is coffee
<Cadey>

If you have ideas, please let me know what they are. I have no clue here.

This is an interesting case of security through obscurity, but I feel that it would be better to just block all federation attempts instead.

More digging

Since this was the fifth such information disclosure I have found, I started to wonder if there were more that I wasn't aware of. So like any rational person I decided to download the source code of Mastodon and take a look at its routing stack to see what else is there.

$ git clone https://github.com/mastodon/mastodon ~/code/mastodon/mastodon

When you are looking at a program, it's usually useful to start at the main function and work your way out from there. Most programs will declare everything the program needs in its main function and pass those around to start various things up. One of the main entrypoints into apps written with Ruby on Rails is its routing stack at config/routes.rb. So let's look there.

Some things that stand out are the two routes that I used to attack counter.social in the past. These routes let you fetch a user as json or one of their posts as json.

Mara is hacker
<Mara>

When other servers are federating, they don't just blindly append .json to the end of URLs like these examples here do. These exmaple URLs tack on .json to force Rails to render JSON to the user to help illustrate the point. In practice federated requests will have authentication via signatures and use the Accept: application/json header.

Then we get to the meaty part. This table of routes spells out all of the things that clients can do over HTTP. I'm not totally sure how that relates to HTTP urls, or routes, but we can easily start comparing the route names in here against the ActivityPub spec and Mastodon documentation.

The collections thing stands out. It seems that there are three kinds of collections defined in the code:

Only the featured collection seems to work on counter.social. Other routes of interest are the outbox (which seems to be incorrectly blocked as you can access the root outbox path that tells you how many toots a counter.social user made, which may be useful for other kinds of signal intelligence), his list of followers (which 403s), and the list of replies (which also 403s).

The only information disclosure left is the featured collection.

Webfinger

ActivityPub relies on Webfinger to look up information on remote users. Webfinger operates on /.well-known/webfinger, and if you block that route, federation will just totally fail.

Guess what counter.social doesn't block? This lets you get metadata about users and any aliases they have. This is ultimately useless from my standpoint, but blocking that would remove most of the problems to begin with, so there is that.

Somebody set up us the bomb

Fun fact: you can put my Mastodon profile into your RSS reader. Another fun fact: this works on counter.social too and lets you bypass the authorization logic for the "private account" feature. This also works if you add .rss to the end of the URL too, and it might work if you add .atom to the end of the URL.

Have fun!


Facts and circumstances may have changed since publication. Please contact me before jumping to conclusions if something seems wrong or unclear.

Tags: CoSo, RubyOnRails, hacking