Even more secret Telegrams

Labunsky Artem
May 20, 2019 · 7 min read

We used to think of Telegram as a reliable and secure transmission medium for messages of any sort. But under the hood, it has a rather common combination of a- and symmetric encryptions. Where’s fun in that? And why would anyone trust their messages to the third-party anyway?

Image for post
Image for post
Spy vs Spy art by Antonio Prohías

TL;DR — inventing a private covert channel over users blocking each other.

Covert channels

We can see an example of it in a Soviet spy movie “Seventeen Moments of Spring” (this one is, like, really good, give it a chance). In it, a flower in a window of the safe house was used to signal if the spy had failed his mission or not. The flower by itself does not mean anything: it can be there and could be not, such symbiosis is a common thing and only telling us about the owner’s love for flowers. Only a predetermined interpretation distinguishes the information received by a spy from the one received by a random passerby.

Image for post
Image for post
Well, someone has failed his mission

In-Window Flower-based channels in Telegram

So what Alice could change in Telegram that Bob can see? Many things, actually: avatars, usernames, last visited time and more. But usually, these things are available to everyone at the same time, limiting dialog privacy — if one possesses the transition method, he could read anything Alice sends. Surprisingly, it is possible to get around this limitation without any kind of encryption involved.

I’m blocking you, haha

Organizing bits

Bit exchange algorithm on every clock looks something like this:

- A checks sending a bit and if has different from the previous value changing it depending on a value:
- A -> T: block B if bit is 1;
- A -> T: unblock B if bit is 0.
- B receives a bit:
- B -> T: resolve A;
- T -> B: available to B information about A;
- B: checks if the received information has a status it:
- B: if it is -> he is not blocked and the bit is 0
- B: if it is not -> he is blocked and the bit is 1

Most modern PCs have good frequency generators (a system clock, for example) so we can synchronize our clocks with them while not using the channel to transmit anything except for the message bits. Only worth noticing that Telegram API requests, both (un)blocking and user status resolving, are network calls and do not tend to work quickly, especially if you are using proxies or VPN. This produces a limitation: clock length should be longer, than an average response time (since we need to fit one into another) and that’s why our data transmission speed will be limited.

Encoding messages

Our channel has extremely low bandwidth, so why we need to use the most effective message encoding available for possible messages. Lucky us, the name of the messenger is reminding about times such problem was a common one.

That’s why we, living in the 21st century, will encode our texts with one of the most efficient available to telegraphers a hundred years ago encodings — the Baudot code. More precisely, its final variation ITA-2 created by Donald Murray to perform fewer API calls at the most frequent symbols of the language.

The only left to successfully transmit a message is to find session boundaries so the recipient could find a sent one among the continuous bit stream. Before the transmission has started, Bob is either blocked or not, and this state will not change by itself anytime soon. That’s why Alice can indicate session start by swapping it to an opposite for only one clock. At the successful end of the session, she will unblock him and leave with peace. He, on the other side, will continue to receive zero bits until decides they are not a part of the message — the Baudot code has no 00000 symbol.

Image for post
Image for post
Message transmission session on the timeline

Drawbacks of the method are a practical impossibility to connect (you can, but it will likely require manual error correction due to the bit shift) to ongoing translation and a need to separate null symbols received with errors from ones been sent. But there all problems of implementation.

High tech

Clock synchronization made with system clocks (and yes, it sleep()s! in between) since it is precise enough considering the time required on every network API call is more than a tenth of a second in most cases. User can set transmission speed as he wants to, but I recommend following ‘no more than a request per second’ rule if you don’t want to both see errors on the other side and find yourself banned by a flood prevention system. Telegram turned out to be very picky about API usage, freezing my access for a day from even a few simple (successful!) authorization attempts in a row and just random blocking for a flood during the transmission for an unknown reason. You should always declare your API usage limits, guys.

If the user decided to use such a weird channel to exchange messages, he should not care about any graphical user interface features. And not all systems have it anyway, that’s why I wrote my application in the form of terminal tool. It allows to both send and receive messages via a channel by a given in command-line arguments user id, but only one operation per launch. Of course, no one will limit you to running only one copy of a program at ones and use multiple channels simultaneously in both ways, you’ll just need to run several copies of the same script with different parameters.

Using the stuff

For Alice:                       |    For Bob:

Enter your phone number: XXX | Enter your phone number: XXX
Enter auth code: YYY | Enter auth code: YYY
Started message transmission... | Listening for the message...
---++ ('O', '9') | ---++ ('O', '9')
--+-+ ('H', '#') | --+-+ ('H', '#')
+++++ (1, 1) | +++++ (1, 1)
--++- ('N', ',') | --++- ('N', ',')
--+-- (' ', ' ') | --+-- (' ', ' ')
++-++ (0, 0) | ++-++ (0, 0)
--+-+ ('H', '#') | --+-+ ('H', '#')
-++-- ('I', '8') | -++-- ('I', '8')
--+-- (' ', ' ') | --+-- (' ', ' ')
--+++ ('M', '.') | --+++ ('M', '.')
++--- ('A', '-') | ++--- ('A', '-')
-+-+- ('R', "'") | -+-+- ('R', "'")
++++- ('K', '(') | ++++- ('K', '(')
+++++ (1, 1) | +++++ (1, 1)
+-++- ('F', '!') | +-++- ('F', '!')
--+++ ('M', '.') | --+++ ('M', '.')
--+++ ('M', '.') | --+++ ('M', '.')
Done, exiting... | ----- ('', '')
| ----- ('', '')
| Automatically decoded: OH, HI
| MARK!..

Received message will be decoded automatically, but if you want to track progress and/or correct some errors manually, take look at command line output.

Outside of the Telegram

P.S. Special thanks to my passion’s unusual love for blocking me

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store