Even more secret telegrams

Even more secret telegrams

Everyone is accustomed to consider telegrams to be a reliable and secure medium for transmitting messages of any kind. However, under the hood, he turns a completely ordinary combination of a- and symmetric encryption, but this is not at all interesting. And in the end, why bother to explicitly trust your messages to a third party?
KDPV by Antonio Prohías
TL; DR - we invent a private hidden channel through users blocking each other.

Covert Channel

There are many workarounds for transferring data between two users, avoiding explicit contact. You can use intermediaries, crypto and steganography, broadcast relay networks and other add-ons over existing protocols. But sometimes it is useful to be able to make contact using only the official stated opportunities. That is, organize hidden channel .

A simple and understandable example of a hidden channel for a Russian-speaking reader is a flower in the appearance window of seventeen moments of spring. By itself, he can either stand or not stand on the window - such a symbiosis is quite common and only speaks of the owner's love for flowers. Only a predetermined interpretation distinguishes the information transmitted by the scout from her, which is received by random passersby.

Flower in the window

Flower-window telegraph channels

To organize your hidden channel by such an example, only two things are conceptually needed: a window and a flower. The window describes the object available for changing and determining the state, and the flower the possible values ​​and the method for changing them.

So what can someone Alice change in a telegraph that is available for viewing to a certain Bob? Yes, a lot of things: avatars, usernames, last visit time and much more. However, they are usually available to everyone at once, which limits the privacy of a possible dialogue — anyone with knowledge of the transmission method will be able to listen to the messages being sent. Oddly enough, this restriction can be circumvented without using cryptography.


Each user has his own unique blacklist, and if the reader has been in it at least once, he should have noticed that the date of the last visit of the offender has changed to "last seen a long time ago" along with an empty avatar. In fact, the user could be online at least a second ago and change a hundred cats in his profile, but the Telegram API simply does not return this data to the application. In this way, it protects your privacy from unwanted persons, instead of letting them know that they are blocked.

So what is the general result between the flower in the window and being in the block list? Both can be checked at a certain point in time by receiving one bit of information depending on whether you are on the black list or not. An additional bonus is the fact that telegrams most likely do not store (or, if they do, not for long only for logging purposes) the history of blocking each other’s users in their logs.

Organize bits

The ability to send and receive bits is, of course, good, but you still need to describe the full mechanism of its operation. The telegram does not send notifications to users when they are added to the blacklist, so the reception of each bit must be initiated by the recipient (Bob) and not dependent on the sender (Alice).It also follows that Alice and Bob must execute requests with the same frequency so that each recipient clock corresponds with one recipient clock.

The exchange algorithm itself at each clock cycle looks like this:

  • A checks the sent bit and, if you want to send a signal, depending on its value:
    • A - & gt; T: block B;
    • A - & gt; T: unlock b.
  • B gets the bit:
    • B - & gt; T: request from user A;
    • T - & gt; B: available B information about A;
    • B: Checks if the received information has a status.

Most modern user processors have good built-in frequency generators (at least, a system clock), so the clocks can be synchronized with their help without using the data transfer channel itself. One has only to note that requests to the telegram API are networked and do not rush to work quickly, which is not helped by the fact of its blocking in the territory of the Russian Federation and the need to use a proxy. But the cycle length should, on average, exceed the time required to complete these requests, so the frequency and data transfer rate is extremely small.

Encode messages

Texts in natural language have a fairly high redundancy, so the messages received with errors will still be often understood by the person. And since telegram is still a messenger, despite attempts to attach all sorts of graphic-audio-video gadgets to it, error correction can be neglected by limiting the data transmitted by text messages.

Due to the low bandwidth of the covert channel, you need to use the most efficient coding for possible messages. Fortunately, the very name of the messenger reminds us of the times when such problems were common.

Therefore, being in the 21st century, we will encode texts with one of the most effective methods available to telegraph operators a century ago - Baudot . More precisely, with its latest variation ITA-2, authored by Murray, in order to make fewer API calls on frequently encountered characters. You can complain about the lack of Russian language, but in my view, transliteration is a simpler way out than Sacrifice additional characters to everyone Yu and U .

It remains only to determine the beginning and the end of each data transfer session, so that the receiving party can select the messages transmitted to it from among the large stream. Before the transfer, Bob is either on the black list or outside. Then Alice signals the beginning of the transfer, changing this state for one clock cycle to the opposite. At the end of the program, she simply unlocks Bob. He continues to receive null characters until he has accumulated enough to reliably state the end of the transfer.

On the timeline

The downside of this approach is the practical impossibility of connecting (more precisely, you can connect, but you have to tinker with manual error correction) to the already ongoing broadcast and separate mistakenly received zero symbols from the actually transmitted ones. However, these are already implementation problems.

High Technologies

After several hours of trying to use the official library to interact with the API, I spat and wrote everything I needed on python using a more human Telethon. The author even presents the API in a synchronous style, which for some reason has become a terrible rarity. Encoding messages using ITA-2 had to write on the knee itself, since I did not really find anything ready.

Frequency synchronization occurs on the system clock (and yes, the program is asleep! in between), which are accurate enough, given the required time to perform requests to the API, which is consistently more than a tenth of a second. The user can set the transfer rate as desired, however, I use the principle “no more request per second” to avoid both errors and freezing for spam with the same type of requests. Telegram, in general, turned out to be very picky about using its API, freezing access to the account through it for a day, even if you simply made three authorizations (and moreover, were successful) in a row, as well as occasional short-term blocking for unknown reasons.

If users are already exchanging telegrams via a hidden channel, they don’t need a special GUI. And not everywhere it is, so I wrote a regular console utility. It allows you to wait in one run and receive a message using the specified user ID, or send it by reading from the command line arguments. Of course, no one forbids using several channels at once, as well as receiving and transmitting messages in parallel, you just need to run several instances in parallel.

Example of usage

To use, you need to get your api_id and api_hash from the telegram by of this instruction and set the obtained values ​​in the file 'covertele.py '. The command line arguments specify the desired action, your ID, the recipient ID, and the message to be sent, if it is the sender. It all looks something like this:



The text is decoded automatically, but amateurs can search for errors with their hands, read on the go and track progress can do it all by outputting the codes sent and received.

If someone wants to, you can also use the simple API provided:

  from covertele import TelegramBlockingAPI
 from cochannel import CovertChannel

 friend = input ("Enter the name of the friend for data transfer:")
 # To work with the telegram channel, you must first create an interaction interface
 # By default, standard I/O is used for authorization, read the source code while crawling
 id = input ("Enter your ID:")
 api = TelegramBlockingAPI (id)

 # A channel is created directly using the created interface
 friend = input ("Enter your friend's id:")
 channel = CovertChannel (api, friend)

 # You can then use channel.receive () and channel.send () to directly exchange data
 channel.send ("Bork, bork!")
 print (channel.receive)

 # If you need to process the code for errors automatically, you can use their counterparts with the suffix _raw
 codes = channel.receive_raw ()
 for code in codes:
 check (code)
 channel.send_raw ([19, 24, 24, 13])  

outside of telegram

It is clear that such a channel can be organized on top of any messenger in which there is a method for determining whether other users block themselves. At the same time, similar interfaces are easily implemented and substituted in a similar way into the code. So if there is a desire - you can use ready-made, and not to write coding, etc. from scratch. Fortunately, a slow python is unlikely to interfere with bitwise transmission at such speeds.

P.S. Special thanks to my passion for love to throw me in an emergency.

- & gt; GitHub

Source text: Even more secret telegrams