Challenge info

Challenge info

It's pretty obvious that this is a script written in the python interpreter's interactive mode.

Here is the commented code for better explanation:

>>> import base64 #importing base64 library
>>> msg = msg + " "+ base64.b64encode(data)       #encoding "data" in base64
                        #then adding it to local variable "msg"
>>> y = []    #creating an empty list "y"
>>> for i in range(0,len(msg)):   #For loop
y.append(ord(msg[i]) + i)   # getting the ordinal (Unicode value) of each character of "msg"
              # then adding the loop's iterator "i" to it
              # then append the result to the list "y" created in line 4
>>> y = y[::-1]       #reversing the list "y"
>>> y #printing "y" in the interpreter
[249, 264, 274, 285, 287, 256, 233, 279, 289, 245, 245, 277, 288, 241, 241, 273, 280, 271, 241, 242, 217, 224, 253, 266, 267, 215, 249, 250, 266, 225, 279, 247, 278, 204, 204, 241, 200, 237, 259, 248, 254, 233, 196, 244, 247, 242, 251, 239, 252, 243, 188, 236, 248, 255, 243, 222, 181, 197, 202, 202, 250, 235, 197, 198, 232, 201, 194, 220, 232, 239, 168, 206, 224, 181, 197, 214, 217, 177, 177, 199, 216, 189, 157, 204, 222, 207, 173, 174, 221, 185, 148, 194, 214, 169, 204, 174, 195, 172, 139, 187, 162, 153, 207, 174, 196, 203, 191, 170, 129, 145, 148, 150, 195, 149, 125, 171, 140, 137, 153, 151, 100, 164, 182, 162, 164, 95, 165, 171, 165, 178, 169, 165, 164, 166, 156, 85, 153, 155, 166, 81, 149, 165, 143, 149, 76, 144, 129, 73, 154, 140, 145, 136, 133, 139, 66, 130, 64, 132, 144, 126, 60, 144, 137, 146, 56, 139, 119, 125, 136, 51, 137, 128, 126, 122, 46, 86, 44, 57, 124, 110, 111, 117, 103, 119, 120, 86, 34, 106, 72]

And since we want to reverse what the author did, so we'll start from the bottom up.

This is what the author did (in order):

  1. Encode "data" in base64.
  2. Concatenate (add) "data" to "msg".
  3. For each character of that encoded "data", grab the ordinal (unicode value).
  4. Add "i" to that unicode value.
  5. Add each value to our list
  6. Reverse the list

So, we'll do the inverse of each step, starting from step 5 to step 1. I'll use python (Python 3.6), but you could use any language you like.

This is our plan:

  1. Reverse the list
  2. Take each value from the list
  3. Subtract "i" (iterator) from each character
  4. Then grab the character equivalent to the ordinal (unicode value) we have after subtraction.
  5. After finishing all the characters, read the message to find out what it says, and to know where the encoded base64 data is.
  6. Decode the "data" in base64.

Lets go.

.

1. Reverse the list:

There are many ways to reverse a list in python. We could just use the same one that the author used in the challenge's script.

y = y[::-1]

Here are 2 other ways to do it in python.

2. Take each character from the list (i.e. a For loop)

I used a for-loop, similar to the one in the challenge's script:

y = [249, 264, 274, 285, 287, 256, 233, 279, 289, 245, 245, 277, 288, 241, 241, 273, 280, 271, 241, 242, 217, 224, 253, 266, 267, 215, 249, 250, 266, 225, 279, 247, 278, 204, 204, 241, 200, 237, 259, 248, 254, 233, 196, 244, 247, 242, 251, 239, 252, 243, 188, 236, 248, 255, 243, 222, 181, 197, 202, 202, 250, 235, 197, 198, 232, 201, 194, 220, 232, 239, 168, 206, 224, 181, 197, 214, 217, 177, 177, 199, 216, 189, 157, 204, 222, 207, 173, 174, 221, 185, 148, 194, 214, 169, 204, 174, 195, 172, 139, 187, 162, 153, 207, 174, 196, 203, 191, 170, 129, 145, 148, 150, 195, 149, 125, 171, 140, 137, 153, 151, 100, 164, 182, 162, 164, 95, 165, 171, 165, 178, 169, 165, 164, 166, 156, 85, 153, 155, 166, 81, 149, 165, 143, 149, 76, 144, 129, 73, 154, 140, 145, 136, 133, 139, 66, 130, 64, 132, 144, 126, 60, 144, 137, 146, 56, 139, 119, 125, 136, 51, 137, 128, 126, 122, 46, 86, 44, 57, 124, 110, 111, 117, 103, 119, 120, 86, 34, 106, 72] #the message in the challenge
y = y[::-1] #reversing the list
for i in range(0,len(y)):
    value = y[i]
    print(value) #printing each value just for fun

3. Subtract "i" (iterator) from each character

We should subtract "i", because the user added "i" to each value. This "i" is based on the loop's current position.

y = [....] #the message in the challenge
y = y[::-1] #reversing the list
for i in range(0,len(y)):
    value = y[i]
    #print(value) #printing each value just for fun

    ordinal = y[i] - i; #subtracted "i" from each value in our list

4. Grab the character which is equivalent to the ordinal

Now we have a number. How did the author calculate this number?

He used python's built-in "ord( )" function to calculate the unicode value of each character from the original message.

What is the inverse of that?

Python's built-in "chr( )" function. It returns to us the original character from the unicode value we supply to it.

So our code now will look like this:

y = [....] #the message in the challenge
y = y[::-1] #reversing the list
for i in range(0,len(y)):
    value = y[i] print(value) #printing each value just for fun
    ordinal = y[i] - i; #subtracted "i" from each value in our list

    original_character = chr(ordinal) #return the original character from the unicode value

We should store the result characters in a string, so that we could print out and read the message.

So our code is:

y = [....] #the message in the challenge
y = y[::-1] #reversing the list
msg = "" # an empty string. we will add our characters to it in the loop
for i in range(0,len(y)):
    value = y[i] print(value) #printing each value just for fun
    ordinal = y[i] - i; #subtracted "i" from each value in our list

    original_character = chr(ordinal) #return the original character from the unicode value
    msg += original_character

5. Read the message

We just use the "print( )" function:

print(msg)

This is what I got:

Running our script

It's obvious that the highlighted part below is the base64-encoded "data". Lets decode it.

base64-encoded "data"

6. Decode "data" in base64

We could just use an online base64 decoder. But why not do it in python?

Python has a built-in library called "base64". Inside it, there is a function called "b64decode". Lets use it.

import base64 #must import the base64 library to use it

y = [...] #the message in the challenge
y = y[::-1]

msg = "" # an empty string. we will add our characters to it in the loop
for i in range(0,len(y)):
  value = y[i]
  ordinal = y[i] - i; #subtracted "i" from each value in our list
  original_character = chr(ordinal) #return the original character from the unicode value
  msg += original_character

#print(msg) #printing our msg
#Hi Stranger. I know that you are a hacker We have the following data RSBDb3JwIFB1YmxpYyBJb1QgQnJva2VyIGhvc3RlZCBieSBlY2xpcHNlIGlzIHB1Ymxpc2hpbmcgc2VjcmV0X21zZyBjYW4geW91IGdldCBpdCBmb3IgdXM=

base64_data = "RSBDb3JwIFB1YmxpYyBJb1QgQnJva2VyIGhvc3RlZCBieSBlY2xpcHNlIGlzIHB1Ymxpc2hpbmcgc2VjcmV0X21zZyBjYW4geW91IGdldCBpdCBmb3IgdXM="
data = base64.b64decode(base64_data)
print(data)

This is the "data" printed:

decoded "data"

It says that an "IoT Broker" hosted at "eclipse" is publishing a "secret_msg". Ok, it appreas that we've finished one part of this challenge. Lets continue.

.

Second part of the challenge

"What is an IOT broker?" you may ask. A quick google search will give you this result:

What is an IoT message broker?

One of the messaging protocols used by "message brokers" is MQTT.

MQTT stands for MQ Telemetry Transport. It is a publish/subscribe, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth

And guess what website offers a free MQTT server (broker) you can play with? Eclipse.org ?

Eclipse's free broker/server

Lets download any free MQTT client, and connect to eclipse's MQTT server. I used MQTT.fx .

After download, install, and runnning, this is what we get:

MQTT.fx application

Configure it to connect to Eclipse's server (broker) like this:

Server configuration

Then connect. After the connection is successful, you can subscribe to any topic to receive the messages that are transmitted for this topic.

I subscribed to the following: "E Corp", "E-corp", and "secret_msg". Remember?

'E Corp Public IoT Broker hosted by eclipse is publishing secret_msg can you get it for us'

And after waiting a couple of seconds, I got this message.

base64 encoded message received

We could conclude that it is encoded in base64 because we see the characteristic padding (the two equal signs "==" at the end). Lets decode it online.

Online base64 decoder

Lets wait 2 minutes to get the flag ?

This is what I got after waiting.. 30 more messages..

We received 30 more messages

One of them is this:

A message to say that the flag will be sent now

And the rest is just numbers:

They're probably unicode values like we saw earlier.

Lets copy the numbers manually from those 29 messages, and then put them in a list:

secret_msg = [83,97,108,117,115,108,97,98,123,49,95,83,116,48,108,51,95,66,114,48,107,51,114,95,70,108,52,103,125]

Then loop through this list, decode each character, add them all together and print the decoded message:

secret_msg = [83,97,108,117,115,108,97,98,123,49,95,83,116,48,108,51,95,66,114,48,107,51,114,95,70,108,52,103,125]

secret_msg_decoded = ""
for i in secret_msg:
  decoded_character = chr(i)
  secret_msg_decoded += decoded_character

print(secret_msg_decoded)

And we got our flag:

the flag!

.

I wanted to show you how to automate the connection to the MQTT-broker using python. It's really easy and straight forward, and we wont have to copy the unicode values manually... but that'll be later in another post.

Thanks for reading.