Spooky, Scary, Skullcode Mystery

The world wide web is a wonderful place. If you know how to look for them, it is full of mysterious pages devoid of any explanation leaving the visitor without any clue of their use or meaning. Skullcode is an excellent example of that.

After stumbling upon this enigmatic web-page I was immediately intrigued by the possible secrets it could hold. It’s not rare for this kind of cryptic websites to be the starting points for “capture the flag”-like treasure hunts. While this might end up being a wild goose chase started by what could just be a neat tech demo, I still wanted to take the time to investigate further to answer the question: “What is Skullcode?”.

Title card

Looking at Skullcode in action

From the moment you open up the skullcode webpage you’re presented with something that looks a lot like an hex editor.

The cursor is initially placed at the address 0x00000666 [1] and you can move around by pressing the arrow keys. You can edit the content of the addresses by pressing the corresponding keys (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f). The page-up and page-down keys can be used to scroll up and down by blocks.

An interesting thing to notice is that while moving and editing around the place you start at, you’ll see a lot of the content that is being edited changing. Editing certain addresses seems to be changing the way the screen displays stuff.

Skullcode seems to use mostly ASCII characters but replaces low values with spooky skull themed pixmaps.

My suspicion, deduced purely from observation, is as follows:

Skullcode is a VM written in JavaScript that runs a Hex Editor that allows you to see and edit the content of it’s memory while it’s running.

This is only an hypothesis, it’s now time to validate it.

Notable addresses

From tinkering with the with the editor for a bit I was able to find a few interesting addresses.

0x00000042

Screen contour color.

0x00000043

Filter applied to the screen.

0x00000050 - 0x0000fefe

Every group of 4 bytes from 0x00000050 to 0x0000fefe represent the characters presented on the screen as well as their respective colors. The first couple of bytes represents the chracter from the character map, the third byte drives the character color while the fourth one changed the background color for that character.

The colors are as follows:

Color map

0x00004400 - 0x000065bf

I believe this is the address of the program that is being executed. Unlike the section driving the screen, this section doesn’t change when we move around in the editor.

0x00006600 - 0x0000667f

This thing [2] :

Mysterious instructions

Seeing the sources

Looking at the page source with a web browser we can notice without any surprise that all of the interesting stuff is done in JavaScript. After opening the .js file you are greeted by a gigantic chunk of coding, preceded by the eval keyword and followed by the function presumably responsible for turning this whole blob into an actual script. To obtain a source file that I could study I used wget to grab the source, replaced the call to eval by a call to print and fed all that to a command line javascript interpreter (js17 in this case). It can be done in one (rather long but simple) line in bash.

wget http://skullcode.com/js/skullcode.js ; cat skullcode.js | sed -e 's/eval/print/' > tmp ; js17 tmp > out.js ; rm tmp

I don’t do a lot of web development so I don’t have any beautifiers handy. I’m sure there are online services that could do the trick but I don’t exactly plan on having a perfectly indented source, I just want it to be formated enough to search for stuff efficiently with vim. As such indent is more than enough.

indent out.js

Its still ugly, but less so.

Just by looking around, we can notice that the use asm keyword is used, revealing that Skullcode uses asm.js. The hypothesis that this is just a big VM is looking good so far.

Looking at the character set

Looking at the sources you can easily find the reference to an image that holds the charset used (sc-font-9x16.png).

I downloaded it and created a little script to split the pixmaps in order to compose them using gimp.

#!/bin/sh
o=0
for i in {0..9}
do
    for j in {0..31}
    do
        o=$((o+1))
        x=$(($j*12))
        y=$(($i*19))
        convert sc-font-9x16.png -crop 9x16+$(($x+2))+$(($y+2)) sprite_$o.png
    done
done

The result is a complete map of the characters used in Skullcode:

Character map

While most of them are characters of the standard extended ASCII encoding, the order and placement of some special latin characters seem different from the extended ASCII I’m used to. It’s possible that it’s a variant of an alternative code page I don’t know. I doubt this is a clue to anything meaningful so I decided to avoid spending hours looking at all the old IBM codepages to find a match.

A bit of social engineering

While creating the charset image I mistakenly opened one the original image file with vim at some point. This was purely accidental but it allowed me to find some very interesting information in tEXt chunk inside the png file.

That text area contained a name and an email address (pointing to another domain: vortexcortex.com.

Pinging both vortexcortex and skullcode confirmed that this was a trace left by the creator of Skullcode and not a leftover from a possible original creator of the character set in question.

Doing a bit of internet research with the name I found in the png attached to the mail yielded an unexpected discovery:

skullcode.com/bootstrap/hexboot.txt

I think this marks the beginning of the end of my journey.

What is Hexaboot

The file I found is the assembly source code of a program called Hexabootable. It includes a reference to its license and a quick warning that mentions what the program is capable. The program, written in assembly must be compiled and written to the MBR of a disk that will be booted by the system or a bootloader.

Here is part of the warning section of the file, pasted for convenience:

This software is ammunition for foot snipers.  You will be editing the
system's memory matrix directly, in real time, as it is running. It is
strongly suggested that you first use an artificial construct such as a
Virtual Machine to familiarize yourself with using Hexabootable.

As it stands, the assumtions that Skullcode was an Hex Editor able to edit the memory of the VM it’s running on seem confirmed. Skullcode is Hexabootable running on an VM written in asm.js with a funky skull themed character set.

Conclusion

While I’m content with this denouement, I still need to prove beyond a shadow of doubt that Skullcode IS Hexabootable. To do so I would need to set up a VM and run a newly compiled version of Hexabootable on emulated hardware, something like qemu or VirtuaBox… but the weekend is comming to an end and I’m satisfied with what I found out so far.

I’m just glad to see how far I’ve gone from my initial “wtf” reaction to this conclusion.

I feel like I’ve learned a thing or two and in the end I think that’s the real motivation behind this little journeu. Who knows, learning might even be the initial motivation behind Skullcode itself.


[1] While it seems that the Skullcode creator is being facetious here, I could not stop myself from thinking that 0x666 isn’t the number of the beast in hexadecimal. It would have been funnier to me if the program had initially positioned the cursor at 0x29A

[2] At the end of the day, this is the one thing I still don’t understand about Skullcode. These are instructions, that’s pretty clear. But I don’t understand what they mean.



Enter your desired user name/password and after your comment has been reviewed by an admin it will be posted and your account will be enabled. If you are already registered please login before posting.