Telegram Message Client - Metasploit


This page contains detailed information about how to use the auxiliary/client/telegram/send_message metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.

Module Overview


Name: Telegram Message Client
Module: auxiliary/client/telegram/send_message
Source code: modules/auxiliary/client/telegram/send_message.rb
Disclosure date: -
Last modification time: 2021-08-27 17:15:33 +0000
Supported architecture(s): -
Supported platform(s): -
Target service / protocol: -
Target network port(s): -
List of CVEs: -

This module can be used to send a document and/or message to multiple chats on telegram. Please refer to the module documentation for info on how to retrieve the bot token and corresponding chat ID values.

Module Ranking and Traits


Module Ranking:

  • normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.

Basic Usage


msf > use auxiliary/client/telegram/send_message
msf auxiliary(send_message) > show targets
    ... a list of targets ...
msf auxiliary(send_message) > set TARGET target-id
msf auxiliary(send_message) > show options
    ... show and set options ...
msf auxiliary(send_message) > exploit

Knowledge Base


The auxiliary/client/telegram/send_message module allows you to send a Telegram message and/or document to a given chat ID or set of chat IDs with a given Telegram bot token. This module also can be used as a notifier for established sessions with using the AutoRunScript handler option.

Module Options


BOT TOKEN

Each Telegram bot is given a unique authentication token when it is created. The token looks like 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11. You can generate a new token by messaging @botfather via https://t.me/botfather and sending the message /newbot to it, which should prompt it to ask a series of questions that will allow you to generate your bot. Once you have completed this, you should get a message saying Use this token to access the HTTP API: followed by the value of the bot's token. Use this value for BOT_TOKEN. If you have any issues, refer to this document.

CHAT ID

Unique identifier for a chat. To get the CHAT_ID value, send a message to the bot username that you created earlier. Then browse to https://api.telegram.org/bot<BOT_TOKEN VALUE>/getUpdates and look for a line like "chat":"id":1344308063. That ID is what you will want to use the value of CHAT_ID; in this case it would be 1344308063.

For group chats, add the bot to the chat, then perform these same steps and look for a line that has the text "type":"group". This should be within a pair of {} that contains an id: field. The value of this id: field is the value of the chat id for the group.

MSG

The content of the message to be sent.

FORMATTING

The Bot API supports basic formatting for messages. You can use bold, italic, underlined and strikethrough text, as well as inline links and pre-formatted code in your bots' messages. Telegram clients will render them accordingly. You can use either markdown-style or HTML-style formatting.

DOCUMENT The full path to the document to be sent.

IDFILE The full path to the file which contains different CHAT_IDs, one per line, which the message and/or document will be sent to.

Demonstration


msf6 > use auxiliary/client/telegram/send_message
msf6 auxiliary(client/telegram/send_message) > show options

Module options (auxiliary/client/telegram/send_message):

   Name        Current Setting  Required  Description
   ----        ---------------  --------  -----------
   BOT_TOKEN                    yes       Telegram BOT token
   CHAT_ID                      no        Chat ID for the BOT
   DOCUMENT                     no        The path to the document(binary, video etc)
   FORMATTING  Markdown         no        Message formating option (Markdown|MarkdownV2|HTML) (Accepted: Markdown, MarkdownV2, HT
                                          ML)
   IDFILE                       no        File containing chat IDs, one per line
   MESSAGE                      no        The message to be sent

msf6 auxiliary(client/telegram/send_message) > set BOT_TOKEN *redacted*
BOT_TOKEN => *redacted*
msf6 auxiliary(client/telegram/send_message) >
msf6 auxiliary(client/telegram/send_message) >
msf6 auxiliary(client/telegram/send_message) >
msf6 auxiliary(client/telegram/send_message) > set CHAT_ID 1725*redacted*
CHAT_ID => 1725*redacted*
msf6 auxiliary(client/telegram/send_message) > set DOCUMENT /home/gwillcox/git/metasploit-framework/bind_meterpreter.py
DOCUMENT => /home/gwillcox/git/metasploit-framework/bind_meterpreter.py
msf6 auxiliary(client/telegram/send_message) > set MESSAGE "Check out this cool new script!"
MESSAGE => Check out this cool new script!
msf6 auxiliary(client/telegram/send_message) > run

[+] Document sent successfully to 1725*redacted*
[+] Message sent successfully to 1725*redacted*
[*] Auxiliary module execution completed
msf6 auxiliary(client/telegram/send_message) > run

[+] Document sent successfully to 1725*redacted*
[+] Message sent successfully to 1725*redacted*
[*] Auxiliary module execution completed
msf6 auxiliary(client/telegram/send_message) > code test_ids
[*] exec: code test_ids

msf6 auxiliary(client/telegram/send_message) > set IDFILE test_ids
IDFILE => test_ids
msf6 auxiliary(client/telegram/send_message) > cat test_ids
[*] exec: cat test_ids

-593*redacted*
1725*redacted*msf6 auxiliary(client/telegram/send_message) > run

[!] Opening `/home/gwillcox/git/metasploit-framework/test_ids` to fetch chat IDs...
[+] Document sent successfully to -593*redacted*

[+] Message sent successfully to -593*redacted*

[+] Document sent successfully to 1725*redacted*
[+] Message sent successfully to 1725*redacted*
[*] Auxiliary module execution completed
msf6 auxiliary(client/telegram/send_message) >

Go back to menu.

Msfconsole Usage


Here is how the client/telegram/send_message auxiliary module looks in the msfconsole:

msf6 > use auxiliary/client/telegram/send_message

msf6 auxiliary(client/telegram/send_message) > show info

       Name: Telegram Message Client
     Module: auxiliary/client/telegram/send_message
    License: Metasploit Framework License (BSD)
       Rank: Normal

Provided by:
  Ege Balc�� <[email protected]>
  Gaurav Purswani

Check supported:
  No

Basic options:
  Name        Current Setting  Required  Description
  ----        ---------------  --------  -----------
  BOT_TOKEN                    yes       Telegram BOT token
  CHAT_ID                      no        Chat ID for the BOT
  DOCUMENT                     no        The path to the document(binary, video etc)
  FORMATTING  Markdown         no        Message formating option (Markdown|MarkdownV2|HTML) (Accepted: Markdown, MarkdownV2, HTML)
  IDFILE                       no        File containing chat IDs, one per line
  MESSAGE                      no        The message to be sent

Description:
  This module can be used to send a document and/or message to 
  multiple chats on telegram. Please refer to the module documentation 
  for info on how to retrieve the bot token and corresponding chat ID 
  values.

Module Options


This is a complete list of options available in the client/telegram/send_message auxiliary module:

msf6 auxiliary(client/telegram/send_message) > show options

Module options (auxiliary/client/telegram/send_message):

   Name        Current Setting  Required  Description
   ----        ---------------  --------  -----------
   BOT_TOKEN                    yes       Telegram BOT token
   CHAT_ID                      no        Chat ID for the BOT
   DOCUMENT                     no        The path to the document(binary, video etc)
   FORMATTING  Markdown         no        Message formating option (Markdown|MarkdownV2|HTML) (Accepted: Markdown, MarkdownV2, HTML)
   IDFILE                       no        File containing chat IDs, one per line
   MESSAGE                      no        The message to be sent

Advanced Options


Here is a complete list of advanced options supported by the client/telegram/send_message auxiliary module:

msf6 auxiliary(client/telegram/send_message) > show advanced

Module advanced options (auxiliary/client/telegram/send_message):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   VERBOSE    false            no        Enable detailed status messages
   WORKSPACE                   no        Specify the workspace for this module

Auxiliary Actions


This is a list of all auxiliary actions that the client/telegram/send_message module can do:

msf6 auxiliary(client/telegram/send_message) > show actions

Auxiliary actions:

   Name  Description
   ----  -----------

Evasion Options


Here is the full list of possible evasion options supported by the client/telegram/send_message auxiliary module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):

msf6 auxiliary(client/telegram/send_message) > show evasion

Module evasion options:

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------

Go back to menu.

Error Messages


This module may fail with the following error messages:

Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.

The document to be sent does not exist or is not a readable file!


Here is a relevant code snippet related to the "The document to be sent does not exist or is not a readable file!" error message:

54:	    datastore['IDFILE']
55:	  end
56:	
57:	  def send_document(conn, chat_id)
58:	    unless ::File.file?(document) && ::File.readable?(document)
59:	      fail_with(Failure::BadConfig, 'The document to be sent does not exist or is not a readable file!')
60:	    end
61:	    raw_params = { 'chat_id' => chat_id, 'document' => Faraday::UploadIO.new(document, 'application/octet-stream') }
62:	    params = {}
63:	    raw_params.each_with_object({}) do |(key, value), _tmp_params|
64:	      params[key] = value

Error while sending document! Make sure you have access to message chat_id : <CHAT_ID>


Here is a relevant code snippet related to the "Error while sending document! Make sure you have access to message chat_id : <CHAT_ID>" error message:

65:	    end
66:	    response = conn.post("/bot#{bot_token}/sendDocument", params)
67:	    if response.status == 200
68:	      print_good("Document sent successfully to #{chat_id}")
69:	    elsif response.status == 403
70:	      print_bad("Error while sending document! Make sure you have access to message chat_id : #{chat_id}")
71:	    else
72:	      print_bad("Error while sending the document to #{chat_id} API Status : #{response.status}")
73:	    end
74:	  end
75:	

Error while sending the document to <CHAT_ID> API Status : <RESPONSE.STATUS>


Here is a relevant code snippet related to the "Error while sending the document to <CHAT_ID> API Status : <RESPONSE.STATUS>" error message:

67:	    if response.status == 200
68:	      print_good("Document sent successfully to #{chat_id}")
69:	    elsif response.status == 403
70:	      print_bad("Error while sending document! Make sure you have access to message chat_id : #{chat_id}")
71:	    else
72:	      print_bad("Error while sending the document to #{chat_id} API Status : #{response.status}")
73:	    end
74:	  end
75:	
76:	  def send_message(conn, chat_id)
77:	    params = { 'chat_id' => chat_id, 'text' => message, 'parse_mode' => formatting }

Error while sending document! Make sure you have access to message chat_id : <CHAT_ID>


Here is a relevant code snippet related to the "Error while sending document! Make sure you have access to message chat_id : <CHAT_ID>" error message:

77:	    params = { 'chat_id' => chat_id, 'text' => message, 'parse_mode' => formatting }
78:	    response = conn.post("/bot#{bot_token}/sendMessage", params)
79:	    if response.status == 200
80:	      print_good("Message sent successfully to #{chat_id}")
81:	    elsif response.status == 403
82:	      print_bad("Error while sending document! Make sure you have access to message chat_id : #{chat_id}")
83:	    else
84:	      print_bad("Error while sending the message to chat_id #{chat_id} API Status : #{response.status}")
85:	    end
86:	  end
87:	

Error while sending the message to chat_id <CHAT_ID> API Status : <RESPONSE.STATUS>


Here is a relevant code snippet related to the "Error while sending the message to chat_id <CHAT_ID> API Status : <RESPONSE.STATUS>" error message:

79:	    if response.status == 200
80:	      print_good("Message sent successfully to #{chat_id}")
81:	    elsif response.status == 403
82:	      print_bad("Error while sending document! Make sure you have access to message chat_id : #{chat_id}")
83:	    else
84:	      print_bad("Error while sending the message to chat_id #{chat_id} API Status : #{response.status}")
85:	    end
86:	  end
87:	
88:	  def run
89:	    unless document || message

You must supply a message and/or document


Here is a relevant code snippet related to the "You must supply a message and/or document" error message:

85:	    end
86:	  end
87:	
88:	  def run
89:	    unless document || message
90:	      fail_with(Failure::BadConfig, 'You must supply a message and/or document')
91:	    end
92:	    url = 'https://api.telegram.org'
93:	    conn = Faraday.new(url: url) do |faraday|
94:	      faraday.request :multipart
95:	      faraday.request :url_encoded

Opening `<ID_FILE>` to fetch chat IDs...


Here is a relevant code snippet related to the "Opening `<ID_FILE>` to fetch chat IDs..." error message:

95:	      faraday.request :url_encoded
96:	      faraday.adapter Faraday.default_adapter
97:	    end
98:	
99:	    if id_file
100:	      print_warning("Opening `#{id_file}` to fetch chat IDs...")
101:	      unless ::File.file?(id_file) && ::File.readable?(id_file)
102:	        fail_with(Failure::BadConfig, 'The ID file is not an existing readable file!')
103:	      end
104:	      File.readlines(id_file).each do |chat_id|
105:	        send_document(conn, chat_id) if document

The ID file is not an existing readable file!


Here is a relevant code snippet related to the "The ID file is not an existing readable file!" error message:

97:	    end
98:	
99:	    if id_file
100:	      print_warning("Opening `#{id_file}` to fetch chat IDs...")
101:	      unless ::File.file?(id_file) && ::File.readable?(id_file)
102:	        fail_with(Failure::BadConfig, 'The ID file is not an existing readable file!')
103:	      end
104:	      File.readlines(id_file).each do |chat_id|
105:	        send_document(conn, chat_id) if document
106:	        send_message(conn, chat_id) if message
107:	      end

Go back to menu.


Go back to menu.

See Also


Check also the following modules related to this module:

Authors


  • Ege Balcı <egebalci[at]pm.me>
  • Gaurav Purswani

Version


This page has been produced using Metasploit Framework version 6.2.1-dev. For more modules, visit the Metasploit Module Library.

Go back to menu.