TheMonera art puzzle write-up
Welcome to the write-up for TheMonera art puzzle, published here: https://www.themonera.art/2019/02/13/monero-puzzle/ . This artwork/puzzle was originally released during DEFCON 2018 and contained a way to access a Monero wallet with an undisclosed amount. The artwork and puzzle hidden inside were a joint project by themonera and midipoet. The original painting was done by Giovanni Paolo Pannini in 1757 (you can see the date in the lower left corner) but the artwork above contains more than 50 (no idea on the exact number) changed areas, full of Monero, film and social media references. The image appears at first sight as very daunting, from a puzzle solving perspective, but in reality contains very few regions of interest in that regard. So let’s get started.
There are a lot of things in the image that may or may not be useful as clues, and I will not go into detail for too many of them because I honestly wouldn’t know where to start. The reality is that there’s only 6–7 distinct areas useful for solving the puzzle, with 4-5 of them required for solving the first step (from what I can tell).
The first important piece is this board of 10 atomic elements, which have text encoded below the symbols for the elements. Since we can see there’s a lot of numbers, uppercase and lowercase letters, as well as the + and = symbols, it’s fairly straightforward to identify this as base64 encoding. Now, the puzzle here is finding the order for the base64 chunks, but it’s not a very hard one: Opening up the Periodic Table of Elements and looking for the atomic elements in the table above, we can immediately see that the 10 elements are grouped together, with no extra elements between them. So that means, the order of the chunks is given by the order of the elements in the Periodic Table! Doing that we get:
Cl — Ar — K — Ca — Sc — Ti — V — Cr — Mn — Fe ( elements 17 to 26 )
Okay, now the natural thing would be to try and decode that in any online base64 decoder, but unfortunately the result will be just random bytes. That’s because the message above is actually the encrypted text for some secret, which we have to decrypt using a passphrase and knowing the cipher used for the encryption.
In order to figure out the cipher, one needs to know at least the general categories of ciphers that exist and are in use. In order to help the solver, there are two distinct references that hint at the same thing: the Twofish cipher. There’s not much more to say about this part, since seeing both references should be enough of a confirmation that what you have is correct.
The next artwork of interest, and probably the one that first catches your eye, is the barcode with the little robot and a note with binary on it. Well, using a barcode scanner gives p864xRDJ but if you’re internet savvy you will know that the little note with the binary on it is the logo of the website https://pastebin.com/ . So then, linking those together and visiting https://pastebin.com/p864xRDJ , we find:
If you can bear to hear the truth you’ve spoken
Twisted by knaves to make a trap for fools,
Or watch the things you gave your life to, broken,
And stoop and build ’em up with worn-out tools:
A nice little verse which can be googled, revealing that the author is Rudyard Kipling, and the poem is called If. While definitely a nice piece of literature, the presence of this verse doesn’t seem to bring us any additional info useful in our puzzle. So let’s move on.
Another thing that should definitely jump into our eye is the morse code right below the Invisible Man poster. Decoding it is straightforward with any online tool and simply yields POSITION THREE. Interestingly, the exact same morse is also present in the lower right corner painting where Fluffypony was added (and is missing a leg!). Only here, the morse code is very well hidden, can you see it in the image above? It’s right at the top, but using a brownish color, very close to the color pallete of the painting behind it. Anyway, the morse code isn’t used for the first step.
This is the last piece that is required for the solving of this puzzle, and it is also perhaps the most misleading and hard to interpret. Of course, Vigenere is a very famous and used cipher in many ARGs/puzzles, so the inclusion here wouldn’t be very suspicious. We could assume that there will be a ciphertext at a later stage and we need to use Vigenere cipher to decode it. Well, that’s not the case here :D
All the information I’ve presented so far was well known since (probably) day 1 of the puzzle, but there was no progress past this point. The main reason for this is definitely the fact that deriving a passphrase out of the entire image seems impossible.
Obtaining the passphrase
I’ve had several attempts at solving this puzzle, with months between them, during which time I’ve tried to gather every single small piece of information/hint released by midipoet after the puzzle was published. Without his reddit threads, I am absolutely sure I would never have gotten it. The two threads are:
and more importantly:
In the 2nd link, midipoet gives a few cryptic hints in an artistic fashion, mentioning, among other things, twofish (thus confirming it again), and more importantly
Remember the clues, find the order, and come calling when the modes are set in front.
Follow the path, remember the brackets, and remember we are all but true.
Now, what puzzled me for the longest time is this “path” which we had to follow. I believed (like many) that we need to tie the Kipling poem into the artwork, somehow deriving the passphrase. What I should’ve paid more attention to was the next bit, “remember the brackets”, because that’s exactly where the trigger for discovering the key is.
If you remember that BLAISE DE VIGERENE 1523–1596 reference, and you also look at the text above which ends with midipoet(2014-****) , while trying to “remember the brackets”, you’re looking at the key to the key, so to speak. Because, well, they forgot the brackets. So you better remember them. But why were brackets important anyway? Well, because they’re needed in the actual key.
Going back to the poem with the knowledge that the “path starts at it” (taken from one of the reddit posts), I now assumed that the actual passphrase to the cipher was something of the type “Rudyard Kipling(1865–1936)”. So, I first compiled a list with variations on this, where everything is joined, where everything is uppercase, lowercase, etc (and others where we also include Kipling’s other name, Joseph), and I tried out various websites. None worked, but, to my surprise, the results they were giving were different between each other. So then I found a few different implementations, 2 in c# and one in python, and tried them out, and one was also giving different results compared to the other two.
So then, I figured, this is all a bit confusing, because the only place where these implementations were different was in the way they derived the key from the passphrase provided. Note that “Rudyard Kipling(1865–1936)” is referred to as a passphrase, while the “key” is a data structure, either 128 ,192 or 256 bits (for twofish) which gets derived from a passphrase (the passphrase can be any arbitrary length text). Since we had no information on the key size needed nor the key derivation used, I eventually gave up on trying my own implementations and turned back to looking at websites, with no luck.
Frustrated, I wrote to midipoet to make sure that the decoding is still functioning properly and that I had not missed something. He replied, after testing himself, that the website seems to be out of service. He also provided me with the name of the website ( https://codebeautify.org/encrypt-decrypt ) in hopes that I may contact the staff to remedy the problem. I did so, but they took another 3 days to get the “encrypt/decrypt” page back up and running (during which time I solved another puzzle for a Monero-based coin, https://medium.com/@elronvhubbard/loki-and-freya-a-christmas-story-c7aeca212ce6 ).
Finally, one morning I woke up and tried the website and to my surprise, it was fixed! Rushing to my PC, I started trying out the passphrases that I had with all the modes that the website lets you use. Not long after, I finally got a correct decoding. All the data needed to reach the “first step” is summarised below:
Nice! You can check that the output of the above gives the plaintext:
Obviously, with the e-mail address being the only thing decoded, we’re supposed to send an e-mail to it. So, I did. And I got an automated reply:
I’m out of the office and will not be checking my mailbox.
You can access it with this:
Well, at first sight, those look like RGB colors in hex encoding. But if it were the case, it would be a really tiny amount of data and not really useful. So instead, we can turn back to the e-mail address itself, and note the name (many people might have already recognized it already, but I didn’t until a google search). A simple google search turns up the fact that it’s an epic poem written by John Milton, with the 2nd edition published in 1674.
So then, we have the name of a book, and we have 4 sets of 3 numbers. Connecting the dots wasn’t too hard here, this is probably a book cipher, with the 3 numbers being # page, line, word. Or something similar. The 4 sets of numbers are below in a nicer formatting:
#030f03 = rgb( 3, 15, 3)
#081505 = rgb( 8, 21, 5)
#0d0702 = rgb(13, 7, 2)
#0e2107 = rgb(14, 33, 7)
Now the book that we want to apply the pairs above is actually the first book (of 12), which should also be one of the first results on google when we search for the book name + year. Here’s one possible link:
We can see, however, that there are no pages, but instead we have paragraphs (stanzas). In that case, the first of the 3 numbers will be the stanza number, the 2nd will still be row number, and the 3rd will be word number. Applying the 4 sets of numbers above to the text gives:
#030f03 rgb( 3, 15, 3) -> paragraph 3 row 15 word 3: disdain
#081505 rgb( 8, 21, 5) -> paragraph 8 row 21 word 5: ambition
#0d0702 rgb(13, 7, 2) -> paragraph 13 row 7 word 2: defiance
#0e2107 rgb(14, 33, 7) -> paragraph 14 row 33 word 7: multitude
Putting the words together we get disdainambitiondefiancemultitude which unlocks the mail address! Hurrah! Well, it did unlock it, honestly! But of course, as soon as I got access to it, I changed the password and transferred ownership to myself.
After claiming the e-mail address for myself, I browsed around for the next step of the puzzle, which turned out to be in the form of an unsent draft mail, included below:
Well, seems like we’re almost done. There’s still the morse.wav file, that you can find here (hopefully, first time I use vocaroo):
It’s a simple audio file with just “TSUNAMI” encoded in morse.
Now, note that the seed provided in the draft is actually 24 words long, and no word repeats twice. Normally, a monero seed should be 25 words long, with the 25th word being a repeat of one of the other 24 words (the 25th acts as a checksum). Importing this seed is possible (the monero client automatically calculates the checksum word for you if you don’t include it) but the wallet will be empty.
Instead, at this point we have to go all the way back to the artwork and remember we had a morse code in there that said “POSITION THREE”. So basically, we need to add the word TSUNAMI to the 3rd position in the seed. Boom! Restoring the seed finally shows the 1 XMR that was sent to the wallet. In case you want to load the seed yourself and check, you can restore from height 1604700, and the full seed is
python knowledge tsunami ionic react drowning tanks eating biggest brunt ungainly lukewarm misery wrap adventure motherly malady glide alchemy biscuit peaches toyed boss cinema tsunami
Thank you very much midipoet and themonera for creating this amazing artwork and including a cryptopuzzle inside of it. I also took part (remotely) in the Monero CTF from Defcon this year, where midipoet had a hand in some fun challenges, so I definitely hope to see (and attempt to solve) more of his work in the future!
For some great and active puzzle-filled communities, check out:
ARG Solving Station: https://discord.gg/uYAXsww
Neon District: https://discord.gg/RB7pKHz