2020-07-28 15:41:05 -05:00
|
|
|
|
##
|
|
|
|
|
|
# This module requires Metasploit: https://metasploit.com/download
|
|
|
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
|
|
|
|
##
|
2020-07-13 08:38:24 +03:00
|
|
|
|
|
2021-05-11 20:19:24 +05:30
|
|
|
|
require 'faraday'
|
2020-07-13 08:38:24 +03:00
|
|
|
|
|
|
|
|
|
|
class MetasploitModule < Msf::Auxiliary
|
2020-07-28 16:14:29 -05:00
|
|
|
|
def initialize
|
|
|
|
|
|
super(
|
2024-01-07 15:04:17 -05:00
|
|
|
|
'Name' => 'Telegram Message Client',
|
|
|
|
|
|
'Description' => %q{
|
2021-05-13 17:47:46 +05:30
|
|
|
|
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.
|
2021-02-16 13:56:50 +00:00
|
|
|
|
},
|
2024-01-07 15:04:17 -05:00
|
|
|
|
'Author' => [
|
|
|
|
|
|
'Ege Balcı <egebalci[at]pm.me>', # Aka @egeblc of https://pentest.blog
|
|
|
|
|
|
'Gaurav Purswani' # @pingport80
|
|
|
|
|
|
],
|
|
|
|
|
|
'License' => MSF_LICENSE,
|
2020-07-28 16:14:29 -05:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
register_options(
|
|
|
|
|
|
[
|
|
|
|
|
|
OptString.new('BOT_TOKEN', [true, 'Telegram BOT token', '']),
|
2021-05-13 17:47:46 +05:30
|
|
|
|
OptString.new('MESSAGE', [false, 'The message to be sent']),
|
2021-05-11 20:19:24 +05:30
|
|
|
|
OptInt.new('CHAT_ID', [false, 'Chat ID for the BOT', '']),
|
|
|
|
|
|
OptPath.new('DOCUMENT', [false, 'The path to the document(binary, video etc)']),
|
2021-05-13 17:47:46 +05:30
|
|
|
|
OptPath.new('IDFILE', [false, 'File containing chat IDs, one per line']),
|
2024-01-07 15:02:53 -05:00
|
|
|
|
OptEnum.new('FORMATTING', [false, 'Message formatting option (Markdown|MarkdownV2|HTML)', 'Markdown', [ 'Markdown', 'MarkdownV2', 'HTML']])
|
2020-07-28 16:14:29 -05:00
|
|
|
|
], self.class
|
|
|
|
|
|
)
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2021-05-13 17:47:46 +05:30
|
|
|
|
def formatting
|
|
|
|
|
|
datastore['FORMATTING']
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2020-07-28 16:14:29 -05:00
|
|
|
|
def message
|
2021-05-11 20:19:24 +05:30
|
|
|
|
datastore['MESSAGE']
|
2020-07-28 16:14:29 -05:00
|
|
|
|
end
|
|
|
|
|
|
|
2021-05-11 20:19:24 +05:30
|
|
|
|
def document
|
|
|
|
|
|
datastore['DOCUMENT']
|
2020-07-28 16:14:29 -05:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def bot_token
|
|
|
|
|
|
datastore['BOT_TOKEN']
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2021-05-11 20:19:24 +05:30
|
|
|
|
def id_file
|
|
|
|
|
|
datastore['IDFILE']
|
|
|
|
|
|
end
|
2020-07-28 16:14:29 -05:00
|
|
|
|
|
2021-05-11 20:19:24 +05:30
|
|
|
|
def send_document(conn, chat_id)
|
2021-05-13 13:37:26 -05:00
|
|
|
|
unless ::File.file?(document) && ::File.readable?(document)
|
|
|
|
|
|
fail_with(Failure::BadConfig, 'The document to be sent does not exist or is not a readable file!')
|
|
|
|
|
|
end
|
2021-05-11 20:19:24 +05:30
|
|
|
|
raw_params = { 'chat_id' => chat_id, 'document' => Faraday::UploadIO.new(document, 'application/octet-stream') }
|
2021-05-13 17:47:46 +05:30
|
|
|
|
params = {}
|
2021-05-13 22:14:54 +05:30
|
|
|
|
raw_params.each_with_object({}) do |(key, value), _tmp_params|
|
2021-05-13 17:47:46 +05:30
|
|
|
|
params[key] = value
|
2021-05-11 20:19:24 +05:30
|
|
|
|
end
|
2021-05-13 17:47:46 +05:30
|
|
|
|
response = conn.post("/bot#{bot_token}/sendDocument", params)
|
2021-05-11 20:19:24 +05:30
|
|
|
|
if response.status == 200
|
2021-05-13 17:47:46 +05:30
|
|
|
|
print_good("Document sent successfully to #{chat_id}")
|
2021-05-11 20:19:24 +05:30
|
|
|
|
elsif response.status == 403
|
2021-05-13 17:47:46 +05:30
|
|
|
|
print_bad("Error while sending document! Make sure you have access to message chat_id : #{chat_id}")
|
2020-07-28 16:14:29 -05:00
|
|
|
|
else
|
2021-05-13 17:47:46 +05:30
|
|
|
|
print_bad("Error while sending the document to #{chat_id} API Status : #{response.status}")
|
2020-07-13 08:38:24 +03:00
|
|
|
|
end
|
2020-07-28 16:14:29 -05:00
|
|
|
|
end
|
2021-05-11 20:19:24 +05:30
|
|
|
|
|
|
|
|
|
|
def send_message(conn, chat_id)
|
2021-05-13 17:47:46 +05:30
|
|
|
|
params = { 'chat_id' => chat_id, 'text' => message, 'parse_mode' => formatting }
|
|
|
|
|
|
response = conn.post("/bot#{bot_token}/sendMessage", params)
|
2021-05-11 20:19:24 +05:30
|
|
|
|
if response.status == 200
|
2021-05-13 17:47:46 +05:30
|
|
|
|
print_good("Message sent successfully to #{chat_id}")
|
2021-05-11 20:19:24 +05:30
|
|
|
|
elsif response.status == 403
|
2021-05-13 17:47:46 +05:30
|
|
|
|
print_bad("Error while sending document! Make sure you have access to message chat_id : #{chat_id}")
|
2021-05-11 20:19:24 +05:30
|
|
|
|
else
|
2021-05-13 17:47:46 +05:30
|
|
|
|
print_bad("Error while sending the message to chat_id #{chat_id} API Status : #{response.status}")
|
2021-05-11 20:19:24 +05:30
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def run
|
2021-05-13 22:14:54 +05:30
|
|
|
|
unless document || message
|
|
|
|
|
|
fail_with(Failure::BadConfig, 'You must supply a message and/or document')
|
|
|
|
|
|
end
|
2021-05-11 20:19:24 +05:30
|
|
|
|
url = 'https://api.telegram.org'
|
|
|
|
|
|
conn = Faraday.new(url: url) do |faraday|
|
|
|
|
|
|
faraday.request :multipart
|
|
|
|
|
|
faraday.request :url_encoded
|
|
|
|
|
|
faraday.adapter Faraday.default_adapter
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
if id_file
|
2021-05-13 17:47:46 +05:30
|
|
|
|
print_warning("Opening `#{id_file}` to fetch chat IDs...")
|
2021-05-13 13:37:26 -05:00
|
|
|
|
unless ::File.file?(id_file) && ::File.readable?(id_file)
|
|
|
|
|
|
fail_with(Failure::BadConfig, 'The ID file is not an existing readable file!')
|
|
|
|
|
|
end
|
2021-05-11 20:19:24 +05:30
|
|
|
|
File.readlines(id_file).each do |chat_id|
|
2021-05-13 17:47:46 +05:30
|
|
|
|
send_document(conn, chat_id) if document
|
|
|
|
|
|
send_message(conn, chat_id) if message
|
2021-05-11 20:19:24 +05:30
|
|
|
|
end
|
|
|
|
|
|
return
|
|
|
|
|
|
end
|
2021-05-13 17:47:46 +05:30
|
|
|
|
send_document(conn, datastore['CHAT_ID']) if document
|
|
|
|
|
|
send_message(conn, datastore['CHAT_ID']) if message
|
2021-05-11 20:19:24 +05:30
|
|
|
|
end
|
|
|
|
|
|
|
2020-07-13 08:38:24 +03:00
|
|
|
|
end
|