aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXe Iaso <me@christine.website>2022-12-20 09:58:19 -0500
committerXe Iaso <me@christine.website>2022-12-20 09:58:19 -0500
commit65861ccd98cc5992fd916a77188e0778c752caef (patch)
treecded6e1f23c472727a16e4d58bf36ea2d8afd4d8
parent66527587726c7cf647e8535ee4e0cabd9a7ad3a5 (diff)
downloadxesite-65861ccd98cc5992fd916a77188e0778c752caef.tar.xz
xesite-65861ccd98cc5992fd916a77188e0778c752caef.zip
coso part 2
Signed-off-by: Xe Iaso <me@christine.website>
-rw-r--r--blog/more-coso-bypasses.markdown263
-rw-r--r--data/toots/0b26c3f97f55b77b8f1c84e76b7b365493b881b382be8d3958326e1427cdc74e.json28
-rw-r--r--data/users/a2dcb9e5c73ef2a138e47b70a3c0cdab119366656be0ed476d46ae3c14848b27.json28
-rw-r--r--lib/xesite_types/src/mastodon.rs3
4 files changed, 319 insertions, 3 deletions
diff --git a/blog/more-coso-bypasses.markdown b/blog/more-coso-bypasses.markdown
new file mode 100644
index 0000000..45b8db3
--- /dev/null
+++ b/blog/more-coso-bypasses.markdown
@@ -0,0 +1,263 @@
+---
+title: "More counter.social \"private account\" bypasses"
+date: 2022-12-20
+author: ectamorphic
+tags:
+ - CoSo
+ - RubyOnRails
+ - hacking
+---
+
+<xeblog-hero ai="Waifu Diffusion v1.3" file="apocalypse-waifu" prompt="mushroom cloud, cityscape, 1girl, gas mask, ninja, dystopian"></xeblog-hero>
+
+Hi there. This is a followup to my article about [the vulnerabilities I found in
+a mastodon server named
+counter.social](https://xeiaso.net/blog/coso-private-account-bypass). This
+community is powered by a very hacked up fork of
+[Mastodon](https://joinmastodon.org/), a popular federated social media platform
+you can self-host that behaves something like Twitter did before the Elon
+takeover.
+
+## Background
+
+[counter.social](https://counter.social) is a social network built on the open
+source software [Mastodon](https://joinmastodon.org). 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](https://en.wikipedia.org/wiki/The_Jester_(hacktivist)) 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.
+
+<xeblog-conv name="Cadey" mood="coffee">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.</xeblog-conv>
+
+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.
+
+<xeblog-sticker name="Cadey" mood="facepalm"></xeblog-sticker>
+
+## 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.
+
+<xeblog-conv name="Mara" mood="hmm">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?</xeblog-conv>
+
+<xeblog-conv name="Cadey" mood="coffee">Here's why:<xeblog-picture path="blog/coso-private-account-blockpage"></xeblog-picture></xeblog-conv>
+
+<xeblog-conv name="Mara" mood="hmm">Yeah, maybe that is a good
+reason.</xeblog-conv>
+
+<xeblog-conv name="Cadey" mood="coffee">If I'm not supposed to view a thing
+without being authenticated, it's a bug if I'm viewing it without being
+authenticated.</xeblog-conv>
+
+## 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](https://twitter.com/theprincessxena/status/1600160959946887168), 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:
+
+<xeblog-toot url="https://national-defence.network/notice/AQKqw3MT6vRE6MF2O0"></xeblog-toot>
+
+<xeblog-conv name="Cadey" mood="enby">Honestly this is one of the highlights of
+my career as a technical communicator!</xeblog-conv>
+
+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.
+
+<xeblog-conv name="Mara" mood="hacker">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](https://docs.joinmastodon.org/spec/activitypub/#secure-mode) to prevent
+unauthorized servers from federating with your server. If th3j35t3r would have
+enabled secure mode, none of these vulnerabilities would work.</xeblog-conv>
+
+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](https://akkoma.social/) 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](https://pony.social/@cadey), 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".
+
+<xeblog-conv name="Cadey" mood="coffee">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.</xeblog-conv>
+
+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.
+
+<xeblog-conv name="Cadey" mood="coffee">If you have ideas, please let me know
+what they are. I have no clue here.</xeblog-conv>
+
+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](https://rubyonrails.org/) is its routing stack at `config/routes.rb`. So
+let's look
+[there](https://github.com/mastodon/mastodon/blob/main/config/routes.rb).
+
+Some things that stand out are [the two routes that I used to attack
+counter.social in the
+past](https://github.com/mastodon/mastodon/blob/c1de6730604f526a6c2d19adcf6f195352de0641/config/routes.rb#L84-L85).
+These routes let you fetch [a user as
+json](https://pony.social/users/cadey.json) or [one of their posts as
+json](https://pony.social/users/cadey/statuses/109542758692635818.json).
+
+<xeblog-conv name="Mara" mood="hacker">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.</xeblog-conv>
+
+Then we get to the [meaty
+part](https://github.com/mastodon/mastodon/blob/c1de6730604f526a6c2d19adcf6f195352de0641/config/routes.rb#L88-L108).
+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](https://www.w3.org/TR/activitypub/) and [Mastodon
+documentation](https://docs.joinmastodon.org/spec/activitypub/).
+
+The collections thing stands out. It seems that there are three kinds of
+collections defined in the code:
+
+- featured - seems to be pinned posts
+- devices - not sure what this is
+- tags - seems to be set to the featured tags on my profile on pony.social
+
+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](https://docs.joinmastodon.org/spec/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](https://pony.social/users/cadey.rss). 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!
diff --git a/data/toots/0b26c3f97f55b77b8f1c84e76b7b365493b881b382be8d3958326e1427cdc74e.json b/data/toots/0b26c3f97f55b77b8f1c84e76b7b365493b881b382be8d3958326e1427cdc74e.json
new file mode 100644
index 0000000..dbc8393
--- /dev/null
+++ b/data/toots/0b26c3f97f55b77b8f1c84e76b7b365493b881b382be8d3958326e1427cdc74e.json
@@ -0,0 +1,28 @@
+{
+ "id": "https://national-defence.network/objects/029da6d4-621f-40ea-8f69-8e78b3c5f11a",
+ "type": "Note",
+ "inReplyTo": "https://pony.social/users/cadey/statuses/109467644427625337",
+ "published": "2022-12-06T16:24:47.140952Z",
+ "url": null,
+ "attributedTo": "https://national-defence.network/users/CIA",
+ "to": [
+ "https://pony.social/users/cadey",
+ "https://www.w3.org/ns/activitystreams#Public"
+ ],
+ "cc": [
+ "https://national-defence.network/users/CIA/followers"
+ ],
+ "sensitive": null,
+ "conversation": "tag:pony.social,2022-12-06:objectId=6635593:objectType=Conversation",
+ "content": "Dear <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"APZpDBF8iT1DkYWNEW\" href=\"https://pony.social/@cadey\" rel=\"ugc\">@<span>cadey</span></a></span>,<br><br>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&#39;t even see you as a threat at all. Keep up the good work!<br><br>Best regards,<br>The CIA",
+ "contentMap": null,
+ "attachment": [],
+ "tag": [
+ {
+ "type": "Mention",
+ "href": "https://pony.social/users/cadey",
+ "name": "@cadey@pony.social"
+ }
+ ],
+ "replies": null
+}
diff --git a/data/users/a2dcb9e5c73ef2a138e47b70a3c0cdab119366656be0ed476d46ae3c14848b27.json b/data/users/a2dcb9e5c73ef2a138e47b70a3c0cdab119366656be0ed476d46ae3c14848b27.json
new file mode 100644
index 0000000..9e2c851
--- /dev/null
+++ b/data/users/a2dcb9e5c73ef2a138e47b70a3c0cdab119366656be0ed476d46ae3c14848b27.json
@@ -0,0 +1,28 @@
+{
+ "id": "https://national-defence.network/users/CIA",
+ "type": "Person",
+ "following": "https://national-defence.network/users/CIA/following",
+ "followers": "https://national-defence.network/users/CIA/followers",
+ "inbox": "https://national-defence.network/users/CIA/inbox",
+ "outbox": "https://national-defence.network/users/CIA/outbox",
+ "featured": "https://national-defence.network/users/CIA/collections/featured",
+ "featuredTags": null,
+ "preferredUsername": "CIA",
+ "name": "Central Intelligence Agency :verified: ",
+ "summary": "The CIA: because lying, cheating, and stealing is how we make America great again.<br/><br/>Overthrowing democratically elected Governments since 1947<br/><br/>",
+ "url": "https://national-defence.network/users/CIA",
+ "manuallyApprovesFollowers": false,
+ "discoverable": true,
+ "published": null,
+ "devices": null,
+ "icon": {
+ "type": "Image",
+ "mediaType": null,
+ "url": "https://national-defence.network/media/f6349000bb00273ed498676299b581e0c670521ad0636f44b2e6162bd9b106ee.blob"
+ },
+ "image": {
+ "type": "Image",
+ "mediaType": null,
+ "url": "https://national-defence.network/media/9c69767bca6ec0a2b141ff13c26f2974b61135c09dba310cec140b8522f2a559.png"
+ }
+} \ No newline at end of file
diff --git a/lib/xesite_types/src/mastodon.rs b/lib/xesite_types/src/mastodon.rs
index 80445bd..ac34574 100644
--- a/lib/xesite_types/src/mastodon.rs
+++ b/lib/xesite_types/src/mastodon.rs
@@ -119,9 +119,6 @@ pub struct Toot {
#[serde(rename = "replies")]
pub replies: Option<Replies>,
-
- #[serde(rename = "source")]
- pub source: Option<Source>,
}
impl Toot {