Telegram API for OSINT – Part 1 – Users

Those of you who have read my previous post or even tried out the getUsers script will already see that there is a large amount of data available within Telegram that isn’t easily accessible to the average user.

Over time I will be adding scripts to this page, hopefully enabling better data extraction for OSINT researchers or the nosey people out there! This is part one of a long series of technical blog posts on what data the API contains and how to extract data from Telegram, starting with part 1 on Users.

Users

A user object in Telegram contains a whole host of information, the userFull object contains the following information:

userFull.PNG

The user object returned can be one of the following:

  • userSelf – current authorized user
  • userContact – user from the contact list
  • userRequest – user not from the contact list, but with known phone number
  • userForeign – user not from the contact list
  • userDeleted – deleted user

Most commonly the User object will be userForeign and will contain the following parameters:

userForeign
UserForeign Object – User is not in contact list

Querying a User

To query the Telegram API for user details, one of the following is required:

  • The user must be a contact
  • The user has a public username
  • The user is in a common group and has been previously queried (see scripts)

Querying a User – Username

If a user has provided a public username, the user will appear in a search (this will be covered in a later post) or the user can be queried directly with their username:

var mtpApiManager = angular.element(document).injector().get('MtpApiManager');
mtpApiManager.invokeApi('contacts.resolveUsername', { 
  username: "publicUsername"
}).then(function (user) {
  console.log(user);
});

Querying a User – ID & Access Hash

To query Telegram for a user, the users.getFullUser API call requires one of three constructors:

  • inputUser = {_: ‘inputUserSelf’}
  • inputUser = {_: ‘inputUserContact’, user_id: id}
  • inputUser = {_: ‘inputUserForeign’, user_id: id, access_hash: user_access_hash}

These are mostly self explanatory, however for inputUserForeign, as the user is not a contact, the access hash is required. This is a checksum of the user_id and is returned by Telegram when the user has previously been queried (using a username or from the list of members in a group).

var mtpApiManager = angular.element(document).injector().get('MtpApiManager');
mtpApiManager.invokeApi('users.getFullUser', {
  id: inputUser
}).then(function (user) {
  console.log(user);
});

Downloading Photos

Photos in Telegram are stored in one of several data-centers and can be retrieved providing you know the volume_id, local_id and secret.  These values are returned in all of the user lookup methods described above.

The downloadSmallFile function is part of the MtpApiFileManager service and returns the data blob for that image. The blob can be turned into an image dataURI using the FileManager.getDataUrl function.

var mtpApiFileManager = angular.element(document).injector().get('MtpApiFileManager');
var fileManager = angular.element(document).injector().get('FileManager');
var inputFileLocation = {
  _: 'inputFileLocation',
  volume_id: photo_small.volume_id,
  local_id: photo_small.local_id,
  secret: photo_small.secret
}
mtpApiFileManager.downloadSmallFile(inputFileLocation).then(function (blob) {
  var dataURI = fileManager.getDataUrl(blob);
  console.log(dataURI);
  return dataURI;
});

Hijacking the Telegram API

The web version of Telegram is written in AngularJS and supports most of the features available in the mobile and desktop versions. This provides a useful platform to inject JavaScript and hijack the AngularJS app to interact with the API, without the need to maintain the code to handle the MTProto authentication.

Following on from the previous post here, injecting into the AngularJS app will allow us to interact with the Telegram API and also allow us to access data associated with page objects, usually inaccessible to a user.

The scripts page contains links to GreaseMonkey scripts for various useful Telegram scripts.

Examples

Getting the current dialog ID:

angular.element(document.body).injector().get('$rootScope').selectedPeerID;

Invoking the API to get members of a Telegram group:

var mtpApiManager = angular.element(document).injector().get('MtpApiManager');
mtpApiManager.invokeApi('channels.getParticipants', {
  channel: appChatsManager.getChannelInput(groupID),
  filter: {
    _: 'channelParticipantsRecent'
  },
  limit: 200,
  offset: 0
}).then(function (data) {
  console.log(data);
  return;
});

More examples will be given over the next few weeks