# Diablo, fighting Lazarus...

NDH 2018 - RE (150 pts).

# NDH 2018 - Diablo, fighting Lazarus…

Event Challenge Category Points Solves
Nuit du hack 16 Diablo, fighting Lazarus… Reverse 150 1 (Forever Alone)

### Description

This is the second part of the Diablo CrackMe series. This challenge is about reversing some Web Assembly to retrieve the correct value to be passed as an attack.

### TL;DR

Dump the strings using the browser, decompile with WABT and search for the function that prints the correct win message. By single stepping through it I realised that it’s a simple XOR done in 3 rounds. Same as xoring with a 3 letter long key.

### Run it

I started by renaming the given HTML file to index.html. Then I went inside the directory with all the challenge files and started my own server with python :

python -m SimpleHTTPServer


Now when going to localhost:8000 and opening the developer tools -> sources, I could see something like this after having refreshed :

All the WASM functions have successfully been loaded and can now be debugged with the builtin debugger :) I then tried a random password to see what answer I’ll get.

### Dump the strings

Now I wanted to see if the flag was not simply stored as plaintext inside the memory, therefore I dumped the strings unsing the browser console :

for (i = 0; i < 2000; i++) {console.log(i, UTF8ToString(i))}


The flag wasn’t there unfortunately but I still got some useful results :

Now I know that the win message is located at 1597 and the one I got earlier is at 1508.

### Decompile

I searched for references to those strings inside the decompiled source. For that I used WABT.

I found references of the strings from earlier in the _Attack function :

I must now identify this function inside the browser and this is a tedious task because there are no debugging symbols.

After a while, I could identify the 21st function as being the right one.

### Breakpoints

I put a breakpoint at the beginning of this function so that I could do dynamic analysis. By single stepping through the function I realized that a first check is made on the length of the password. The password must be 27 chars long so I chose to input “ABCDEFGHIJKLMNOPQRSTUVWXYZa”

After that, the application does a bunch of work on memory but if I try to access it while debugging, it fails ! I can’t dump the memory while the application is working :(

I continued single stepping until I entered a loop.

In this loop, the first char of the password is xored with the constant 35.

Then this result is compared to 110.

Now I know that the first char of the password is 35^110 = 77 = “M”.

At the next iteration, surprinsingly, it’s not the second letter that is xored but the fourth one (“D”). It skips 2 letter each time and loops 9 times.

By repeating the same process as before, I found the partial flag:

M??1??r??S??4??_??k??4??a??

At this point it was clear to me what was going on, I should encounter 2 loops after this one and that’s exactly what happened. :)

Each following loop did the same but with a different key, which is the same as xoring the entire password with a 3 letter key.

For the curious, the XOR key was “#fB”

### Flag

In the end, the password was M4g1karP_SPl4sh_l1ke_4ttacK

And hence the flag:

ndh2k18_M4g1karP_SPl4sh_l1ke_4ttacK

ENOENT