Sign in to follow this  
mundanename

HacknSlashAnnounce

Recommended Posts

OK, I have to revive this thread, because there are some mysteries yet to be solved related to this puzzle, and I just found an interesting lead.

Previously, Illessa discovered this base64-encoded string while investigating the memory map of the executable:

MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMeqDCPIoPMd8CSnjGI96lJG3ijSEMDFuJCG4yaWUgbzpHijnyhQtAWn8PXhWOeie0v56AcqjXtKuSeSeLalrZsCAwEAAQ==

I decided to dig a little deeper, so I first converted the data to hexadecimal:

30 5C 30 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05 00 03 4B 00 30 48 02 41 00 C7 AA 0C 23 C8 A0 F3 1D F0 24 A7 8C 62 3D EA 52 46 DE 28 D2 10 C0 C5 B8 90 86 E3 26 96 52 06 F3 A4 78 A3 9F 28 50 B4 05 A7 F0 F5 E1 58 E7 A2 7B 4B F9 E8 07 2A 8D 7B 4A B9 27 92 78 B6 A5 AD 9B 02 03 01 00 01

I decided to search if the first few bytes could give a clue as to what it was. Turns out, I found a correlation between the first 24 bytes of this sequence and the beginning of multiple RSA keys. For example, it can be found in this official Cisco documentation:

> An Introduction to IP Security (IPSec) Encryption

So I think it's safe to assume that this is a RSA key. But for what? And why is it there in the first place?

--

Also, nobody has figured out yet how the incantation and tweet are generated. Here are mine:

AND SPIRIT WHICH CAN BREAK THE BOUNDARIES OF UNDRESTANDING SUCH THAT I ALWAYS REALIZE THE POWERS I HAVE OVER HIDDEN BUT NOT INACCESSIBLE TRUTHS.

@Noughtceratops AxhEzVOUxfmceQbsoGSGbn8hqwPgalZhBpzdIchseZaNY/8979YoymMc0mzXsUBixIqy5MoriU4TVWw6sJNpog==

Again, the tweet is base64-encoded data, but I haven't been able to deduce anything from it by itself. If somebody could compile all the tweets generated so far, convert them all to hex data and compare them, we might be able to figure something out...

Share this post


Link to post
Share on other sites

I had to download my twitter archive to find this, but here's mine:

gQt3tQFh2Meh1a62fIUnGFnYjL2t7oAC897CX/LQAk+l2lFstLef5dWoNIzWhVMpadsnOb5q/vShuCFzgOjFLQ==

Which converts into hex as:

81 0B 77 B5 01 61 D8 C7 A1 D5 AE B6 7C 85 27 18 59 D8 8C BD AD EE 80 02 F3 DE C2 5F F2 D0 02 4F A5 DA 51 6C B4 B7 9F E5 D5 A8 34 8C D6 85 53 29 69 DB 27 39 BE 6A FE F4 A1 B8 21 73 80 E8 C5 2D

And I think I said before that the incantation that worked for me was: AND WITH THIS APPLICATION I DO DECLARE THAT BIRTHRIGHT HAS NO STANDING IN THE CHAMBERS OF WISDOM.

Share this post


Link to post
Share on other sites
Also, nobody has figured out yet how the incantation and tweet are generated. Here are mine:

AND SPIRIT WHICH CAN BREAK THE BOUNDARIES OF UNDRESTANDING SUCH THAT I ALWAYS REALIZE THE POWERS I HAVE OVER HIDDEN BUT NOT INACCESSIBLE TRUTHS.

@Noughtceratops AxhEzVOUxfmceQbsoGSGbn8hqwPgalZhBpzdIchseZaNY/8979YoymMc0mzXsUBixIqy5MoriU4TVWw6sJNpog==

Again, the tweet is base64-encoded data, but I haven't been able to deduce anything from it by itself. If somebody could compile all the tweets generated so far, convert them all to hex data and compare them, we might be able to figure something out...

My incantation is long gone & I'm not on a windows box to redo it - you can probably get a bunch of sample outputs by searching twitter for tweets @Noughtceratops and finding the ones with the "==" padding

Honestly I'm not sure how fruitful this will be. Brandon has said we've found everything and at the time I figured all the information you're going to get is contained in:

Opening the running exe using HxD i found this

http://pastebin.com/KUGyj3rq

- We know our incantations were made from chunks of that long string of them at the beginning of the output - as I recall the process grabbed some system info so odds are there's a bit of logic in the encrypted bit of the code that isn't easily debugged stitching them together from various aspects of your PC; MAC address, CPU ID etc. could confirm this by running it on two similar machines with the same MAC & seeing if you get similar outputs (or by seeing if your incantation changes after you change your MAC address).

- I discarded pursuing that base64 string after we realised what was going on - balance of probability it's the public key that was used to encrypt the tweet - not helpful for decrypting it (it's long enough and the correlation you found with other RSA keys would seem to back that up).

- Content of the tweet - we know from Brandon's responses to people that the encrypted tweet gave him some idea how we generated it, we also know it varied from person to person - looking at that in-memory section again we have:

"@Noughtceratops ....FROM/DEBUGGER...ntdll.dll...DbgUiRemoteBreakin"

Odds are these are the initial building blocks for the tweet; the final version would also have something unique so we all get different outputs - maybe our incantations in a compressed/index form, maybe a timestamp (can't recall if the tweet changed on multiple runs).

Share this post


Link to post
Share on other sites

Well, the puzzle might be solved, but not how it works, and that's the part that's been bugging me for a while now.

The theory that the RSA key is used to encrypt the tweet before encoding to base64 makes sense. So how about hacking the RSA key with a custom one for which we know the private key?

So I generated a custom key pair for which the public key had the same number of bytes than the real one. I found a match while generating 512-bit keys. Here is my custom key pair, again encoded in base64 (and split in multiple lines to not break the forums):

Private key:

MIIBOgIBAAJBAMGhu1i+8TVDy8VxO6EUCWlqnuOmwPUwl5YUWKE4

GCqmxUjYiZ+8Ojn2EAei6rfQC9OQjrUUWUzWGP3EUoGERx0CAwEAA

QJALFg+0K9CDIHPTBOHpXcyRJsvclGBRWXwgWV9esae+j07UgtSRL1

D0VBwhF+cEoyFsY1vfr5qMObA0El8osRkXQIhAOUdKQh0XYbqnDKuPv

jFv/ThV0WJOyZDYbd8VL01ZdNbAiEA2Fql5X6LiERG6vahqitcwRDWfoD

xy7zfR0WqPdg8sOcCIQDALeGJUfJRhOFYMYhoq5cEFTBbB20x/zsr6YI6

41tyGQIgJg2zlizuz9Xqf1NH1g1wcAjNIUz+um4K+5c2PVB2REsCIFU03

bae9bKiWSdQEcEQAsFvGAo/YGUCaC98nHFRBtOy

Public key:

MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMGhu1i+8TVDy8VxO6E

UCWlqnuOmwPUwl5YUWKE4GCqmxUjYiZ+8Ojn2EAei6rfQC9OQjrUUW

UzWGP3EUoGERx0CAwEAAQ==

I first thought of hacking the key directly in the EXE, but the data is compressed so that's hardly feasible. It's easily possible to do the next best thing and hack it in memory while the program is running. I used Process Hacker to do this job. And it actually worked.

First of all, I've been using a different computer, so I got a different incantation:

AND WITH THIS INCANTATION I FOREVER INTWINING OURSELVES TO OUR COMBINED DESTINIES WHICH PRODUCE A KIND OF INFINITE REWARD IN THE CONSTRUCTION OF MECHANISMS TO AID OUR DISCOVERY OF KNOWLEDGE AND TRUTH.

Then, I ran the hacked program a few times and collected the tweets. Every tweet was different, but after applying my private key on it I got consistent results. By consistent, I mean that I got 2 unique results, depending on whether I was running the process through OllyDbg or not.

Through OllyDbg: FROM/DEBUGGERO/DcajbDGml/Rgr2TEFVYKzUkgo=

Normal execution: SUCCESS/HASH/O/DcajbDGml/Rgr2TEFVYKzUkgo=

So it looks like the first 13 characters is the method used to crack the incantation, followed by a unique base64-encoded string for which I have yet to decipher its meaning.

Any ideas from there? It might help if others would try hacking the public key as well and post their results...

P.S.: I'm starting to wonder if Brandon eats base64-encoded cereals for breakfast...

Share this post


Link to post
Share on other sites

Heh, fair enough, just didn't want you to be disappointed if it didn't go anywhere new & exciting, but if you're just interested in the mechanics, that's cool :)

OK my theory that its just an index for constructing the incantation doesn't really pan out, my first instinct was to convert to decimal and compare against the word count of the full incantation text. But you got a very simple incantation (can be found in the text as only two chunks), and the string is both quite long and erratic enough to imply its not just giving a bunch of sequential indexes

base64="O/DcajbDGml/Rgr2TEFVYKzUkgo="

Decimal=59 240 220 106 54 195 26 105 127 70 10 246 76 65 85 96 172 212 146 10

Hex=3b f0 dc 6a 36 c3 1a 69 7f 46 0a f6 4c 41 55 60 ac d4 92 0a

Share this post


Link to post
Share on other sites

I went back to my first computer I used and did the custom RSA key patch trick again. This is the result:

SUCCESS/HASH/J+DteJIfgxx0m9Li6OheFvszgN4=

Also, I believe I figured out what is this new base64-encoded data: a SHA-1 hash. I base this on the fact that the decoded data is 20 bytes long, and considering the concatenated string literally contains the word "HASH".

But a hash of what? I haven't figured it out yet. I tried hashing my incantations, but they weren't matching.

By the way, so far the tweet construction is looking as such:

unknown data -> SHA-1 -> Base64 -> append to "FROM/DEBUGGER" if debugger detected or "SUCCESS/HASH/" otherwise -> RSA 512-bit -> Base64 -> append to "@Noughtceratops " -> copy to clipboard

Just... wow.

--

I also did a more throughout analysis of the contents of the EXE, and found more cool stuff.

First of all, I found an obvious string near the end of the EXE that other people missed, probably because they incorrectly decrypted the EXE from the video by not figuring out where the ENC file ended inside the MP4:

"One last puzzle brought to you by Double Fine Productions, and a very special Hack ‘n’ Slash character, Ida."

Super interesting tidbit, especially considering the main character's name has been revealed to be Alice, not Ida. We'll have to look forward to that character! Speaking of which, IDA* is a graph search algorithm. Hmmm...

Next, at the end of the huge blob of strings previously found with the incantation stuff, right after the string "YOUR INCANTATION: ", I found the strings "aes" and "rijndael". I didn't realize they were strings when I solved the puzzle months ago, but turns out that AES encryption is a Rijndael cipher. Probably just an easter egg, but it's pretty funny.

Also, the huge blob of strings contains the "FROM/DEBUGGER" string, but not the "SUCCESS/HASH/" string. It was located in a different location entirely. Interestingly enough, immediately before it are pages of zeros, but there's some data afterwards before more pages of zeros appear. Not sure if it's relevant for analysis since it contains some trivial stuff like the base64 alphabet (why am I not surprised), but it might be worth a look once we understand the program better.

Finally, speaking of the "FROM/DEBUGGER" string, I believe the strings "ntdll.dll" and "DbgUiRemoteBreakin" immediately afterwards are there because the EXE is testing ntdll!DbgUiRemoteBreakin to detect the debugger. I'm not familiar enough with debuggers and the Windows API to confirm this, but that's my guess.

...I really need to learn how to use debuggers.

Share this post


Link to post
Share on other sites

My current assumptions:

- The unidentified 20 bytes is a SHA-1 hash

- The hash is computed only once

- Whatever is hashed is something that has a high probability to be unique to each PC

- Whatever is hashed is used as the seed to generate the incantation

What I tried without success to determine what is used as a seed:

- Rainbow table attack

- Changing the location of the EXE

- Hashing my Windows product ID

- Hashing my computer's name

- Hashing my Windows username

- Hashing my network card's MAC address

- Hashing my HDD volume number

- Hashing my HDD serial number

- Hashing my CPU serial number

- Change capitalization or encode to Base64 before hashing

- Capture Windows events generated by the EXE through Process Monitor

I'm getting to the point where I might as well start going step-by-step through the program while deciphering the assembly code to understand what's going on, which I'm not looking forward to considering I'm not familiar with the x86 instructions set. I've been able to verify by myself that the incantation generation starts immediately after pressing Enter on "YOUR INCANTATION: ", but not the inner workings of the process.

Share this post


Link to post
Share on other sites

Used the entire day today getting used to debugging with OllyDbg and reading x86 assembler. Turns out that debugging a self-extracting program is a pain in the donkey, since OllyDbg can't figure out what's executable and what's not. But it was worth it.

--

First, I was able to decompile the debugger detection code into pseudocode. It's... doing things it really should not do.

Note that DebuggerDetected() is how I called the code that overwrites "SUCCESS/HASH/" with "FROM/DEBUGGER". It doesn't do anything else.

As for the pseudocode, behold:

var Debug = kernel32.GetProcAddress(kernel32.LoadLibraryA("ntdll.dll"), "DbgUiRemoteBreakin");

var DebugLength = 0x00;

do (

   DebugLength++;

} while (Debug[Length-1] != 0xCC); // 0xCC = INT3 instruction

var CustomDebug = new byte[0x1000];

memcpy(CustomDebug, Debug, DebugLength);

if (DebugLength > 0x00) {

   var a = 0x00;

   do {

       if (Debug[a] == 0xE8) { // 0xE8 = CALL instruction

           CustomDebug[a+0x01] = Debug[a+0x01]-CustomDebug+Debug; // really dirty patch

       }

       a++;

   } while (DebugLength > a);

}

Debug[0x00] = 0xB8; // MOV instruction

Debug[0x01] = DebuggerDetected;

Debug[0x05] = 0xD0FF; // CALL instruction

Debug[0x00] = 0xB8; // MOV instruction

Debug[0x08] = CustomDebug;

Debug[0x0C] = 0xD0FF; // CALL instruction

Debug[0x0E] = 0xC2; // RETN instruction

// by coincidence, Debug[0x0F] == 0x0000

if (kernel32.IsDebuggerPresent()) {

   DebuggerDetected();

}

Notice that ntdll.DbgUiRemoteBreakin is overwritten in the process. This is the resulting pseudocode:

DebuggerDetected();

CustomDebug();

return 0;

So basically, what this code does is:

- Copy the function ntdll.DbgUiRemoteBreakin in a new array of 4096 bytes

- Patch the copied function so that calls performed within the copy remain in the copy

- Patch the original function so that a call to DebuggerDetected() followed by a call to the patched copy is executed if a debugger attempts to attach to the process

- Call kernel32.IsDebuggerPresent() to check if a debugger was already attached to the process before the patch, and call DebuggerDetected() if applicable

What I find rather surprising with this method is how badly the patch is applied. And by that I mean that it doesn't work. The idea is neat, but it makes incorrect assumptions about the contents of the function and how memory is allocated. For example. it assumes that bytes 0xCC and 0xE8 are automatically INT3 and CALL instructions respectively. Turns out that on my Windows 7 64-bit PC, one instance of 0XE8 inside the function is actually a parameter, which completely corrupts the code. So if I try to attach OllyDbg after "YOUR INCANTATION: " has been printed, the process crashes. Oops.

--

Also, I finally found the unknown data while debugging! My assumptions were correct: it's a SHA-1 hash of the volume GUID path on which Windows is installed. For example, mine is:

\\?\Volume{62ca4546-c809-11df-990d-806e6f6e6963}\

To find out yours, simply run mountvol in cmd.

So to recap, here's how to generate the tweet manually:

- Get the volume GUID path on which Windows is installed

- Hash the path with SHA-1

- Encode the hash in Base64

- Append "SUCCESS/HASH/" or "FROM/DEBUGGER" immediately before the encoded hash

- Encrypt the result using the following RSA public key:

MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMeqDCPIoPMd8CSnjGI96lJG3ijSEMDF

uJCG4yaWUgbzpHijnyhQtAWn8PXhWOeie0v56AcqjXtKuSeSeLalrZsCAwEAAQ==

- Encode the encrypted data in Base64

- Append "@Noughtceratops " before the encoded data

So now we can all send fake tweets to Brandon! Well except me, since I don't have a Twitter account anymore. But that's besides the point.

--

One mystery left: how is the incantation generated? Stay tuned!

Share this post


Link to post
Share on other sites

That makes a lot of sense if it's meant to be a unique code for everyone. Nice work!

Share this post


Link to post
Share on other sites

Just noticed while looking back the thread that T3slider had already found the "Ida" message. Sorry about that.

In any case, I'm done!

First, the decompiled code. Note that I called Incantation the final result and Book the huge blob of text that was originally posted by MonoS up to " BY THE FEAR OF OTHERS."

var Hash = sha1(kernel32.GetVolumeNameForVolumeMountPointA(kernel32.GetVolumePathNameA(kernel32.GetWindowsDirectoryA())));

var HashLength = 20;

var IncantationLength = 4;

memcpy(Incantation, Book, IncantationLength);

Incantation[4] = '\0';

var SentenceEnd = Book+4;

for (var HashPos = 0; HashPos < HashLength; HashPos += 2) {

   var HashCopyLength = HashLength - HashPos;

   if (HashCopyLength >= 2) { // always true lol

       HashCopyLength = 2;

   }

   memcpy(Seed, Hash+HashPos, HashCopyLength);

   var RandomByte = 0x00;

   for (var c = 0; c < HashCopyLength; c++) { // RNG

       RandomByte ^= Seed[c];

   }

   var MatchingWordCount = 0;

   var Word = strstr(Book, Incantation+IncantationLength-4); // looking for last 4 letters of incomplete incantation inside Book

   if (Word) { // always true lol

       do { // counting number of matches

           if (Word < Book+1526) { // Book has a length of 1530 characters

               MatchingWordCount++;

           }

           Word = strstr(Word+4, Incantation+IncantationLength-4);

       } while (Word);

       if (MatchingWordCount == 0) {

           break; // uh-oh, this may cause a crash because the sentence has already ended

       }

       var RandomWordNumber = RandomByte % MatchingWordCount; // pick random match

       MatchingWordCount = 0;

       Word = strstr(Book, Incantation+IncantationLength-4);

       while (Word) { // start counting again until find the random pick

           if (MatchingWordCount == RandomWordNumber) {

               memcpy(Incantation+IncantationLength, Word+4, 4); // append the 4 characters after the random pick to the incantation

               IncantationLength += 4;

               Incantation[incantationLength] = '\0';

               SentenceEnd = Word + 8;

               break;

           }

           MatchingWordCount++;

           Word = strstr(Word+4, Incantation+IncantationLength-4);

       }

   }

}

while (Incantation[incantationLength-1] != '.') { // no more random stuff, copy what remains of the current sentence

   Incancation[incantationLength] = *SentenceEnd;

   IncantationLength++;

   SentenceEnd++;

}

Incantation[incantationLength] = '\0'; // end incantation

return IncantationLength;

So basically, here's how the incantation is generated:

1 - Get the SHA-1 hash of the volume GUID path of the Windows install directory

2 - Copy the first 4 characters of the block of text in the incantation

3 - Count all matches in the block of text for the last 4 characters of the incantation

4 - Pick one match at random using the following formula: (bitwise XOR of 2 bytes of the hash, starting from the left) modulo (number of matches) + 1

5 - Append the 4 characters following the random pick at the end of the incantation

6 - Repeat steps 3 to 5 until no match is found or until all bytes of the hash have been used

7 - Complete the rest of the incantation with what followed the rest of the last random pick up to a period

I have been able to verify the validity of this method using my own hash/incantation combination.

This is both simple and brilliant. I love it.

One more thing: As I noted in comments, I noticed the possibility of a crash if the last 4 characters picked overflows the end of the block of text. Not sure if that case is possible or not yet though.

In any case, I believe the EXE has revealed all of its secrets now. I guess the only worthwhile thing left to do now is to make a list of all possible incantations and their probabilities.

Share this post


Link to post
Share on other sites

OK, I verified and I don't think generating the incantation would cause a crash after all. I may be wrong, but it's unlikely. Worst case scenario, it's only going to copy 44 bytes past the end of the block of text, which is going to be ignored when comparing with the user input since the block of text is NULL-terminated.

So the only real cause of concern for crashes is the patch applied on ntdll.DbgUiRemoteBreakin, which I'm pretty sure is the cause of the weird stuff gateway2006 was experiencing. Speaking of which, I forgot to mention that the patching code is executed twice: once when starting the program, and another time when it terminates. Pretty sure this is another bug since there is no point in patching anything after the main code has ended.

As for the list of incantations, I started doing it manually, but there are a lot more combinations than I expected...

Share this post


Link to post
Share on other sites

I made an ugly program in C++ that generated all possible incantations, sorted them and counted duplicates. Not posting the source code because it's basically a hacked version of the pseudocode I posted before and it's extremely inefficient.

Results: There are 5694 unique possibilities out of 67361349 possible combinations. Assuming the RNG is working as intended, the most probable incantations have a probability of ~1.25%, while the least probable have a probability of ~0.00000148% . You can download the full list of incantations with their frequency here.

Some of my favorites:

- AND EMBOLDEN MY CAPABLE OF CHALLENGENDERSTANDING.

- AND EMBOLDEN MY CAPABLE THAT MUST INVARIABLY ENGENDER MAGNIFICENT AMPLIFICATION OF THE DESIRED OUTCOMES THAT WE PRODUCE.

- AND EMBOLDEN MY CAPACITY FOR DEMONSTRUCTION OF MECHANISMS TO AID OUR DISCOVERY OF KNOWLEDGE AND TRUTH.

- AND MAGIC IN OUR BIRTHRIGHT HAS NO STANDING.

- AND SPIRIT WHICH PRODUCES A RESULT THAT WE PRODUCE.

- AND SPIRIT WHICH PRODUCES A RESULT THAT WERE NEVER REALLY THERE DESPITE THE INSISTENCE OF THOSE PRESENTING THEMSELVES AS WIZARDS.

- AND SPIRIT WHICH PROTECT THAT WHICH CANNOT BE PROTECTED.

- AND TRUTH. AND WITH THE CHAMBERS OF OTHERS.

- AND TRUTH. AND WITH THE INFINITE IN THE FEAR OF OTHERS.

- AND TRUTH. AND WITH THE MAGIC IN OURSELVES AS WIZARDS.

- AND TRUTHS. AND TRUTHS. AND TRUTHS. AND TRUTH.

- AND TRUTHS. AND WITH THEE BOUNDARIES OF WISDOM.

- AND WITH THE BOND IN THE BOND IN THE BONDS THAT WERE NEVER REALLY THERE DESPITE THE INSISTENCE OF THOSE PRESENTING THEMSELVES AS WIZARDS.

- AND WITH THE INFINITE RESTRAINED BY THE BONDS THAT WERE NEVER REALLY THERE DESPITE THE INSISTENCE OF THOSE PRESENTING THEMSELVES AS WIZARDS.

- AND WITH THE LOCK CLASPED SIMPLY TO THE FEAR OF OTHERS.

- AND WITH THE MAGIC OF THE MIND AND SPIRIT WHICH STRENGTHEN AND EMBOLDEN MY CAPACITY FOR TAKING CONTROL OVER THAT WHICH WAS ALWAYS OUR BIRTHRIGHT THOUGH SOMESTIMES WE FOOL EVEN OURSELVES TO PROTECT THAT WHICH CANNOT BE PROTECTED.

- AND WITH THE MAGIC OF THIS APPLICATION OF MY POWER.

- AND WITH THE POWER. AND WITH THE FEAR OF OTHERS.

- AND WITH THIS APPLICATION I FOREVER OPEN THE LOCK CLASPED SIMPLY TO PROVIDE OPPORTUNITY FOR DEMONSTRATION OF MY POWER.

- AND WITH THIS APPLICATION I REVER OPEN THE BOUNDARIES OF UNDRESTANDING SUCH THAT I ALWAYS REALIZE THE POWERS I HAVE OVER HIDDEN BUT NOT INACCESSIBLE TRUTHS.

- AND WITH THIS APPLICATION OF THE FINITE OF UNDERSTANDING.

- AND WITH THIS APPLICATION OF THE INFINITE IN THE INFINITE THAT HAS PRODUCED MUCH WONDER AND MAGIC IN OUR WORLD AND COMMIT TO THE PURSUITE OF UNDERSTANDING.

...

I know Kung-Fu.

Share this post


Link to post
Share on other sites

I find it kinda weird that your code looks so different from mine. I tried to be as close to the original program as possible. Did you do the same?

On a different note, I noticed a comment from Brandon on the website that mentions IDA Pro being his favorite debugger. The name of the character was a clue all along. Kind of weird that I didn't find anything about that when I originally searched for that name.

Oh, and since it looks like the teaser website is gone for good, I've uploaded the puzzle for those late to the party.

Share this post


Link to post
Share on other sites

It's not so strange, my first pass was porting the code to C using both IDA disasembly and the hex-rays decompiler.

Then I ported it to C# with unsafe calls and tried to understand the algorithm and remove all unsafe calls and replace them with standard C# (String types, byte array extraction using LINQ methods, regex for substring position search).

The gist I posted is something like my 4th iteration that I did around it...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this