CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/client/telegram/send_message.rb
Views: 11784
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'faraday'
7
8
class MetasploitModule < Msf::Auxiliary
9
def initialize
10
super(
11
'Name' => 'Telegram Message Client',
12
'Description' => %q{
13
This module can be used to send a document and/or message to
14
multiple chats on telegram. Please refer to the module
15
documentation for info on how to retrieve the bot token and corresponding chat
16
ID values.
17
},
18
'Author' => [
19
'Ege Balcı <egebalci[at]pm.me>', # Aka @egeblc of https://pentest.blog
20
'Gaurav Purswani' # @pingport80
21
],
22
'License' => MSF_LICENSE,
23
)
24
25
register_options(
26
[
27
OptString.new('BOT_TOKEN', [true, 'Telegram BOT token', '']),
28
OptString.new('MESSAGE', [false, 'The message to be sent']),
29
OptInt.new('CHAT_ID', [false, 'Chat ID for the BOT', '']),
30
OptPath.new('DOCUMENT', [false, 'The path to the document(binary, video etc)']),
31
OptPath.new('IDFILE', [false, 'File containing chat IDs, one per line']),
32
OptEnum.new('FORMATTING', [false, 'Message formatting option (Markdown|MarkdownV2|HTML)', 'Markdown', [ 'Markdown', 'MarkdownV2', 'HTML']])
33
], self.class
34
)
35
end
36
37
def formatting
38
datastore['FORMATTING']
39
end
40
41
def message
42
datastore['MESSAGE']
43
end
44
45
def document
46
datastore['DOCUMENT']
47
end
48
49
def bot_token
50
datastore['BOT_TOKEN']
51
end
52
53
def id_file
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
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
76
def send_message(conn, chat_id)
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
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
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
106
send_message(conn, chat_id) if message
107
end
108
return
109
end
110
send_document(conn, datastore['CHAT_ID']) if document
111
send_message(conn, datastore['CHAT_ID']) if message
112
end
113
114
end
115
116