Shabak Challenge — Part 2: Like a Boss

Danny Povolotski
5 min readApr 28, 2017

--

In the previous part we solved the first challenge put out by the Shabak (Israeli equivalent of the FBI) cyber security division, found here:

10100110110100001100001011000100110000101101011.com

If you followed all the instructions correctly (hopefully I didn’t completely spoil the whole thing for you), you should land on the next challenge page.

Success! Well.. Kinda…
Team Airplane managed to identify the encryption algorithm that the server uses to encrypt the content from the response.
Sadly, they only know how to write pseudo code, so as a programmer you need to buckle up buckaroo and implement the algorithm and decipher the response.

Downloading the file and extracting it yields three files:

  • EncryptedMessage.bin
  • Key.bin
  • ReadMe.txt
EncryptedMessage.bin viewed in a HEX editor

Opening the binary files with a hex editor doesn’t really provide us with anything useful on first glance, so we jump straight to ReadMe.txt that contains some pretty detailed instructions.

MegaDecryptor
--------------
In this exercise you are required to decrypt the secret passphrase that was encrypted with the following scheme.
The encrypted buffer ("CipherText.bin") is encrypted by an alternating stream whose behavior is defined by the key.
The given key ("Key.bin") is an array of EncryptionStepDescriptors, where an EncryptionStepDescriptor is
defined as follows:
struct EncryptionStepDescriptor
{
UINT8 operationCode;
UINT8 operationParameter;
UINT32 lengthToOperateOn;
};
Each EncryptionStepDescriptor describes a single step for a specific operation on the stream.a) operationCode - Here are the operationCodes:
1) Xor = 0
2) Add = 1
3) Subtract = 2
b) operationParameter - Each operation code receives an operation parameter (operationParameter) and uses it with the current
byte in the stream to compute a binary operation.
c) lengthToOperateOn - The amount of bytes in the stream to apply this binary operation to.For example:
Given the stream(/"CipherText.bin"): "ccccccc" and the key: { {Add, 1, 4}, {Subtract, 2, 3} }
we should end up with: "ddddaaa"
If you have reached the end of the stream, but there are more operations to do according to the key
you have to apply the key in reverse.
For example:
Given the stream(/"CipherText.bin"): "aaaaaaaaaaeeeeehhhhhhhhhgggghh" and the key:
{
{
Add,
5,
10
},
{
Add,
1,
5
},
{
Subtract,
2,
9
},
{
Subtract,
1,
8
}
}
we should end up with: "ffffffffffffffffffffffffffffff"

Looks like we’re going to have to get our hands dirty with some code!

Loading Key.bin

Naturally, the first thing we have to do in order to solve this challenge and decrypt the message is load and process the Key.bin file.

First let’s recount what we know about that file. We know that it was design to hold the following data structure:

struct EncryptionStepDescriptor{   uint8_t operationCode;   uint8_t operationParameter;   uint32_t lengthToOperateOn;};

uint8_t is basically the same as UINT8 but more cross-platform and works everywhere.

We also know that the file holds an array of those.

Based on that knowledge and lack of further instructions we’re going to assume that the binary file is serialized using the most primitive and fault prone method (just storing plain data as bytes in a sequential stream, without internal checksums or meta information) and attempt to load the data from the binary file.

We’re going to put the above struct in our code and write a function that takes a file path, and loads the file into the memory into a EncryptionStepDescriptor structure.

We’re expecting the file to contain 8 bits of operation code information, 8 bits of operation parameter and 32 bits of length parameter, repeated as many times as necessary.

Our resulting code with some inline comments to clarify what’s going on looks like this:

To test if it works, we’re going to call the function with the path to our file:

std::vector<EncryptionStepDescriptor> descriptors = loadKey("C:\\Key.bin");
Great success!

It looks like we got it right. The key file seems to contain 8 encryption step descriptors, alternating between their 3 types (Xor, Add, Subtract) and corresponding operation and length parameters.

Loading EncryptedMessage.bin

Now that we have the encryption key, we have to use a similar process to load the actual encoded message. Since we’re going to later need to iterate over it character by character, let’s store the data in a vector<uint8_t> variable.

Looks good! Now let’s try to run it, and see if we get anything.

Great! We’re game. This looks like the same data that we observed earlier in the HEX editor. Now all that’s left is decrypting the message.

Decryption Algorithm

This step is pretty straightforward. All we have to do is carefully follow the instructions laid out in the ReadMe file.

For the sake of comfort and readability, let’s create a couple of enums:

enum Operation { Xor, Add, Subtract };enum Direction { Backward, Forward };

These will help us describe the operation type and direction in our code without using numbers.

First, let’s create a function that takes in a character and applies an operation to it according to the spec we have for this algorithm. This is pretty simple:

This function takes in a character, an operation code (Xor, Add, Subtract) and a parameter. It returns the character after the mutation has been applied to it.

We’re also going to create a very similar function that helps us do some logging:

Now all that’s left is to follow the algorithm steps. I included the code with some helpful inline comments:

Running the result and seeing the decrypted message

And finally, for the moment we’ve been waiting for: we run our final program.

Great Success! I like!

I’ll leave the password a mystery and let you do the work of putting this whole thing together and experiencing the whole process.

Stay tuned for Part 3, where we decrypt the next challenge’s encrypted message.

If you’d like to work with me on real world challenges and problems, shoot me a line to:
dannypovolotski@gmail.com

I also offer mentorship, consultation and assistance. You can check out my reviews on Codementor:

https://www.codementor.io/danny/

--

--