Friday, July 04, 2014

Jamming XKeyScore

Back in the day there was talk about "jamming echelon" by adding keywords to email that the echelon system was supposedly looking for. We can do the same thing for XKeyScore: jam the system with more information than it can handle. (I enumerate the bugs I find in the code as "xks-00xx").


For example, when sending emails, just send from the address "bridges@torproject.org" and in the email body include:

https://bridges.torproject.org/
bridge = 0.0.0.1:443
bridge = 0.0.0.2:443
bridge = 0.0.0.3:443
...

Continue this for megabytes worth of bridges (xks-0001), and it'll totally mess up XKeyScore. It has no defense against getting flooded with information like this, as far as I can see.


Note that the regex only cares about 1 to 3 digit numbers, that means the following will be accepted by the system (xks-0002):

bridge = 75.748.86.91:80

The port number matches on 2 to 4 digits ([0-9]{2,4}). Therefore, bridges with port numbers below 10 and above 9999 will be safe. I don't know if this code reflect a limitation in Tor, or but assuming high/low ports are possible, this can be used to evade detection (xks-0011).

Strangely, when the port number is parsed, it'll capture the first non-digit character after the port number (xks-0012). This is normally whitespace, but we could generate an email with 256 entries, trying every possible character. A character like < or ' might cause various problems in rendering on an HTML page or generating SQL queries.


You can also jam the system with too many Onion addresses (xks-0003), but there are additional ways to screw with those. When looking for Onion addresses, the code uses a regex that contains the following capture clause:

([a-z]+):\/\/)

This is looking for a string like "http://" or "https://", but the regex has no upper bounds (xks-0004) and there is no validation. Thus, you can include "goscrewyourself://o987asgia7gsdfoi.onion:443/" in network traffic, and it'll happily insert this into the database. But remember that "no upper bounds" means just that: the prefix can be kilobytes long, megabytes long, or even gigabytes long. You can open a TCP connection to a system you feel the NSA is monitoring, send 5 gigabytes of lower-case letters, followed by the rest of the Onion address, and see what happens. I mean, there is some practical upper bound somewhere in the system,, and when you hit it, there's a good chance bad things will happen.

Likewise, the port number for Onion address is captured by the regex (d+), meaning any number of digits (xks-0005). Thus, we could get numbers that overflow 16-bits, 32-bits, 64-bits, or 982745987-bits. Very long strings of digits (megabytes) at this point might cause bad things to happen within the system.

There is an extra-special thing that happens when the schema part of the Onion address is exactly 16-bytes long (xks-0006). This will cause the address and the scheme to reverse themselves when inserted into the database. Thus, we can insert digits into the scheme field. This might foul up later code that assumes schemes only contain letters, because only letters match in the regex.


In some protocol fields, the regexes appear to be partial matches. The system appears to match on HTTP servers with "mixminion" anywhere in the name. Thus, we start causing lots of traffic to go to our domains, such as "mixminion.robertgraham.com", that will cause their servers to fill up with long term storage of sessions they don't care about (xks-0007)


Let's talk X.509, and the following code:

fingerprint('anonymizer/tor/bridge/tls') =
  ssl_x509_subject('bridges.torproject.org') or
  ssl_dns_name('bridges.torproject.org');

Code that parses X.509 certificates is known to be flaky as all get out. The simplest thing to do is find a data center you feel the NSA can monitor, and then setup a hostile server that can do generic fuzzing of X.509 certificates, trying to crash them.

It's likely that whatever code is parsing X.509 certificates is not validating them. Thus, anybody can put certificates on their servers claiming to be 'bridges.torproject.org' (xks-0008). It's likely that the NSA is parsing SSL on all ports, so just pick a random port on your server not being used for anything else, create a self-signed CERT claiming to be "bridges.torproject.org', then create incoming links to that port from other places so at least search-engines will follow that link and generate traffic. This will cause the NSA database of bridges to fill up with bad information -- assuming it's not already full from people screwing with the emails as noted above :).


<img src="http://www.google.com/?q=tails+usb" />

Putting the above code in a web page like this one will cause every visitor to trigger a search for TAILS in the XKeyScore rules. The more people who do this, the less useful it becomes to the NSA (xks-0009) in labeling people as suspicious. Likewise, putting <title>tails.boum.org/<.title> in your webpages will cause the same effect, even when CSS/JavaScript makes such a title invisible.


In theory, the NSA should only be monitoring foreign traffic, and not traffic originating from the United States (or, apparently, the other five-eyes). So here is the fun thing (xks-0010): run your jamming tools from United States IP addresses against those servers in Iran you know the NSA is monitoring. Since the code should already be ignoring the traffic because it originates from the United States, then they can't complain if you've filled up their databases full of Tor Onion and bridge addresses.








7 comments:

  1. Do you mean mails which look like this?

    import numpy.random

    bridges = []
    for i in numpy.random.randint(0, 256, 20):
    for j in numpy.random.randint(0, 256, 20):
    for k in numpy.random.randint(0, 256, 20):
    for l in numpy.random.randint(0, 256, 20):
    for p in numpy.random.randint(20,1000, 20):
    bridges.append("bridge = {}.{}.{}.{}:{}\n".format(i,j,k,l,p))

    header = "https://bridges.torproject.org/\n"

    with open("bridges.txt", "w") as f:
    f.writelines([header] + bridges)

    (add cumulative whitespace after each colon, execute with python)

    ReplyDelete
  2. I archived your post at http://127.0.0.1:8888/freenet:USK@3byFQBKaPi-DSdQ6-fHDUEbBjg06coQveZwdHJGD7s8,rQKQseO8PcXwX-mO8XOg4FAwAoQ10hTWLkwTFewVRtQ,AQACAAE/jamming-xkeyscore/0/ (you need freenet running for this to work).

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. "bridge = 0.0.0.1:443"

    Is the "=" correct? In the regex there is a "\s" (whitespace?) but I'm not an expert in C...

    ReplyDelete
  5. http://who.is/tools/traceroute/128.31.0.34/ (Is an IP hosted@MIT; runs via Backbone at Hops 13)

    "moria.csail.mit.edu (128.31.0.34) 13.219 ms !X 12.940 ms !X 13.019 ms !X" (traceroute Hops 17)

    The IP 128.31.0.34 (found on the end of the script) is an Server from the MIT.

    SEE:
    // START_DEFINITION
    appid('anonymizer/mailer/mixminion', 3.0, viewer=$ascii_viewer) =
    http_host('mixminion') or
    ip('128.31.0.34');
    /

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete