Dumpster Diving through Namecoin and Emercoin
I was at Defcon 27 recently and saw a talk titled “Secrets Worlds in Plain Web. The BlockChain DNS.” by Fernando Amatte. He spoke about blockchain based DNS infrastructure, specifically Namecoin and Emercoin, as a means of hiding secrets in plain view. I missed the beginning of the talk, but I don’t recall him presenting any specific examples of people using blockchain DNS services. This gave me a few questions:
- Is anyone using these blockchain DNS services?
- What are they using them for?
- Are any interesting services “hiding in plain site?”
At first glance these questions should be easy to answer. If the DNS records are written to a blockchain I should be able to trivially download and search the blockchain(s), enumerate all the domains, and see what’s out there. So that’s what I set out to do.
Blockchain-DNS.info
My first stop was the website https://blockchain-dns.info/ to see what it takes for a layperson to access these sites. I downloaded the firefox plugin and visited their explore page just to see what was out there. As it turns out, a lot of resolution errors, parked domains, and porn. Off to a great start. Let’s get a bit more scientific with it.
Enumerating Namecoin
Clicking around the blockchain-DNS explore page was fun, but I wanted to more exhaustively see what was out there. Namecoin sounded familiar so I started with that.
First, download and install Namecoin from github. If you’re ever installed Bitcoin, it’s pretty much the exact same process. If you install the QT GUI version you will have to add the server option to your namecoin.conf. Here is what mine looks like:
datadir=/path/to/my/extra/ssd/namecoin/data
rpcallowip=127.0.0.1/32
rpcuser=[username]
rpcpassword=[password]
server=1
Once the Namecoin chain is running and synced I needed a way to dump all the records it contained. Thankfully Namecoin provides a utility just for this called ncdumpzone. Install instructions are on the ncdns github page.
During install I ran into the following error:
package golang_org/x/crypto/cryptobyte: unrecognized import path
I have no idea what caused this, but you can fix it by editing the following file
in the x509-signature-splice dependency: ~/go/src/github.com/namecoin/x509-signature-splice/x509/x509_splice.go
,
changing golang_org
to golang.org
and re-installing.
Now I can run ncdumpzone from my ~/go/bin/ folder and get results in the following format:
zielmicha.bit. 600 IN NS 87.98.234.72.zielmicha.bit.
zimperium.bit. 600 IN A 127.0.0.1
zionsbank.bit. 600 IN A 144.76.12.6
*.zionsbank.bit. 600 IN A 144.76.12.6
zonealarm.bit. 600 IN NS ns1.cloud-name.ru.zonealarm.bit.
zonealarm.bit. 600 IN NS ns2.cloud-name.ru.zonealarm.bit.
i.bit. 600 IN A 45.63.38.124
v.bit. 600 IN A 45.63.38.124
x.bit. 600 IN A 45.63.38.124
Awesome! I let the command run for a bit, dumping it to a text file, to see what happened. The command kept running for hours without end, and giving a lot of looping and duplicate results. I briefly checked the source code and it looks like it’s supposed to stop at some point? I didn’t spend a lot of time trying to figure out why it kept going so I came up with a lazy solution. I would take the records from ncdumpzone, hash them, ignore hashes I’d already seen, and store anything new.
Here is the quick and dirty python script I came up with:
#!/usr/bin/env python3
import sys
import sqlite3
import hashlib
conn = sqlite3.connect("domains.db")
c = conn.cursor()
c.execute("""CREATE TABLE IF NOT EXISTS records (
id integer PRIMARY KEY,
hash text NOT NULL,
domain text NOT NULL,
type text NOT NULL,
record text NOT NULL);""")
try: # try-except in case we want to quit early with ctrl+c
for line in sys.stdin:
p_line = line.strip()
p_hash = hashlib.sha256(line.encode()).hexdigest()
p_line = line.split("\t")
# Check if the hash already exists
c.execute("SELECT count(*) FROM records WHERE hash=?", (p_hash,))
count = c.fetchone()[0]
# If it's new, add it to the database
if count == 0:
print(f"Inserting: {p_line[0]}, {p_line[3]}, {p_line[4]}")
c.execute("INSERT INTO records (hash, domain, type, record) VALUES (?, ?, ?, ?)",
(p_hash, p_line[0], p_line[3], p_line[4]))
conn.commit()
else:
print("Skipping.")
except KeyboardInterrupt:
print("Exiting...")
conn.commit()
conn.close()
sys.exit(1)
conn.commit()
conn.close()
Then I ran ./ncdumpzone | ./dump_namecoin.py
and let it sit for a while.
After a short while I started seeing only “Skipping.” lines with no new
entries, so I ran watch ls -latr domains.db
and left the terminal for
a few days so I could quickly see if the database had been updated. After
a few days with no updates I killed the script and called it “good enough
for now.” I had a database with (probably) most of the DNS records in Namecoin.
Enumerating Emercoin
Emercoin took a bit more thought than Namecoin. Emercoin stores DNS records
in its Name-Value Storage (NVS) service.
By default it supports a number of service abbreviations that you can prepend
to names to indicate what the name and value should be used for. So, sort of a
tag:name->value storage system. The abbreviation for DNS is “dns:” so a DNS record Name
would look like dns:emercoin.com
. The Value is just DNS records delimited by
the pipe character, like A=192.168.0.123|TXT=example website
.
To enumerate all DNS records then, we can enumerate the NVS service, get all
the names that start with dns:
, and look at their values. Thankfully, the
emercoin-cli has a method called name_scan
that does exactly that.
The Emercoin node installed without any issues. Again, it was just like installing Bitcoin (it’s Bitcoin forks all the way down).
TL;DR, here is my emercoin.conf:
rpcallowip=127.0.0.1/32
rpcuser=[username]
rpcpassword=[password]
server=1
emcdns=1
And here is the script I used to dump the NVS service to a sqlite database:
#!/usr/bin/env python3
import sqlite3
import json
import sys
from subprocess import check_output
# Create the database
conn = sqlite3.connect("emercoin_nvs.db")
c = conn.cursor()
c.execute("""CREATE TABLE IF NOT EXISTS nvs_records (
id integer PRIMARY KEY,
name text NOT NULL,
value text NOT NULL,
expires_in integer NOT NULL,
expired integer NOT NULL);""")
# Get the first 500 NVS pairs
out = check_output(["/path/to/emercoin-cli",
"-rpcuser=[username]",
"-rpcpassword=[password]",
"name_scan"])
# decode with replace to preserve all that binary
out = json.loads(out.decode("utf-8", "replace"))
try: # try-except in case we want to quit early with ctrl+c
while len(out) > 0:
for nvp in out:
if "expired" not in nvp.keys() and nvp["expires_in"] > 0:
# If the record hasn't expired, set expired to 0 (False)
nvp["expired"] = 0
else:
# Otherwise set expired to 1 (True)
nvp["expired"] = 1
print(f"Inserting {nvp['name']}")
c.execute("""INSERT INTO nvs_records (name, value, expires_in, expired)
VALUES (?, ?, ?, ?)""",
(nvp["name"], nvp["value"], nvp["expires_in"], nvp["expired"]))
conn.commit()
# Get the next 500 records
out = check_output(["/path/to/emercoin-cli",
"-rpcuser=[username]",
"-rpcpassword=[password]",
"name_scan",
out[-1]["name"], "501"])
out = json.loads(out.decode("utf-8", "replace"))
# First record will be the one we searched for, which is the last
# Name-Value pair saved from the previous batch, so get rid of it
out.pop(0)
except KeyboardInterrupt:
print("Exiting...")
conn.commit()
conn.close()
sys.exit(1)
conn.commit()
conn.close()
This on actually terminates properly. After a few minutes I had the entire Name-Value
Storage enumerated in emercoin_nvs.db
.
Is anybody there?
So I have these records, now what? I need some way of checking all these sites to see what’s on them. There are lots of tools for scraping websites and taking screenshots. I considered sketchy but it seemed like overkill for what I wanted to do. I settled on EyeWitness because it attempts to classify the sites it scrapes, which is exactly what I wanted to do.
Instead of mucking about with DNS settings I spun up a fresh Kali VM, installed
EyeWitness, and added all the valid A records I had to the /etc/hosts file.
I don’t have a script here, I just opened up the databases in a DB browser,
copy pasted them into vim, and ran some commands until they were formatted properly.
Then I pasted them into /etc/hosts, made a new file called domains.txt, removed
the IPs from domains.txt, fired off ./EyeWitness.py --web -f domains.txt
, and
waited. And waited. And… waited… As it turns out, a lot of these sites
have nothing going on. About half timed out.
In total I had 4463 domains with A records. This matches the Blockchain-DNS explore page, which claims that of the 140,472 domains it serves 5,016 have IP addresses. I’ll assume the 553 I’m missing are from OpenNIC and not blockchain.
Results
Here are the categorization results from EyeWitness:
Category | Count |
---|---|
Uncategorized | 1624 |
Directory Listings | 9 |
Content Management System (CMS) | 1 |
Network Devices | 1 |
401/403 Unauthorized | 139 |
404 Not Found | 60 |
Splash Pages | 14 |
Internal Error | 5 |
Bad Request | 48 |
Errors | 2560 |
Okay, so I misspoke earlier. More than half aren’t actually hosting anything.
I spent a lot of time looking through the results and most of them are really boring. A lot of empty CMS and “blog coming soon” type pages. The directory listings are all pretty much the same site, and only host a single image. I’ll include some of the screenshots so you don’t have to bother installing the plugins and visiting them yourself.
Namecoin
Someone registered a few domains on Namecoin to create an uncensored host for the Bible on biblical themed domains (such as bible4u.bit):
Blockchain-DNS.info had several alternative Namecoin domains registered. There are some blogs and personal sites of blockchain enthusiast types. A few blockchain projects had alternative domains. One router login page, one router traffic graph. A wedding invitation. Some wikileaks mirrors. Not a whole lot “hiding in plain site” as it were. One of the running themes is the repetition of domains. When there is an active site, it is rarely registered once. The bible site had at least 4 or 5 names. There were half a dozen sites dedicated to the 12 networking truths. It was pretty easy to tell when looking at the list which sites would be identical, they would have similar names, the same A record, and similar TXT records.
In the category of crime sites I did come across a few. Joker’s Stash for one, although it’s not clear if this is the real site or a phishing page:
There were a number of free movie and TV sites, mostly in some Cyrillic script. Some nextcloud login pages, and a lot of 404s.
Emercoin
Emercoin was about as interesting as Namecoin. There were no exposed router logins or anything like that, but there were a few more crime sites and one very dedicated Chaturbate white label.
The overwhelming majority of emercoin domains were parked. Again, there was a plethora of 404s, domains that go nowhere, and blockchain projects.
In the crime sites categories we have many more alternative domains for Joker’s Stash as well as a few carding sites. Here’s one called unicc:
And another called Antigreedy:
The following is by far my favorite discovery. Someone invested in creating a white label Chaturbate affiliate and really really wants blockchain enthusiasts as their customer base. There were 996 domains dedicated to this singular Chaturbate white label site:
When I came across this I was a bit perplexed. Why is there a cam site that seems exclusively available on blockchain based DNS? How does it have this many performers? Surely this must be some kind of e-whore or catfishing setup. Alas, no, as it turns out Chaturbate makes it very easy to create and market your own white label version of the site (NSFW), with the same community/backend, and a revenue share based on traffic you drive. So I guess registering as a white label and throwing up 996 domains on emercoin was cheap enough that the traffic gained from curious blockchain enthusiasts was profitable? I guess?
TL;DR
- Is anyone using these blockchain DNS services?
Maybe a few dozen people.
- What are they using them for?
Mostly domain parking, empty projects, and a smattering of crime.
- Are any interesting services “hiding in plain site?”
Not really.
If you really wanted to create hidden services that were difficult for others to find or contained content that is illegal there are much better tools to do so. For the most part these blockchain domains look like the kind of thing you’d find on the regular internet, with a bias towards sites that would be made by the kind of people that use blockchain DNS.
TODO
- Look at other Emercoin NVS attributes
- Look at other record types besides A records
- I’d love to see traffic stats on that white label from blockchain DNS