paint-brush
What's wrong with stickers in Telegram? Deanonymize anonymous channels in two clicksby@vognik
1,669 reads
1,669 reads

What's wrong with stickers in Telegram? Deanonymize anonymous channels in two clicks

by Maksim RogovNovember 6th, 2024
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

I reversed the algorithm for generating IDs for Telegram stickers, it leads to their creator, and also developed and automated an OSINT method for deanonymizing Telegram channel authors.
featured image - What's wrong with stickers in Telegram? Deanonymize anonymous channels in two clicks
Maksim Rogov HackerNoon profile picture

Introduction

There are many channels on Telegram that many people call “anonymous”. Their authors like to divide their own accounts into “private” and “work” accounts, customize their privacy to the maximum, and follow the best practices of OSINT countermeasures.


Finding out the identity of the author of such a Telegram channel sometimes becomes difficult. By using a separate account, he leaves no trace behind him, and sometimes he doesn't even use it: many like to specify other sources of communication, like a separate email.


Over time, the channels of these anonymous people become popular, and the authors think about a beautiful design for their brainchild. Telegram provides a lot of creative opportunities to show style: your own background, stickers and emoji.


Authors of Telegram channels order branded stickers from designers and use the @Stickers bot to “register” them in the messenger.


Many use their personal accounts for this purpose without thinking that this becomes their Achilles heel, which can lead to their complete de-anonymization.


In this article we will write our own module for Maltego, which will be able to reveal the identity of the author of an anonymous Telegram channel in two clicks. We will also prove it in practice!

Concept

In Telegram, each sticker pack has its own ID, which can be obtained using the API. For example, let's take the stickers https://t.me/addstickers/HotCherry, here is their visual representation (that is, what the user sees), and what the API sends.



The key field here is the ID field, which at first glance seems to be a unique identifier of the stickerpack and does not indicate its author in any way. However, if you look deeper, it is not so.


There is an operation on a number called binary shift to the right. Its essence is to shift all the bits of the number to the right by a certain number of digits, and fill the free space on the left with zeros.


Let's perform a binary shift to the right by 32, using the example of the number returned by the API.



The number 1391391008142393345 can be represented in binary form, it will be the digit with 0 written in red against it. And then start moving this number to the right, adding zeros to the left - and at the end you will get the digit opposite to which is written 32.


If you translate it into a regular binary value, you will get a shorter and more recognizable identifier 323958464. As we managed to find out, this is not the identifier of a stickerpack, but the identifier of a specific Telegram user.


The user with this identifier in Telegram is the creator of the stickerpack.



I showed you the process of converting from a stickerpack to the profile ID of its owner:


  1. There was a stickerpack with an unclear ID
  2. We performed a binary shift of this ID by 32 to the right (or divided the number by 2^32, if it's easier)
  3. And we got the ID of a specific user in Telegram.


But there is a problem: from the numeric ID we get, we can't directly find out what kind of user this user is: what is his username, avatar and so on, because there is simply no such method in the API. So how did I get the user @owlhug, the creator of the Hot Cheery stickerpack?


There is a reverse API method that allows you to get a user's profile and ID by username. You have it called every time you open the link [t.me/<login](http://t.me/<login) user> or search by username in Telegram.


You can use this legitimate method, scan all Telegram users (for example, by taking them from all public chats), and map ID<>username. Fortunately, I didn't have to do this myself, someone-else did the job for us.


There is a bot that has scanned a lot of users, got all the IDs for them, and now gives free search by them to everyone. This bot's name is tgdb_bot.



So the whole floo looks like this:


  1. Get the stickerpack ID
  2. Perform a binary shift of ID >> 32.
  3. Enter the resulting ID into the bot tgdb_bot.
  4. Get username as output
  5. See the stickerpack creator's profile


And so with every stickerpack that was published in the target channel. If it is a stickerpack branded for a particular channel, there is a chance that it was created by the channel administrator from his personal account.



Manually doing it, of course, is very time-consuming and not convenient.


So we will train Maltego to do everything automatically, let's get started!

Getting to know Maltego

This chapter is about installing and configuring everything you need to get up and running.

Installation and configuration

Here everything is very simple - you need to download from the official sites:


  • Python: programming language interpreter, in which we will write our module.
  • VSCodium: Visual Studio Code source code editor, but with telemetry cut out.
  • Maltego: the tool, with it all will work for open source intelligence, pre-installed in Kali Linux


And install them on your computer by running the appropriate installers.


Maltego is an open source investigative program, primarily a paid program. But it has a Community Edition, - a slightly reduced version, which is quite enough for small tasks. Its serious limitation is no more than 12 results per conversion, but it won't be a hindrance for this article.


To use Maltego CE, you need to download Maltego from the official site to your computer, run it and pass a simple registration. To do this, click the corresponding button under the Maltego CE (Free) bar or simply follow this link.


The program will send us to a website where we will have to fill in a couple of fields.



Once we pass the registration, we go back to the app, click Login and accept the user agreement.



Log in and go through all the other steps, leaving all the default settings.



Final Ninth Paragraph.



Finally, everything is ready to go.


First Look

In my opinion, Maltego has a pretty simple and intuitive interface that is easy to understand. However, you may have questions, so let me explain the basics.



Here are the main features we will be using throughout this article:


  1. New Graph - a canvas on which we will place different Entities, and build a graph that will eventually lead us to the author of the anonymous Telegram channel.
  2. Entity Palette - from here we can drag and drop Entities onto the graph, which can be linked to each other. For example, a person and their assets: phone number, bitcoin wallet, address of their personal website, and so on. Each of these objects is a separate entity, without them Maltego is practically useless.
  3. Transforms are functions that take one entity as input and create new ones based on the input data - this is how a graph grows. Transforms help to extract new information by enriching the existing information.


These three complementary points constitute the fundamental pillars of Maltego.

Ad astra per aspera

It's time to do some development: create Entities, Transforms, and write code.

Creating Entities

There are many different entities in Maltego - bitcoin addresses, organizations, IP addresses, and more can be added to the graph.


However, it doesn't have entities by default, which would allow us to fully work with Telegram itself.


So we'll have to create them ourselves, we'll create three entities:


  • Telegram Channel - this is where Maltego will automatically search for all stickers ever published using Transform
  • Sticker Set - a sticker set, from which we will extract its owner
  • Telegram User - a user of the messenger


In order to start an entity, you need to choose Entities → Manage Entities in the top menu.



This opens a window with many preset entities. From Entity Manager we can import new entities, export existing ones, or create our own entities.



Click on New Entity and get into the mode of creating a new entity.



Let's fill in the fields:


  • Display Name - human-readable name that will be displayed in the left menu of Entity Palette. Now we are creating an entity that will denote the user's profile in Telegram. That's why we will call it “Telegram User”
  • Short Description - a short description that will be displayed right below the name.
  • Unique Type Name - a unique name that we will use during programming to add our entity to the graph. It is recommended to use naming from the company, infrastructure, and short name of the entity itself, separated by a dot. My company will be called Interlinked.
  • Category - the category that the entity belongs to. I'll have it be Social Network, although you could create a separate one called Telegram. This is used solely for grouping.
  • Large Icon - The icon with which the entity itself will be displayed on the graph. Maltego has a pre-installed Telegram logo, so select it.

It should look like this.



The second step is the step of populating the main property or caption that will be displayed below our entity. Besides the main property, there are additional properties that we can create for our transformations.


But right now we will only fill in the main one, let's describe it:


  • Property Display Name - a human-readable name so that we can humanize this property ourselves from the others
  • Short Description - a description so we don't forget what this property is responsible for
  • Unique Property Name - a unique name that we will use in programming
  • Data Type - the type of data that will be written to this field. In our case it's string, because short text will be written here as a value.
  • Sample Value - here I have written onetimeusername, this is the username of Pavel Durov in Telegram. All new entities will appear with a pre-filled property from this value, it can also be left empty.



Once an entity is created, it will appear in Entity Manager. You can find it by keyword. There is also one preset here that relates to Telegram, but it is completely meaningless, so we don't use it.



Now the entity we just created can be dragged and dropped onto the graph. As you can see, it inherits the icon we chose when we created it and the default value. The other properties of the entity are not shown in the graph.



An entity is a convention with which we have represented a real Telegram user on the graph. In our example, this is the profile of the user onetimeusername, which in reality looks like this.



Following the image of the first entity, let's create the remaining two entities as well. This will be the Sticker Set entity, which in Telegram can be displayed like this.



Each Sticker Set has its own name and unique username, by which you can add it to your sticker collection and use it later. Click Create Entity and fill in all the fields in the same way as we did earlier with the profile.



The last in line is a Telegram channel, in the messenger itself it can be displayed like this.



But, again, let me clarify: entities in Maltego are templates that can be used to represent any channel, user or sticker set by filling in the appropriate fields when we add them to the graph.


Let's customize the last entity and its properties.



Finally, all entities are ready for further development.



We can already place them on the graph, but that's not enough. It's time to bring them back to life.

Mastering maltego_trx and pyrogram

Now, finally, let's start programming. Don't worry, it will take very little time to write the minimal logic and your Transform. I'll be using Visual Studio Code to write the code, but you can use any other editor you like.


Maltego has a library for Python called Maltego TRX - you can't write your Transform without it, you need it to integrate with the main Maltego client. Use the command line to install the library.


pip install maltego-trx


Now you can create a project for work, to do this you need to type in the command line


maltego-trx start new_project


where new_project is the name of the project, for me it is maltego-telegram.


A folder with a new project and pre-prepared files will be created.


Let's analyze each of them in order:


  • transforms - a directory with pre-made Transforms, you can look at them and use them as examples to write your own transforms
  • docker-compose.yml and Dockerfile - you can write a module for Maltego and bring it up as a server, many people use this to avoid sharing the source code and selling their own modules. Instead, we will write our own local version, so these files can be deleted, we won't need them.
  • extensions is a file that stores information about the module: the version and its developer, as well as some basic settings
  • project.py - the file that is run to initialize or execute Transforms. It is what Maltego calls when it wants to execute a particular Transform.
  • requirements.py - this file stores the project dependencies, this is maltego_trx and all the others you will use during development. At the end of development you should generate it if you want to share your project with someone.
  • settings.py - configuration settings, we will look at them next.


Now open the folder in VSCodium and start writing the code itself. Since we are going to extract data from Telegram, we need an appropriate library to interact with its MTProto API. The Pyrogram library will work for us.


You can install it using the command


pip install pyrogram


Now you need to log in using this library. Beforehand, you need to go to https://core.telegram.org/api/obtaining_api_id and, following the instructions, get api_id and api_hash values for authorization under your account.



Once the tokens have been obtained, write the following code in a separate login.py file.



All it does is log in under your account and write you messages in your saved messages that everything is working. Our Maltego module uses Telegram MTProto API, so we can't do without authorization.


Now run the script using the command


You will need to enter:


  • phone number
  • the code that will be sent to your personal messages from Telegram
  • cloud password (if you have one installed)



Once done, this will appear in your saved messages



And a session file is created. This is crucial, because Maltego does not provide an input option for Local Transforms, and we would be stuck at the point of logging in. Authorization only takes place the first time, and each subsequent time the existing session from the my_account.session file will be used.



In the settings.py file we remove the standard content (since it is useless in the case of Local Transforms), and replace it with the Config class, which will load the secrets needed for the work: these are already familiar api_id and api_hash, as well as bot_token, which will be needed in the course of work.



The secrets themselves are now loaded from the config.ini file. So before you can use the module, you have to fill this file and execute login.py - otherwise there is no other way.


From channel to stickerpacks

Time to move on to the Transforms folder to write the basic logic. We need to create a file that has a telling name and uses the PascalCase notation - I've reviewed many modules and almost every one uses it.


This is because all Python classes are capitalized, and the name of the file must match the name of the main class that will be inherited from DiscoverableTransform, otherwise Maltego won't recognize it.


So, our first file is ChannelToStickerSet.py, and it will be responsible for dumping all the stickers from the Telegram channel specified by the user, as well as building a further graph.



Let's consider lines 19-30. As I wrote above, it is mandatory to specify a class that matches the file name. And also register the @registry.register_transform decorator with the mandatory parameters:


  • display_name is the label that characterizes Transform. It appears when you right-click on an Entity and want to select a further action. With us, it will characterize the transformation into a sticker set.
  • The input_entity is the entity that is taken as input. Transform will apply to it
  • description - a short description


I have also specified an optional output_entities parameter that will be displayed in the Transforms editing interface, in Maltego, I have specified it purely for convenience.


The first thing we do, after registering all the formalities, is to get channel, the property that specifies the username of the channel.

username = request.getProperty("properties.channel").


Next, I call the asynchronous fetch_stickers function, which does all the basic work of finding stickers. This is done by reading all the messages in the channel and filtering exclusively those that fall under the “sticker” criteria.


async def fetch_stickers(username):
sticker_sets = []
async with app:
	async for message in app.get_chat_history(username):
		if message.sticker is not None and message.sticker not in sticker_sets:
			sticker_sets.append(message.sticker)
	
	return sticker_sets


The final step is to traverse all the collected stickerpacks and call the addEntity function, which creates the entity.


stickerset_entity = response.addEntity("interlinked.telegram.StickerSet", value=sticker_set.set_name)


The parameters passed to it are:


  • interlinked.telegram.StickerSet - UniqueName of the entity, which we specified when creating it as soon as we familiarized with Maltego
  • value - the value itself, which will be written to the Main Property of the entity.


This completes the writing of the foot Transform. It will be used to build a graph with many links from the channel to the stickers that were published in it.

From stickerpacks to their creators

Let's move on to the second file, this is StickerSetToOwner.py , which will be responsible for converting from the stickerpacks we got in the previous step to those who registered them in Telegram, using the @Stickers bot.


The contents of this file are as follows:



The big fetch_sticker_set_owner function is the one that does most of the work. It takes the name of the stickerpack as input and calculates who created it.


Let's understand step by step how it works:


  1. The GetStickerSet method is called, which returns information about the stickerpack, including its unique identifier, a long positive integer.
    sticker_set = await app.invoke(
        functions.messages.GetStickerSet(
            stickerset=types.InputStickerSetShortName(
                short_name=short_name
            ),
            hash=0
        ),
    )


  1. Each stickerpack has its own ID, which, at first glance, looks random. But if you perform a binary shift to the right by 32, this ID turns into the ID of the user who created it. In Telegram, each user has a static ID assigned to him, in addition to his username (which can change). This binary shift can be performed with a single command.
owner_id = sticker_set.set.id >> 32


  1. Based on the ID, the inline function of the bot tgdb_bot is called, which turns these IDs into usernames of real users. It indexed a lot of Telegram users in advance and saved them in its database, and now it allows anyone to search by it.
    if inline_results := inline_search.results:
        message_text = inline_results[0].send_message.message
        username_match = re.search(r'(@\\S+)', message_text)
        if username_match:
            username = username_match[0]
            with contextlib.suppress(Exception):
                owner = await app.get_users(username)
                return owner


But the bot doesn't always find the user, so there is a Fallback with ID return.


At the end, the usual logic with the creation of an entity is executed, this time it is UserProfile, which we created earlier, the main property of which records the obtained username of the user.


    stickerset_owner_entity = response.addEntity(
        "interlinked.telegram.UserProfile",
        value=owner.username
    )


The final touch is to add the written Transforms to Maltego.


In project.py you need to call the write_local_mtz function, which will create a special file with the extension .mtz for importing into Maltego. This file will contain metadata information about all Transforms, the path to the files to be called (ChannelToStickerSet.py and StickerSetToOwner.py), and the path to the interpreter.


In project.py, to do this, call the write_local_mtz function, which will create a special file with the .mtz extension for importing into Malego. This file will contain metadata information about all Transforms, the path to the files to be called (ChannelToStickerSet.py and StickerSetToOwner.py), and the path to the interpreter.


Next, we do


python project.py


And we see the final file telegram.mtz appear in the folder.

Reaping the rewards

Everything is ready to import this into Maltego and check the results. To do this, go back to the program and select Import → Import Config from the top menu. The program will prompt you to upload a file - choose the one that appeared in the previous step.



Maltego will display the Transforms that will be imported into the program. This is done in case you write new Transforms and the program does not import the ones you wrote earlier. Select all of them from the list and click “Next”.



Finish.



Transforms are imported into the program and now we can check how it will work. To do this, add a Telegram channel entity to our graph from the menu on the left.



Double-click on the entity and change the username. I have entered here the username of my channel, which was specially created for testing this module.



The contents of this channel itself are three stickerpacks from different sets.



Now, if you click on the created entity, you will see a Transform that wasn't there before - this is the result of our work.



Click it. We wait for the script to run and see three new stickerpacks that were previously published in the channel appear before our eyes.



Now select any stickerpack, click on PCM and “To Sticker Set Owner”.



Magic happened before our eyes! We got all the stickerpacks ever published and were able to recognize their owners in just a couple of clicks.



All stickerpack owners are known, but the only thing missing is beauty. In order to clearly understand what kind of stickerpacks they are, we would like to display their previews, as well as avatars of their creators. This will require some small improvements, which we will do now.

Cosmetic improvements

We refine already existing mechanisms - we learn to add new properties and fill them, so that in the end it turned out beautifully, and was not ashamed to share graphs.

New Properties

Go to the familiar Entity Manager and search for the keyword “Telegram” so that we have all the entities at our fingertips. We will have to edit all 3 entities and add new properties to them (such as previews and titles), so we'll have to do a bit of work.



Open the first entity - Telegram User. And add an ID property for it. This is necessary in case we fail to convert the user ID into username, but we still need to save its ID (in case we manage to run it through other sources manually?).



Add also properties:


  • Photo (URL type) - here we will save the user's photo to display it on the graph instead of the usual Telegram icon and to distinguish it from other entities.
  • First Name and Last Name - each user has a natural name in addition to Username, and we will store it under the entity itself.
  • Full Name - Maltego has functions that allow us to fill the fields automatically, based on other fields. We can take the values of the First Name and Last Name fields, and display them as a caption right below the entity in the graph. The $trim($property($properties.first_name) $property($properties.last_name)) function concatenates two strings, first name and last name, and removes the extra spaces on the sides.



It is also worth mentioning that Maltego has two types of variables for images:


  • URL - when you specify here the address of the image, it is loaded by the link automatically
  • IMAGE - a local image that is loaded from your computer


I would prefer the second type with local images, but it didn't work correctly for me (when I tried to specify an image for an entity, it didn't save), so we use URL. This carries some security risks, which I will discuss below.


After you've filled everything in, you should get something like what's on the screenshot:



Now switch to the Display Settings tab. Here you can customize the properties that the entity will display. We are only interested in two of them:


  • Display Value - the signature that is displayed below the entity. Earlier Username was specified here, but it would be more logical to set “Full Name”, i.e. not his “nickname”, but his real name.
  • Large Image - by default, we have the Telegram icon here. But we want to display the user's avatar, so we change this value to Photo, where we will write the link to the avatar.


We set up the Telegram channel in the same way: it has a username (which we already set up when we first created the entity), as well as a logo (which here is called Photo), and the name of the channel itself.



And Sticker Set. In Telegram terminology, Thumbnail should be stored as an image.



That's the end of the property customization, it's time to add some minor updates to the code.

Good old code

I created a new file utils.py and wrote in it a wrapper over functions to handle HTTP requests from the Requests library. The difference between it and the usual one is that it can execute different types of requests, and retry them if the connection failed the first time for some reason.



Getting previews for stickers is done in several steps:


  1. The getStickerSet method is called to get information about the sticker. The response will contain a file_id that points to the preview image. This is typically the optimized image of the first sticker in the set.


  2. Next, we need to get the file_path to generate the final link. This is done by querying the getFile method and specifying the file_id from the first clause as a parameter of the same name.


  3. When the file_path is obtained, the preview finally downloads it via a direct link.


I have formalized all this floo as a separate class StickerSetPhotoFetcher , which uses the same bot_token from the config. But why do we need it when we already use MTProto API with Telegram library?


As I mentioned above, even if you download an image using Pyrogram, for some reason it is not imported correctly into Telegram. This may be a problem with my PC or the Community version of Maltego.


Since there was no solution with a static file, the only way to directly link to it is through the usual API, using raw HTTP requests, which is what we use.


The risk to consider here is that Maltego stores a direct link to the file, with your bot's token. So start separate bots that are not linked in any way to real projects, and share projects with caution.



The final step is to call the function function and pass the name of the stickerpack to it. Once the image is received, it can be written to the properties.thumbnail property

stickerset_entity.addProperty("properties.thumbnail", value=thumbnail)


We do the same with the name, it was already returned to us by the regular API when we got set_name from the sticker set.

stickerset_entity.addProperty("properties.title", value=sticker_set.title)


In the end, it should look like this:


In the case when we get a Telegram user and the StickerSetToOwner.py file, everything is much simpler - it is enough to take a photo from the t.me/<username> page and save a link to it. The username is taken from the same place.


Finally, it's done!

Now that everything is ready, it's time to go back to Matego and see how it works. This will be the smallest subchapter in this epic article, so without further ado:


It works perfectly!

Comrade Z Major

At the beginning of the article I claimed that this method can be used to de-anonymize the owner of a Telegram channel, but I did not provide evidence - it's time to correct myself.


For an example, I took a random Telegram channel where I thought the author was impersonating someone other than who he really is.


It is called “Comrade Major Z” and has almost 17,000 followers. Initially, posts in it were published ostensibly on behalf of a “comrade major” from the Russian Federal Security Service, with short text messages and random photos of “people in epaulets”.



In 2019, this same “FSB Major” covered the “protests for fair elections” that were taking place in Russia at the time.



Currently turned into a news channel with more moderate rhetoric. It writes about the Russian-Ukrainian war (SVO in the Russian context) and various events in Russia with a pro-state position.



The contacts include a channel with three subscribers @silovikicat without any information, as well as the mail mayorfsb.protonmail.com, about which there is no information in public sources. So it's time to try the Maltego way of searching.


Your personal FSB handler. The most scandalous telegram channel. For support questions contact @silovikicat or email [email protected].


Add the channel to the program and search for stickerpacks and their creators:



Among the stickerpacks of Pepe Frog, Slutsky and Taxi Ultima, which do not stand out in any remarkable way. However, there is one special one that bears the same name as the channel itself, MayorFSB, with the exact same nickname.



The contents of the stickerpack are photos of the enforcers with “branded quotes,” with the last sticker in the set pointing to the @MAYORFSB channel itself, the contents of which we just checked out above.


Inscriptions on stickers, from left to right:


  1. I'm gonna put you in jail for reposting
  2. Comrade Major @MAYORFSB
  3. The general said to put everybody in the squad car



Maltego shows that the creator of the stickerpack is a certain “Mikhail K” with the username kapyshonchik. If you open his profile in Telegram, you can also see the characteristic description “I oppress soy, promote imperialism, do colonization. Expensive.”



It's easily found through a Google search. Here, for example, is the Facebook profile of “Mikhail Kapyushonov”, which has exactly the same username https://www.facebook.com/kapyshonchik/.



We also managed to find a LinkedIn page where he already has his real name - Mikhail Grachev. The avatar matches one of those published on Facebook. Educated at the Financial University under the Government of the Russian Federation, Last place of work - own internet marketing studio RUCOM.



He spent a year in design and has been running his own marketing studios for over 13 years.



You can see he likes the FSB theme. On the site printdirect.ru, a user with the same nickname created a single T-shirt with an artwork and a quote from the founder of the Soviet state security agencies.


“Only a man with a cool head, a hot heart and clean hands can be a chekist.” - T-shirt quote


On Instagram, Mikhail also publishes a photo against the background of the FSB building on Lubyanka, as well as a facade sign of the FSB, this time from St. Petersburg.


The FSB building on Lubyanka is seen in the blurred background

Federal Security Service of the Russian Federation for the City of St. Petersburg and the Leningrad Region


At the stage of analyzing the channel “Comrade Z Major”, I also noticed that its author actively PRs the Russian battalion “Española”. There are more than 20 positive references to this battalion on the channel.



This battalion is known for the fact that its main part is made up of Russian soccer ultras. “Española” was created in 2022 to participate in the war against Ukraine.


Some part of the battalion holds neo-Nazi views.


Mikhail “Pitbull” Turkanov is a neo-Nazi, the commander of one of Espanyola's units.


I thought that the PR posts in support of Espanyola were not random, and I also decided to check the Telegram channel of this battalion - it is not anonymous and has contacts for communication.


Its editors do not publish stickers, but many posts are accompanied by emoji captions “Glory to Russia” and “Española”.



An emoji search led to a faceless profile under the nickname izvekovaelvira


The same nickname can be found on Telegram, and it's a woman in a relationship with Dzerzhinsky fan, Mikhail Grachev.



That about sums it up. Using my Maltego module, I found that kapyshonchik:


  • registered stickers for the “Major Z FSB” channel.
  • is a fan of Dzerzhinsky, and even created his own t-shirt design with him on it.
  • likes to take pictures of FSB buildings (but, as stated on his LinkedIn, has no ethnical affiliation with the service).
  • the rhetoric under the posts with FSB buildings is similar to that used in the channel's early posts (as well as in the profile description, where he alludes to his activities)
  • his girlfriend drew emoji for the channel of the Russian battalion Espanola, which is actively promoted on the channel “Major Z FSB”


These are facts based on my judgment. They do not directly indicate that Mikhail is the administrator of the FSB Major channel. But their totality indicates that he is related to it and may well be its administrator.


Conclusion

This is where our article comes to an end. I wrote in detail about how to write modules for Maltego on the example of finding stickerpack owners, and also did my own little investigation to find the administrator of the channel “Comrade Z Major”, who pretends to be a “man in shoulder straps”, but is not.


I hope this article was useful to you! I would appreciate your feedback.



Source code: https://github.com/vognik/maltego-telegram