Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How I Obtained Satoshi's Treasure Keys 1, 2, and 3 in Minutes

Today (April 16th 2019 at noon) the first major clues to discover key #1 was set to be released in a few cities. A QR code with the words 'orbital' were found at these locations and looked like this: (https://imgur.com/a/6rNmz7T). If you read the QR code with your phone you will be directed to this url: https://satoshistreasure.xyz/k1

At this URL you are prompted to input a passphrase to decrypt the first shard. An obvious first guess was to try the word 'orbital' from the QR code. Not suprisingly this worked! This reveals a congratulations page and presents the first key shard:

ST-0001-a36e904f9431ff6b18079881a20af2b3403b86b4a6bace5f3a6a47e945b95cce937c415bedaad6c86bb86b59f0b1d137442537a8.

Now, we were supposed to wait until April 17th to get clues from the other cities for keys #2 and #3 but that wouldn't stop me from digging around with all the new information we had. All that time "playing" notpron (http://notpron.org/notpron/) years ago was going to help me here.

The first thing I noticed was the k1 in the url and quickly checked to see if k2, k3, and k4 existed. I was excited to see that both k2 and k3 already existed but k4 (and anything higher) did not appear to exist yet.

The next thing I noticed was that k2 and k3 were both exactly the same setup as k1 where it wanted me to input a passphrase to "decrypt the page". I thought this was strange wording as I expected the verification to happen server side. I checked the page source to find that the actual congrats page that reveals the shard was included in the source code (albeit encrypted by the passphrase).

The source code that runs when you submit a passphrase looks like this:

document.getElementById('staticrypt-form').addEventListener('submit', function(e) {
    e.preventDefault();

    var passphrase = document.getElementById('staticrypt-password').value,
        encryptedMsg = '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',
        encryptedHMAC = encryptedMsg.substring(0, 64),
        encryptedHTML = encryptedMsg.substring(64),
        decryptedHMAC = CryptoJS.HmacSHA256(encryptedHTML, CryptoJS.SHA256(passphrase).toString()).toString();

    if (decryptedHMAC !== encryptedHMAC) {
        alert('Bad passphrase!');
        return;
    }

    var plainHTML = CryptoJS.AES.decrypt(encryptedHTML, passphrase).toString(CryptoJS.enc.Utf8);

    document.write(plainHTML);
    document.close();
});

Let me break this down for you:

document.getElementById('staticrypt-form').addEventListener('submit', function(e) {});

This line is setting up the event listener for when the decryption form is submitted. This means when the form is submitted, whatever code is defined inside of function(e){} will run.

e.preventDefault();

This line isn't important but just prevents the browser from performing the default action when a form is submitted. If this wasn't included the page would likely refresh and not continue to run the code below.

var passphrase = document.getElementById('staticrypt-password').value;

This line reads the value you typed into the password box into a variable called passphrase. In our case this would hold the string "orbital" (assuming that is what you typed in).

encryptedMsg = '13ea059e2490f645da28f5f1529ca...'

I truncated this because it's a really long string but you can see the full string above. This is storing the fully encrypted passphrase and HTML of the congrats page.

encryptedHMAC = encryptedMsg.substring(0, 64);

This tells us that the first 64 characters of the encryptedMsg above represent the encrypted passphrase. This will be used to check if our passphrase is correct.

encryptedHTML = encryptedMsg.substring(64);

This tells us that the rest of the encrypted message is the actual HTML for the congrats page that contains the shard!

decryptedHMAC = CryptoJS.HmacSHA256(encryptedHTML, CryptoJS.SHA256(passphrase).toString()).toString();

Here we see that what I've been calling the "encrypted passphrase" is really the HMACSHA256 digest of the encrypted html using the sha256(passphrase). Essentially, if our passphrase is correct then the decryptedHMAC will equal the encryptedHMAC.

if (decryptedHMAC !== encryptedHMAC) {
  alert('Bad passphrase!');
  return;
}

Here we can see the check if the passphrase you provided was able to generate the encryptedHMAC. If the passphrase is not correct then the page will show you the error "Bad passphrase!"

var plainHTML = CryptoJS.AES.decrypt(encryptedHTML, passphrase).toString(CryptoJS.enc.Utf8);
document.write(plainHTML);
document.close();

If the passphrase is correct then it uses it to decrypt the encryptedHTML and then overwrites the page with the new HTML so you can see the congrats page!

After I saw this source code I realized because the check for whether or not the passphrase was correct was done locally I could brute force this using a dictionary attack. I also assumed the passphrases for k2 and k3 would be english words.

I quickly googled for a downloadable dictionary english word list and opened a new ruby script. A few minutes later I had this script:

require 'openssl'
require 'digest'

K1_encryptedHTML = "..."
K2_encryptedHTML = "..."
K3_encryptedHTML = "..."

K1_encryptedHMAC = "13ea059e2490f645da28f5f1529ca8095b1832ba95a0f3256b302ae58dca59af"
K2_encryptedHMAC = "2c5d8ae979d4dee1f33e7b3b11a8f57101e4c77e444d273dfc156f3f52a43934"
K3_encryptedHMAC = "e24b9cd8ba500e388252827e72f37b23e4c5eab209c36ce66bc3b71de45fdc4c"


File.foreach('words.txt') do | passphrase | 
  sha256Passphrase = Digest::SHA256.hexdigest(passphrase.strip.downcase)
  K1_decryptedHMAC = OpenSSL::HMAC.hexdigest('SHA256', sha256Passphrase, K1_encryptedHTML)
  K2_decryptedHMAC = OpenSSL::HMAC.hexdigest('SHA256', sha256Passphrase, K2_encryptedHTML)
  K3_decryptedHMAC = OpenSSL::HMAC.hexdigest('SHA256', sha256Passphrase, K3_encryptedHTML)
  
  if K1_decryptedHMAC.eql?(K1_encryptedHMAC)
    puts "Passphrase for K1 is #{passphrase}"
  end
  
  if K2_decryptedHMAC.eql?(K2_encryptedHMAC)
    puts "Passphrase for K2 is #{passphrase}"
  end
  
  if K3_decryptedHMAC.eql?(K3_encryptedHMAC)
    puts "Passphrase for K2 is #{passphrase}"
  end

end

Let me break it down section by section for you:

require 'openssl'
require 'digest'

Here we are just including ruby libraries that are useful working with crypto. They provide the ability to compute SHA256 and HMACSHA256 which we need for this problem.

K1_encryptedHTML = "..."
K2_encryptedHTML = "..."
K3_encryptedHTML = "..."

K1_encryptedHMAC = "13ea059e2490f645da28f5f1529ca8095b1832ba95a0f3256b302ae58dca59af"
K2_encryptedHMAC = "2c5d8ae979d4dee1f33e7b3b11a8f57101e4c77e444d273dfc156f3f52a43934"
K3_encryptedHMAC = "e24b9cd8ba500e388252827e72f37b23e4c5eab209c36ce66bc3b71de45fdc4c"

These are just storing the encrypted HTML and HMAC from each of the satoshistreasure.xyz decrypt pages source code.

File.foreach('words.txt') do | passphrase | 

This will loop over each word in my words.txt dictionary and assign each word to passphrase one at a time.

sha256Passphrase = Digest::SHA256.hexdigest(passphrase.strip.downcase)
K1_decryptedHMAC = OpenSSL::HMAC.hexdigest('SHA256', sha256Passphrase, K1_encryptedHTML)
K2_decryptedHMAC = OpenSSL::HMAC.hexdigest('SHA256', sha256Passphrase, K2_encryptedHTML)
K3_decryptedHMAC = OpenSSL::HMAC.hexdigest('SHA256', sha256Passphrase, K3_encryptedHTML)

This calculated the decrypted HMAC for all three puzzles from the current passphrase.

if K1_decryptedHMAC.eql?(K1_encryptedHMAC)
  puts "Passphrase for K1 is #{passphrase}"
end
  
if K2_decryptedHMAC.eql?(K2_encryptedHMAC)
  puts "Passphrase for K2 is #{passphrase}"
end
  
if K3_decryptedHMAC.eql?(K3_encryptedHMAC)
  puts "Passphrase for K3 is #{passphrase}"
end  

This did a quick check to see if the decrypted HMAC was equal to the encrypted HMAC. If this is true then we know the passphrase is the solution to the problem!

When I ran this scrypt in a few seconds it output:

Passphrase for K3 is blackhole
Passphrase for K2 is cosmos
Passphrase for K1 is orbital

I was shocked! That was easy :) . I checked each passphrase on the k2 and k3 decrypt pages to make sure they were correct. They were!

Hope this helps you understand how I was able to obtain three of the key shards in a few minutes. Please follow me on twitter @johncantrell97 for future #sastoshistreasure tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.